OpenMP中调度程序对循环变量的处理
Procession of loop variables by a scheduler in OpenMP
循环变量默认为私有变量。让我们假设线程有这个循环头:
#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_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();
例如,线程将执行以下迭代:
tid #0: 0, 4, 8...
tid #1: 1, 5, 9...
tid #2: 2, 6, 10...
tid #3: 3, 7, 11...
这是实现OpenMP的一种天真、直接的方法,它应该让您了解整个机器是如何工作的。
相关文章:
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 如何处理非default_constructible tyname 变量
- 在通知提升间处理条件变量时未按住锁会导致问题
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- C++预处理会生成变量成员、资源库和映射
- 如何处理冲突的函数和变量名称?
- C++单个变量来处理来自用户的多个类
- C++11如何在1个线程中使用条件变量处理2个线程安全队列
- 当线程处理不同的类时,应该在哪里声明条件变量、互斥对象
- 当使用lambda进行变量的复杂初始化时,如何处理从内部抛出的lambda外部异常
- 多线程处理中的静态成员变量
- 如何使用模板处理多类型变量?
- 在调用进程的上下文中通过 win32 执行批处理,从而保留环境变量
- 如何处理参数中的基类和指针变量
- 使用共享变量进行线程处理
- C编译器如何使用非初始化的变量处理
- 如何处理MinGM32位加密编译器中的128位变量(Diffie-Hellman算法)
- 在C 11中处理模板化函数中的空隙变量
- C++ 读取文件和写入变量时未处理的异常 - getline 错误?
- 静态变量需要在MAIN处理ARGV参数之前进行初始化