【问题标题】:OpenMP strange behaviourOpenMP 奇怪的行为
【发布时间】:2012-02-06 15:59:49
【问题描述】:

您好,我有以下代码,我使用带有 -fopenmp 标志的 gcc (>4.2) 编译:

int main(void)
{
#pragma omp parallel for
    int i; 
    for(i=0;i<4;i++) while(1);

    return 0;
}

我在 OSX Lion(版本 1.7.3,llvm-gcc 4.2.1)和 CentOS 6.2 上获得了 SIGSEGV。我在这里做错了什么?谢谢

【问题讨论】:

  • 我也一样,Win7/cygwin,gcc 4.5.0。我通过 gdb 运行它:它创建线程,然后我得到Program received signal SIGSEGV, Segmentation fault. 0x63602726 in omp_get_max_active_levels ()。没有while(1),它运行良好。 OpenMP 如何处理这个无限循环?
  • 您正在使用未声明的变量。但这应该会产生编译错误,而不是段错误。但是在声明了i 后,我也遇到了段错误,gcc-4.5.1,openSuSE 11.4。
  • 我忘了添加.. int i.. 我写的代码很匆忙:D.

标签: c segmentation-fault openmp


【解决方案1】:

不确定这是否与编译器版本和配置有关,但while(true){} terminates

更准确地说,如果你写一个循环

  • 不调用库 I/O 函数,并且
  • 不访问或修改易失性对象,并且
  • 不执行同步操作 (1.10) 或原子操作(第 29 条)

并且不会终止,您有未定义的行为

这可能最终不适用于您的情况,但随着 C++11 变得更加成熟,请注意。

【讨论】:

  • 无关紧要,这是 C,在 C 中,只有当控制表达式不是常量表达式时,循环才会被假定终止。由于while(1); 由常量表达式控制,循环不能终止。
  • 有趣的是,我没有意识到 C 具有这样的非常数表达式质量。请您指出标准吗?
  • 你好,spraff,我在 C => while(1); 中没有看到任何未定义的行为; (请指向C标准)。它应该是在自己的地址处跳转的无条件跳转(jmp)。如果我创建 4 个线程(使用 pthread_create)并在启动函数中放入“while(1);”我没有收到 SIGSEGV,我的 4 个核心是 100%。我想用 openmp 实现相同的行为,但它似乎没有我想象的那么可靠。
  • 由于我没有实际的标准,所以我会选择 n1570,在 6.8.5 (6) 中:“控制表达式不是常量表达式的迭代语句,不执行输入/输出操作,...”。 'not a constant expression' 限定符可能再次被删除,但由于它已被添加到该段落的后面,我不希望这样。
【解决方案2】:

非常有趣。

我稍微修改了代码 所以

int main(void)
{
int i;
#pragma omp parallel 
  {
        while(1);
    }
    return 0;
} 

等等

inline void func() {
    while (1) ;
}

int main(void)
{
int i;
#pragma omp parallel for 
    for(i=0;i<8;i++) {
        func();
    }
    return 0;
}

他们都工作正常。

【讨论】:

  • 我知道,我也试过后者。 (也可以在没有内联的情况下使用)。但是您认为我编写的代码有什么问题(除了缺少... int i)。在我的 CentOS 上 gomp_loop_static_start() 被调用,参数如 => chunk_size=140737488347560, istart=0x7ffffffffe1b0, iend=0xca。最后一个是被取消引用的指针..因此得到 SIGSEGV。如果我明确使用 schedule() 将块大小设置为一个值,则 iend 指针是一个有效地址.. 我没有得到 SIG 11。另外,如果我调试你的后一个代码(使用内联 fnc) gomp_loop_static_start() 不会完全被调用。
  • 如果您在启用优化的情况下进行编译,那么您还会遇到 func() 情况下的段错误。
  • @J.F.Sebastian 不在这里,使用func(),它在 390+% 的 CPU(从 -O0 到 -O3 和 -Os)下什么都不做。在所有优化级别上都带有朴素的while(1); 的段错误。 gcc 是 4.5.1。很奇怪。
  • gcc 4.6.1: -O0 没有段错误,-O1+ -- 段错误。
  • @sfa,我真的不知道会发生什么。认为应该查看生成的汇编代码。后面我会尝试使用 Intel C++ 编译器,现在我没有时间了。
【解决方案3】:

gcc 中有一个关于这个问题的错误,我报告了它,他们会提供修复。这是链接:GCC bug

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多