OpenMP中调度程序对循环变量的处理

Procession of loop variables by a scheduler in OpenMP

本文关键字:变量 处理 循环 调度程序 OpenMP      更新时间:2023-10-16

循环变量默认为私有变量。让我们假设线程有这个循环头:

#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的值必须以某种方式共享。这是怎么回事?

长话短说,OpenMP编译器将为该循环生成一个函数,该函数将由多个线程并行调用。

循环迭代器将被规范化,边界将被重写为thread_idthread_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();

例如,线程将执行以下迭代:

tid #0: 0, 4, 8...
tid #1: 1, 5, 9...
tid #2: 2, 6, 10...
tid #3: 3, 7, 11...

这是实现OpenMP的一种天真、直接的方法,它应该让您了解整个机器是如何工作的。