我有一个非常复杂的程序,它使用内部FFT算法。我最近决定尝试使用FFTW来提高性能。就像确保FFTW链接和运行的简单测试一样,我将以下代码添加到应用程序的开头,但是,当我运行时,我在创建fftwf_plan
时出现了分段错误:
const size_t size = 1024;
vector<complex<float> > data(size);
for(size_t i = 0; i < size; ++i) data[i] = complex<float>(i, -i);
fftwf_plan plan =
fftwf_plan_dft_1d(size,
(fftwf_complex*)&data[0],
(fftwf_complex*)&data[0],
FFTW_FORWARD,
FFTW_ESTIMATE);
// ^ seg faults here ^
fftwf_execute(plan);
fftwf_destroy_plan(plan);
任何想法会导致什么?
使用FFTW 3.3。试过2个不同的编译器,g ++ 4.1.1和icc 11.1。此外,核心文件文件显示没有任何意义:
Thread 1.1: Error at 0x00000000
Stack Trace: PC: 000000, FP=Hex Address
修改
我使用以下命令重新配置FFTW以添加调试:
setenv CFLAGS "-fPIC -g -O0"
configure --enabled-shared --enable-float --enable-debug
make
make install
当程序出现分段错误时,它位于fftwf_plan_dft_1d()
方法的随机位置,但是,堆栈跟踪总是显示在search
函数内或之下,{ {1}}。
答案 0 :(得分:2)
很明显,这个问题源于多线程。即使主要功能在FFTW中是线程安全的(例如fftwf_execute
),创建计划的功能也不是。这并不能完全解释为什么只是在启动时运行测试失败,但是,当我在互斥锁中解除了计划创建时,分段错误就停止了。
答案 1 :(得分:1)
计划的创建和销毁必须是单线程的
fftw_init_threads();
#pragma omp parallel for
for(i=0;i<n;i++) {
#pragma omp critical {
plan = fftw_create_plan....
}
fftw_execute(plan); // or the fftw_execute_dft for multiple in/out fft operations
#pragma omp critical {
fftw_destroy_plan(plan);
}
}
fftw_cleanup_threads();
答案 2 :(得分:0)
我已经晚了3年,但是在使用多线程(--enable-openmp
和fftw_plan_with_nthreads(omp_get_max_threads())
)时,我偶然发现了一个非常类似的问题。 Mine seg出现fftw_destroy_plan(p)
。
事实证明,在重构我的代码时我并没有注意,我在致电fftw_cleanup_threads()
之前打电话给fftw_destroy_plan(p)
...傻,我知道,但它让我追逐我尾巴约1小时。
使用多线程时,需要在所有fftw *函数之后调用fftw_cleanup_threads()
,就像在任何fftw *函数之前需要调用fftw_init_threads()
一样。