fftw在运行多个同步进程时效率很低

时间:2017-03-10 14:17:50

标签: 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
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;
};

正如您所看到的,上面的程序也可以测试简单的浮点运算,所以我也测试了它,并且没有进程之间的干扰。

如果这是真的,对我的应用程序来说,这是一个非常严重的性能限制,我需要运行几十个同步进程。考虑在N为2的幂的简单情况下写我自己的1D fft。不应该那么难,对吗?

0 个答案:

没有答案