c - 运行最小 OpenMP 程序时的非法指令

标签 c multithreading gcc openmp

这个最小的 OpenMP 程序

#include <omp.h>
int main() 
{
  #pragma omp parallel sections
  {
    #pragma omp section
    {
      while(1) {}
    }

    #pragma omp section
    {  
      while(1) {}
    }
  }
}

使用gcc test.c -fopenmp编译和运行时会产生这个错误:

Illegal instruction (core dumped)

当我用

改变其中一个循环时
  int i=1;
  while(i++) {}

或它编译和运行时没有错误的任何其他条件。看起来,1 作为不同线程中的循环条件会导致一些奇怪的行为。为什么?

编辑:我使用的是 gcc 4.6.3

编辑:这是 gcc 中的错误,提交为 Bug 54017给 gcc 开发人员。

最佳答案

这显然是 GCC 中的错误。 GCC 使用 libgomp 中的 GOMP_sections_start() 例程实现 OpenMP 部分,该例程返回调用线程应执行的基于 1 的部分 ID 或 0 如果所有工作项都已分发。基本上转换后的代码应该是这样的:

main._omp_fn.0 (void * .omp_data_i)
{
   unsigned int .section.1;

   .section.1 = GOMP_sections_start(2);
L0:
   switch (.section.1)
   {
      case 0:
         // No more sections to run, exit
         goto L2;
      case 1:
         // Do section 1
         while (1) {}
         goto L1;
      case 2:
         // Do section 2
         while (1) {}
         goto L1;
      default:
         // Impossible section value, possible error in libgomp
         __builtin_trap();
   }
L1:
   .section.1 = GOMP_sections_next();
   goto L0;
L2:
   GOMP_sections_end_nowait();
   return;
}

在您的情况下,default0 情况都会导致 __builtin_trap()__builtin_trap() 是一个 GCC 内置函数,应该会异常终止您的程序,在 x86 上它会发出 ud2 指令,使 CPU 发出非法操作码异常.它通常放在代码永远不会执行的地方,例如GOMP_sections_start()GOMP_sections_next() 的所有可能的正确返回值 应该 被开关中的 case 覆盖,如果达到默认值 (在 libgomp 中发出可能的错误信号)它应该会失败,你会向开发人员投诉 :)

编辑:这绝对不是预期的 OpenMP 行为,iccsuncc 也不会发生。我提交了Bug 54017到 GCC Bugzilla。

编辑 2:我更新了文本以更准确地反射(reflect) GCC 应该产生的内容。看起来 GCC 对并行区域中的控制流产生了错误的印象,并进行了一些进一步破坏代码生成的“优化”。

关于c - 运行最小 OpenMP 程序时的非法指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11542692/

相关文章:

c++ - 指数的前 n 位

相互依赖的CMake库

c# - 使用 C# 提高多线程访问的位图检索(从屏幕/窗口)速度和存储

c - 关于 GCC 编译器和链接器的问题

c - 在C中如何按字节数进行转换?

c - 有什么方法可以打印 n 行 n 列,其中 (1,1) 是 1 ... (1,n) 是 n 那么 (2,1) 是 2 ... (2, n-1) 是 n (2,n) 为 1 且继续;

java - 以线程安全的方式填充映射并将该映射从后台线程传递给另一个方法?

java - BlockingQueue 中阻塞的线程

c++ - "variable tracking"占用了我的编译时间!

c - 不同 gcc 版本的语法错误?