2015-11-28 28 views
0

默认情况下,循环变量是私有的。假设我们有一个线程这个循环头:循环开始执行由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的值必须以某种方式共享。这个怎么用?

+0

[你见过?](https://msdn.microsoft.com/en-us/library/x5aw0hdf.aspx) – Kenney

回答

1

长话短说,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的天真,简单的方法,它应该给你的整个机械是如何工作的想法。

+0

谢谢。如果'i'随机增加会发生什么? – null

+0

你可以对循环体内的循环迭代器做些什么有限制。编译器只会告诉你,该循环无法并行化。 – simpel01

+0

不应该每个线程都用不同的参数而不是其他函数调用'openmp_loop_0'吗? – null