ハーブ・サッターの説得力のある講義Not your father's C++に触発された私は、MicrosoftのVisual Studio 2010を使ってC++の最新バージョンをもう一度見直すことにしました。私は特に、C++は「安全で速い」と主張しました。パフォーマンスクリティカルなコードをたくさん書く。安全で高速FFT
ベンチマークとして、同じ単純なFFTアルゴリズムをさまざまな言語で作成しようと決めました。
Iは、内蔵complex
タイプとvector
コレクションを使用して、次のC++ 11のコードを思い付いた:この関数は唯一n
が不可欠であるn
-elementベクトルのために働くことを
#include <complex>
#include <vector>
using namespace std;
// Must provide type or MSVC++ barfs with "ambiguous call to overloaded function"
double pi = 4 * atan(1.0);
void fft(int sign, vector<complex<double>> &zs) {
unsigned int j=0;
// Warning about signed vs unsigned comparison
for(unsigned int i=0; i<zs.size()-1; ++i) {
if (i < j) {
auto t = zs.at(i);
zs.at(i) = zs.at(j);
zs.at(j) = t;
}
int m=zs.size()/2;
j^=m;
while ((j & m) == 0) { m/=2; j^=m; }
}
for(unsigned int j=1; j<zs.size(); j*=2)
for(unsigned int m=0; m<j; ++m) {
auto t = pi * sign * m/j;
auto w = complex<double>(cos(t), sin(t));
for(unsigned int i = m; i<zs.size(); i+=2*j) {
complex<double> zi = zs.at(i), t = w * zs.at(i + j);
zs.at(i) = zi + t;
zs.at(i + j) = zi - t;
}
}
}
注意2の威力。 n
で動作する高速FFTコードをお探しの場合は、FFTWをご覧ください。
私が理解しているように、vector
を索引付けするためのCの構文では、境界チェックは行われないため、メモリに安全ではなく、非決定的な破損やメモリアクセス違反などのメモリエラーの原因になることがあります。だから代わりにxs.at(i)
を使用しました。
私はこのコードを「安全で高速」にしたいと思いますが、私はC++ 11のエキスパートではありませんので、このコードを改善してより慣用的で効率的なものにしたいのですか?
*「このコードを改良して、より慣用的または効率的にすることを頼んでいますか?」 - おそらく[codereview](http://codereview.stackexchange.com)がより良い場所になるでしょうレビューのために。 – Flexo
すべてではないにしても、ほとんどの標準ライブラリは、最適化されていない/デバッグモードのイテレータ/インデックスデバッグを提供しています。これは 'operator [] 'でチェックします。リリースモードでは無効になっているため、完全なパフォーマンスが得られます。 FWIWは、MSVCのライブラリです。また、別のlibがそうしているかどうか分からない場合は、デバッグでは 'at 'を、リリースモードでは' operator []'を呼び出すヘルパー関数を書くことができます。 – Xeo
他にどの言語を使用しましたか?比較を見るのは面白いだろう。 –