C++ fftw在同时运行多个进程时效率非常低
我发现fftw在许多(比如8+)不同进程中同时运行时效率非常低,即使我的机器上有许多内核(20个)。这是非常令人惊讶的,因为我能够以这种非常简单的方式并行许多其他cpu密集型任务。但fftw仍在挣扎C++ fftw在同时运行多个进程时效率非常低,c++,fftw,C++,Fftw,我发现fftw在许多(比如8+)不同进程中同时运行时效率非常低,即使我的机器上有许多内核(20个)。这是非常令人惊讶的,因为我能够以这种非常简单的方式并行许多其他cpu密集型任务。但fftw仍在挣扎 这里是我创建的C++测试程序的输出: magland@jm3:~/dev/fftw_load_test$ ./fftw_load_test.js --num_processes=1 --task=fftw Calling: bin/fftw_load_test --task=fftw Creatin
这里是我创建的C++测试程序的输出:
magland@jm3:~/dev/fftw_load_test$ ./fftw_load_test.js --num_processes=1 --task=fftw
Calling: bin/fftw_load_test --task=fftw
Creating plan...
Running fftw load test for M,N=4,40000000
Elapsed time (sec) for M,N=4,40000000 (1.20901e+7 nums per sec): 13.234
相比之下,当运行相同的程序时,只需在6个单独的进程中启动
Running fftw load test for M,N=4,40000000
Running fftw load test for M,N=4,40000000
Running fftw load test for M,N=4,40000000
Running fftw load test for M,N=4,40000000
Running fftw load test for M,N=4,40000000
Running fftw load test for M,N=4,40000000
Elapsed time (sec) for M,N=4,40000000 (1.10079e+7 nums per sec): 14.535
Elapsed time (sec) for M,N=4,40000000 (1.02328e+7 nums per sec): 15.636
Elapsed time (sec) for M,N=4,40000000 (1.01183e+7 nums per sec): 15.813
Elapsed time (sec) for M,N=4,40000000 (6.55845e+6 nums per sec): 24.396
Elapsed time (sec) for M,N=4,40000000 (6.16642e+6 nums per sec): 25.947
Elapsed time (sec) for M,N=4,40000000 (6.11084e+6 nums per sec): 26.183
这就是我一直在寻找的东西。我花了相当长的时间来孤立于这样一个简单的例子,因为我并不怀疑FFTW会有这样一个基本的限制
这就是我调用fftw的方式:
typedef long long bigint;
struct Fftw_runner {
Fftw_runner() {
}
~Fftw_runner() {
fftw_free(data_in);
fftw_free(data_out);
}
void init(bigint M_in,bigint N_in,QString task_in) {
M=M_in;
N=N_in;
MN=M*N;
task=task_in;
data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * MN);
data_out = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * MN);
int rank = 1;
int n[] = { (int)N };
int howmany = M;
int* inembed = n;
int istride = M;
int idist = 1;
int* onembed = n;
int ostride = M;
int odist = 1;
unsigned flags = FFTW_ESTIMATE;
if (task=="fftw") {
qDebug() << "Creating plan...";
p_fft = fftw_plan_many_dft(rank,n,howmany,data_in,inembed,istride,idist,data_out,onembed,ostride,odist,FFTW_FORWARD,flags);
}
}
void apply() {
if (task=="fftw") {
for (bigint i=0; i<MN; i++) {
data_in[i][0]=0;
data_in[i][1]=0;
}
//set input data
//fft
fftw_execute(p_fft);
//multiply by kernel
}
else if (task=="flops") {
double sum=0;
for (bigint n=0; n<N; n++) {
for (bigint m=0; m<M; m++) {
sum+=m*n;
}
}
printf("Print the result to force computation: %g\n",sum);
}
}
bigint M;
bigint N,MN;
QString task;
fftw_complex* data_in=0;
fftw_complex* data_out=0;
fftw_plan p_fft;
};
typedef long long bigint;
结构Fftw_转轮{
Fftw_跑步者(){
}
~Fftw_runner(){
fftw_免费(数据输入);
无fftw(数据输出);
}
void init(bigint M_in、bigint N_in、QString task_in){
M=M_in;
N=N_英寸;
MN=M*N;
任务=任务中的任务;
数据输入=(fftw\u复合体*)fftw\u malloc(sizeof(fftw\u复合体)*MN);
数据输出=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*MN);
int秩=1;
int n[]={(int)n};
int多少=M;
int*inembed=n;
int=M;
int idist=1;
int*onembed=n;
int ostride=M;
int-odist=1;
无符号标志=FFTW_估计值;
如果(任务==“fftw”){
qDebug()1 fftw使用多少缓存?@huseyintugrulbuyukisik如果这是个问题,是否有一种简单的方法来限制每个进程的缓存使用?是否每次需要计算FFT时都要创建FFT计划?如果是,那么不要这样做!缓存该计划并重新使用它。此外,如果您像@PaulR所说的那样缓存该计划,并且多次使用该计划,您可以一个比FFTW\u更好的估计值
。我已经有一段时间没有使用FFTW了,但我记得有一个选项正好在这个选项之上,它似乎可以在不花费太长时间创建plan@magland我所说的FFTW_评估意见的意思是,您可以更改导致创建计划需要更长时间的内容,但是fftw_exec应该更快。因此,如果你执行一个计划的次数足够多,那么投资是值得的。如果你执行的次数不够,那么估算就足够了。