默认情况下,循环变量是私有的。让我们假设我们有线程这个循环头:
#pragma omp parallel num_threads(4)
{
#pragma omp parallel for schedule(static,1)
for(i=0; i<40; i+=2) {
//...
}
}
在循环开始执行之前,静态调度程序可能会按如下方式分配迭代:
线程1:迭代0,4,8,12,16
主题2:迭代1,5,9,13,17
主题3:迭代2,6,10,14,18
主题4:迭代3,6,12,15,19
我不明白线程3在第三次迭代中如何知道i
的正确值(如果循环按顺序执行,这将是第10次迭代)。 i
是私有的,因此每个线程都有自己的副本并递增i
。同样,必须以某种方式共享i
的值。这是如何工作的?
答案 0 :(得分:1)
简而言之,OpenMP编译器将为该循环生成一个函数,该函数将由多个并行线程调用。
循环迭代器将被规范化,并且边界将被重写为thread_id
和thread_num
上的参数:
// code generated for #pragma omp for
void openmp_loop_0(int thread_id, int thread_num, ... closure ...) {
for(i=thread_id; i<40/2; i+=thread_num) {
...a[i*2]...
}
}
// code replaced in the main() function
thread t0(openmp_loop_0(0, 4, ...).start();
thread t1(openmp_loop_0(1, 4, ...).start();
...
openmp_loop_0(3, 4, ...)
t0.join(), t1.join(), t2.join();
e.g。线程将执行以下迭代:
tid #0: 0, 4, 8...
tid #1: 1, 5, 9...
tid #2: 2, 6, 10...
tid #3: 3, 7, 11...
这是实现OpenMP的一种天真,直接的方式,它应该让您了解整个机器的工作原理。