Herb Sutter の説得力のある講義Not your Father's C++に触発されて、Microsoft の Visual Studio 2010 を使用して C++ の最新バージョンをもう一度見てみることにしました。パフォーマンスが重要なコード。
ベンチマークとして、同じ単純な FFT アルゴリズムをさまざまな言語で記述してみることにしました。
complex
組み込みの型とvector
コレクションを使用する次の C++11 コードを思いつきました。
#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
要素ベクトルに対してのみ機能することに注意してください。n
高速な FFT コードを探している人は、 FFTWn
を参照してください。
私が理解しているように、xs[i]
a にインデックスを付けるための C の従来の構文vector
は境界チェックを行わないため、メモリ セーフではなく、非決定論的な破損やメモリ アクセス違反などのメモリ エラーの原因となる可能性があります。だからxs.at(i)
代わりに使った。
さて、このコードを「安全で高速」にしたいのですが、私は C++11 の専門家ではないので、このコードをより慣用的または効率的にするための改善をお願いしたいと思います。