根据libgomp手册,代码格式为:
#pragma omp parallel for
for (i = lb; i <= ub; i++)
body;
变为
void subfunction (void *data)
{
long _s0, _e0;
while (GOMP_loop_static_next (&_s0, &_e0))
{
long _e1 = _e0, i;
for (i = _s0; i < _e1; i++)
body;
}
GOMP_loop_end_nowait ();
}
GOMP_parallel_loop_static (subfunction, NULL, 0, lb, ub+1, 1, 0);
subfunction (NULL);
GOMP_parallel_end ();
我做了一个非常小的程序来调试,看看这个实现是如何工作的:
int main(int argc, char** argv)
{
int res, i;
# pragma omp parallel for num_threads(4)
for(i = 0; i < 400000; i++)
res = res*argc;
return 0;
}
接下来,我运行gdb并将断点设置为“GOMP_parallel_loop_static”和“GOMP_parallel_end”。最初,库未加载,因此它们正在等待处理。当在gdb中运行测试程序时,我得到了以下结果:
(gdb) run 2 1 6 5 4 3 8 7
Starting program: ./test 2 1 6 5 4 3 8 7
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-
gnu/libthread_db.so.1".
[New Thread 0x7ffff73c9700 (LWP 5381)]
[New Thread 0x7ffff6bc8700 (LWP 5382)]
[New Thread 0x7ffff63c7700 (LWP 5383)]
Thread 1 "test" hit Breakpoint 2, 0x00007ffff7bc0c00 in GOMP_parallel_end () from /usr/lib/x86_64-linux-gnu/libgomp.so.1
正如您所看到的,它在“GOMP_parallel_end”中达到了第二个断点,但不是第一个断点。我想知道如果libgomp手册清楚地表明“GOMP_parallel_loop_static”首先出现,这怎么可能。
谢谢。
答案 0 :(得分:1)
GCC的那部分文档并没有真正定期更新,所以将其作为实际发生的近似值来阅读它可能是一个好主意。如果您对该详细程度感兴趣,我建议您查看-fdump-tree-all
生成的调试文件和类似选项。
使用最新版本的GCC,您的示例会生成对__builtin_GOMP_parallel
的调用,该调用会映射到GOMP_parallel
。我认为那个内部会在最后调用GOMP_parallel_end
,这就是你所看到的内容。
void
GOMP_parallel (void (*fn) (void *), void *data, unsigned num_threads, unsigned int flags)
{
num_threads = gomp_resolve_num_threads (num_threads, 0);
gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads));
fn (data);
ialias_call (GOMP_parallel_end) ();
}
当然,很高兴接受更新文档的补丁。 : - )