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开发人员.
这显然是海湾合作委员会的一个错误.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)
会发生什么事情,在你的情况下,案件default
和0
案件都会导致__builtin_trap()
.__builtin_trap()
是一个GCC内置的,它应该异常终止你的程序,并且在x86上它会发出ud2
指令,使CPU发出非法的操作码异常.它通常放在代码永远不会执行的地方,例如所有可能正确的返回值,GOMP_sections_start()
并且GOMP_sections_next()
应该被交换机中的情况覆盖,如果达到默认值(发出可能的错误信号libgomp
),它应该失败并且你会抱怨开发者:)
编辑:这绝对不是预期的OpenMP行为,它不会发生icc
或suncc
.我已经向GCC Bugzilla 提交了Bug 54017.
编辑2:我更新了文本,以更密切地反映GCC应该产生的内容.看起来GCC对并行区域中的控制流有错误的印象,并进行了一些"优化",进一步破坏了代码生成.