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

ste*_*fen 7 c multithreading gcc openmp

这个最小的OpenMP程序

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

    #pragma omp section
    {  
      while(1) {}
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在编译和运行时将产生此错误gcc test.c -fopenmp:

Illegal instruction (core dumped)
Run Code Online (Sandbox Code Playgroud)

当我改变其中一个循环时

  int i=1;
  while(i++) {}
Run Code Online (Sandbox Code Playgroud)

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

编辑:我正在使用gcc 4.6.3

编辑:这是gcc中的一个错误,并作为Bug 54017提交给gcc开发人员.

Hri*_*iev 7

这显然是海湾合作委员会的一个错误.GCC使用GOMP_sections_start()例程来实现OpenMP部分,该例程libgomp返回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;
}
Run Code Online (Sandbox Code Playgroud)

会发生什么事情,在你的情况下,案件default0案件都会导致__builtin_trap().__builtin_trap()是一个GCC内置的,它应该异常终止你的程序,并且在x86上它会发出ud2指令,使CPU发出非法的操作码异常.它通常放在代码永远不会执行的地方,例如所有可能正确的返回值,GOMP_sections_start()并且GOMP_sections_next() 应该被交换机中的情况覆盖,如果达到默认值(发出可能的错误信号libgomp),它应该失败并且你会抱怨开发者:)

编辑:这绝对不是预期的OpenMP行为,它不会发生iccsuncc.我已经向GCC Bugzilla 提交了Bug 54017.

编辑2:我更新了文本,以更密切地反映GCC应该产生的内容.看起来GCC对并行区域中的控制流有错误的印象,并进行了一些"优化",进一步破坏了代码生成.