7

私は EE であり、コードの専門家ではありません。

Embarcadero C++ Builder (XE3) を使用しています。

複素数に対してかなりの数の演算を行う FFT アルゴリズムがあります。Embarcadero の複雑な数学ライブラリをバイパスし、独自のコードですべての計算を行うと、FFT が約 4.5 倍速く実行されることがわかりました。ここに示されている 4 つの操作はすべて、途方もない時間を必要とします。

#include <dinkumware\complex>
#define ComplexD std::complex<double>
ComplexD X, Y, Z, FFTInput[1024];
double x, y;
Z = X * Y; 
x = X.real();
y = X.imag();
Z = ComplexD(x,y); 

乗算を独自の交差乗算に置き換えると、実行時間が半分になりました。しかし、私の懸念は、入力配列の実部と虚部にアクセスする方法にあります。私はこれをやっています:

double *Input;
Input = reinterpret_cast<double *>(FFTInput);
// Then these statements are equivalent.
x = FFTInput[n].real();
y = FFTInput[n].imag();
x = Input[2*n];
y = Input[2*n+1];

これを行うと、実行時間が再び半分に短縮されますが、この reinterpret_cast が賢明かどうかはわかりません。入力配列を複素数ではなく 2 つの double に変更することもできますが、この FFT を多数のプログラムで使用しているため、すべてを書き直す必要はありません。

この reinterpret_cast は問題ありませんか、それともメモリの問題がありますか? また、Embarcadero の複雑な数学関数をより高速に実行する方法はありますか? そして最後に、私にとってそれほど重要ではありませんが、この reinterpret_cast は移植可能ですか?

4

2 に答える 2

5

これは許可されています。これは標準的な引用ではありませんが、cppreferenceには次のように書かれています。

複素数の配列の要素へのポインターとp有効な配列インデックスiの場合、reinterpret_cast<T*>(p)[2*i]は複素数の実部であり、 は複素数p[i]reinterpret_cast<T*>(p)[2*i + 1]虚部ですp[i]

すぐに実際の規格からの引用を探します。

于 2013-10-10T15:38:28.200 に答える
2

ここから、ページの下部に次のように記載されています。

任意の複素数 z の場合、reinterpret_cast<T(&)[2]>(z)[0]は z の実部であり、 は zreinterpret_cast<T(&)[2]>(z)[1]の虚部です。

複素数 p の配列の要素へのポインターと有効な配列インデックス i の場合、reinterpret_cast<T*>(p)[2*i]は複素数 p[i] の実部であり、複素数 p[i]reinterpret_cast<T*>(p)[2*i + 1]の虚部です。(C++11以上)

これらの要件は、本質的に std::complex の 3 つの特殊化のそれぞれの実装を、それぞれ実数成分と虚数成分を保持する、同じメンバー アクセスを持つ value_type 型の非静的データ メンバーを 2 つだけ宣言するように制限します。

したがって、あなたがしていることは C++11 で動作することが保証されていますが、それ以前では動作しません。ライブラリの実装では引き続き機能する可能性がありますが、ライブラリの実装が 3 番目の段落に従って非静的データ メンバーをこれ以上定義していないことを確認する必要があります。

于 2013-10-10T15:39:51.153 に答える