【问题标题】:Segmentation fault using FFTW使用 FFTW 的分段错误
【发布时间】:2011-09-27 19:02:27
【问题描述】:

我有一个非常复杂的程序,它使用内部 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 调用的函数search

【问题讨论】:

  • 你应该找出它在哪一行出现了段错误,然后用更多信息更新问题。
  • 你说这都是内部代码。这意味着您可以确定 seg 故障发生在 fftwf_plan_dft_1d 的哪一行。
  • 一进入fftwf_plan_dft_1d,调试器就会突然停止,没有任何错误或状态,如果我检查一个核心文件,它什么也没有显示。
  • 我猜如果isize_t-i 不会给你预期的结果。通过查看标题 fftw3.h,我看到他们期望 C99 复合体具有相同的布局。您确定 std::complex 具有相同的布局/兼容吗?
  • 您可能需要使用调试符号重新编译 FFTW 以查看发生了什么。在类似 Linux 的系统上,将 FFTW-3.3 源代码分发版 cd 解压缩到解压缩的文件夹中,然后键入 CFLAGS='-g -O0' FFLAGS='-g -O0' ./configure

标签: c++ fftw


【解决方案1】:

显然问题源于多线程。尽管 FFTW 中的主要函数是线程安全的(例如fftwf_execute),但创建计划的函数却不是。这并不能完全解释为什么只是在启动时运行测试失败,但是,当我在互斥锁中解释计划创建时,分段错误就停止了。

【讨论】:

  • 在 Apache Spark(使用 JNI)中集成 FFTW3 时遇到问题。如果我在集群模式下使用每个节点的单个核心或单台机器(本地模式)中的单个核心来执行我的应用程序,那么一切正常。但是,如果我通过每台机器使用两个或更多内核来执行我的应用程序,我会发现这个问题:SIGSEGV (0xb) at pc=0x00007ff9007bc5ae, pid=27386, tid=0x00007ff91e1f1700 - 有问题的框架:C [libfftw3f.so.3+0x155ae ] fftwf_mkplan+0xe
  • 您能否再解释一下如何创建互斥锁?谢谢
【解决方案2】:

计划的创建和销毁必须是单线程的

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();

【讨论】:

    【解决方案3】:

    我迟到了 3 年,但我偶然发现了一个非常相似的问题,在使用多线程时也是如此(--enable-openmpfftw_plan_with_nthreads(omp_get_max_threads()))。我的 seg 在fftw_destroy_plan(p) 上出现故障。

    原来我在重构代码时没有注意,我在调用fftw_destroy_plan(p)之前调用了fftw_cleanup_threads()……我知道这很傻,但它让我追了大约1小时。

    使用多线程时,fftw_cleanup_threads() 需要在所有 fftw* 函数之后调用,就像fftw_init_threads() 需要在任何 fftw* 函数之前调用一样。

    【讨论】:

    • 嗨@normadize,我一直在关注你,因为你在wordpress 论坛上发起的主题。在评论中,您提到 qtranslate-slug 可以改进。我现在也在维护它,我想知道你做了哪些改变。对不起,在这里追捕你...... :)
    • Mods 肯定会删除它,但也许您可以在他们删除之前留下一些联系信息或写信给我的 gmail 地址(同名)。
    猜你喜欢
    • 1970-01-01
    • 2019-06-26
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多