20年前,我编写了一个矩阵计算C++库,我愿意使用英特尔MKL库来提高它的性能。对于复值向量/矩阵,我的库使用两个拆分数组:一个用于实部,一个用于虚部。
以下是计时结果:
fftw时间= 0.005(s),fftpack时间= 0.001(s)
。
对于长度< 1500000的向量,双值fftpack比fftw快。
下面是我使用的代码:
Matrix X=randn(M,1); //input vector
//start timer
Matrix Y = MyFFTW(X);
// measure time
//function to compute the FFT
Matrix MyFFTW(Matrix X)
{
int M= X.rows();
int N= X.cols();
Matrix Y(T_COMPLEX,M,N); // output complex to store FFT results
// Input data could also ba matrix
double* in_data = (double*)fftw_malloc(sizeof(double) * M );
fftw_complex* out_data = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * (M / 2 + 1));
fftw_plan fftplan = fftw_plan_dft_r2c_1d(M, in_data, out_data, FFTW_ESTIMATE);
//one fftplan is used for all the matrix columns
for (int i = 1; i <= N; i++)
{
//copy column number i to in_dataused by the fftplan, arrays indexing is 1-based like matlab
memcpy(in_data, X.pr(1,i), M* sizeof(double));
fftw_execute(fftplan);
//split out_data to real and imag parts
double* pr = Y.pr(1,i), * pi = Y.pi(1,i);
int k = (M - 1) / 2, j;
for (j = 0; j <= k; j++)
{
*pr++ = out_data[j][0];
*pi++ = out_data[j][1];
}
if (M % 2 == 0)
{
*pr++ = out_data[M/2][0];
*pi++ = out_data[M/2][1];
}
for (j = k; j >= 1; j--)
{
*pr++ = out_data[j][0];
*pi++ = out_data[j][1];
}
}
fftw_destroy_plan(fftplan);
fftw_free(in_data);
fftw_free(out_data);
return Y;
}使用VisualStudio2019作为编译器和最后一个英特尔MKL库,在Intel核心i7 @ 3.2 GHz上获得结果。编译器标志是:
/fp:fast /DWIN32 /O2 /Ot /Oi /Oy /arch:AVX2 /openmp /MD 链接库是:
mkl_intel_c.lib mkl_intel_thread.lib mkl_core.lib libiomp5md.lib是否有更好的方法,使fftw更快的向量的小规模?
更新:
我在Matlab上进行了测试,Matlab使用MKL进行fft计算:
matlab fft时间= 0.071233(s)
除了首次用N=65536调用fft外,Matlab(64位)比使用fftpack (对于N> 500000)和使用MKL的my函数(win32)都快。
谢谢
发布于 2020-07-21 06:44:50
关于fftw,AFAIK,没有来自MKL的具体的性能提示,这将有助于加快小案例的性能。实际上,从mkl使用fftw的开销非常小。
关于您的工作台:我看到您测量分配/取消分配部分,创建fftw计划,并复制操作。但是,这个基准测试中唯一的一个例程(fftw_execute)是由mkl优化的。这可能是管道的问题。您可以添加MKL_VERBOSE模式来检查fftw_execute的执行时间.
https://stackoverflow.com/questions/63006016
复制相似问题