如何设置具有线程和不同精度的 FFTW?

How to setup FFTW with threads and different precisions?

我需要使用具有不同算术精度和多线程计划的 FFTW。

我需要为所有精度设置多线程吗?像这样:

fftwf_init_threads();
fftwf_plan_with_nthreads(nthreads);
fftw_init_threads();
fftw_plan_with_nthreads(nthreads);
fftwl_init_threads();
fftwl_plan_with_nthreads(nthreads);

或者在我的开始例程

中写这个
fftw_init_threads();
fftw_plan_with_nthreads(nthreads);

够了吗?

不同精度的fftw库是完全独立的。因此,您需要通过调用 fftw 的相应函数来为所有精度设置多线程

int nbthreads=2;
fftw_init_threads();
fftw_plan_with_nthreads(nbthreads);
fftwf_init_threads();
fftwf_plan_with_nthreads(nbthreads);
fftwq_init_threads();
fftwq_plan_with_nthreads(nbthreads);

...

fftw_cleanup_threads();
fftwf_cleanup_threads();
fftwq_cleanup_threads();

这是一个说服你的示例代码。一旦构建了相应的库,它就可以在 Unix 上由 gcc main.c -o main -lfftw3_threads -lfftw3 -lfftw3f_threads -lfftw3f -lfftw3q_threads -lfftw3q -lm -lpthread -Wall 编译。

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include <fftw3.h>

int main ( ){
    int n = 40000000;
    int nf = n*2;
    int nq =n/32;

    fftw_complex *in;
    fftw_complex *in2;
    fftw_complex *out;
    fftw_plan plan_backward;
    fftw_plan plan_forward;

    fftwf_complex *inf;
    fftwf_complex *in2f;
    fftwf_complex *outf;
    fftwf_plan plan_backwardf;
    fftwf_plan plan_forwardf;

    fftwq_complex *inq;
    fftwq_complex *in2q;
    fftwq_complex *outq;
    fftwq_plan plan_backwardq;
    fftwq_plan plan_forwardq;

    //thread parameters
    int nbthreads=2;
    fftw_init_threads();
    fftw_plan_with_nthreads(nbthreads);
    fftwf_init_threads();
    fftwf_plan_with_nthreads(nbthreads);
    fftwq_init_threads();
    fftwq_plan_with_nthreads(nbthreads);

    in = fftw_malloc ( sizeof ( fftw_complex ) * n );
    out = fftw_malloc ( sizeof ( fftw_complex ) * n );

    inf = fftwf_malloc ( sizeof ( fftwf_complex ) * nf );
    outf = fftwf_malloc ( sizeof ( fftwf_complex ) * nf );

    inq = fftwq_malloc ( sizeof ( fftwq_complex ) * nq );
    outq = fftwq_malloc ( sizeof ( fftwq_complex ) * nq);

    // forward fft
    plan_forward = fftw_plan_dft_1d ( n, in, out, FFTW_FORWARD, FFTW_ESTIMATE );
    fftw_execute ( plan_forward );

    plan_forwardf = fftwf_plan_dft_1d ( nf, inf, outf, FFTW_FORWARD, FFTW_ESTIMATE );
    fftwf_execute ( plan_forwardf );

    plan_forwardq = fftwq_plan_dft_1d ( nq, inq, outq, FFTW_FORWARD, FFTW_ESTIMATE );
    fftwq_execute ( plan_forwardq );

    // backward fft
    in2 = fftw_malloc ( sizeof ( fftw_complex ) * n );
    plan_backward = fftw_plan_dft_1d ( n, out, in2, FFTW_BACKWARD, FFTW_ESTIMATE );
    fftw_execute ( plan_backward );

    in2f = fftwf_malloc ( sizeof ( fftwf_complex ) * nf );
    plan_backwardf = fftwf_plan_dft_1d ( nf, outf, in2f, FFTW_BACKWARD, FFTW_ESTIMATE );
    fftwf_execute ( plan_backwardf );

    in2q = fftwq_malloc ( sizeof ( fftwq_complex ) * nq );
    plan_backwardq = fftwq_plan_dft_1d ( nq, outq, in2q, FFTW_BACKWARD, FFTW_ESTIMATE );
    fftwq_execute ( plan_backwardq);

    fftw_cleanup_threads();
    fftw_destroy_plan ( plan_forward );
    fftw_destroy_plan ( plan_backward );

    fftw_free ( in );
    fftw_free ( in2 );
    fftw_free ( out );

    fftwf_cleanup_threads();
    fftwf_destroy_plan ( plan_forwardf );
    fftwf_destroy_plan ( plan_backwardf );

    fftwf_free ( inf );
    fftwf_free ( in2f );
    fftwf_free ( outf );

    fftwq_cleanup_threads();
    fftwq_destroy_plan ( plan_forwardq);
    fftwq_destroy_plan ( plan_backwardq );

    fftwq_free ( inq );
    fftwq_free ( in2q );
    fftwq_free ( outq );

    return 0;
}

您可以评论 fftwq_init_threads(); fftwq_plan_with_nthreads(nbthreads);fftwq_cleanup_threads(); 并监控 cpu 用法以检查 fftw 在这种情况下不会使用多线程来实现四精度。

要使用 intel simd sse2 为不同的精度构建 fftw3,请执行:

./configure --enable-threads --enable-shared --enable-sse2
make 
make install
./configure --enable-threads --enable-shared --enable-sse2 --enable-float
make 
make install
./configure --enable-threads --enable-shared --enable-quad-precision
make
make install

sse2 不支持四精度。