我是FFTW库的新手。我已经使用FFTW库成功实现了1D和2D fft。我将2D fft代码转换为多线程2D fft。但结果完全相反。与串行化的2D FFT代码相比,多线程2D FFT代码运行时间更长。我错过了某个地方。我按照FFTW documentation中给出的所有说明来并行化代码。
这是我的并行化2D FFT C程序
#include <mpi.h>
#include <fftw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define N 2000
#define M 2000
#define index(i, j) (j + i*M)
int i, j;
void get_input(fftw_complex *in) {
for(i=0;i<N;i++){
for(j=0;j<M;j++){
in[index(i, j)][0] = sin(i + j);
in[index(i, j)][1] = sin(i * j);
}
}
}
void show_out(fftw_complex *out){
for(i=0;i<N;i++){
for(j=0;j<M;j++){
printf("%lf %lf \n", out[index(i, j)][0], out[index(i, j)][1]);
}
}
}
int main(){
clock_t start, end;
double time_taken;
start = clock();
int a = fftw_init_threads();
printf("%d\n", a);
fftw_complex *in, *out;
fftw_plan p;
in = (fftw_complex *)fftw_malloc(N * M * sizeof(fftw_complex));
out = (fftw_complex *)fftw_malloc(N * M * sizeof(fftw_complex));
get_input(in);
fftw_plan_with_nthreads(4);
p = fftw_plan_dft_2d(N, M, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(p);
/*p = fftw_plan_dft_1d(N, out, out, FFTW_BACKWARD, FFTW_ESTIMATE);
fftw_execute(p);
puts("In Real Domain");
show_out(out);*/
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
fftw_cleanup_threads();
end = clock();
time_taken = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("%g \n", time_taken);
return 0;
}
有人可以帮助我指出我正在做的错误吗?
答案 0 :(得分:0)
这种行为是不正确绑定的典型行为。
一般来说,OpenMP线程都应绑定到同一套接字的内核,以避免NUMA效应(这可能会导致性能不理想甚至最差)。
此外,确保MPI任务被正确绑定(一个任务应该绑定到来自相同套接字的多个核心,并且每个核心应该使用一个OpenMP线程。)
由于MPI,您的OpenMP线程最终会进行时间共享。
首先,我建议您开始打印MPI和OpenMP绑定。
如何实现这一点取决于MPI库和OpenMP运行时。如果您使用Open MPI和Intel编译器,则可以KMP_AFFINITY=verbose mpirun --report-bindings --tag-output ...
然后,如前所述,我建议您开始轻松并提高复杂性
希望,2。将比1快.4将比3快。