2017-01-11 101 views
3

我正在运行带有动态负载平衡的openmp for for循环。我想打印每个线程在程序结束时处理多少个任务/迭代。 循环如下所示:使用动态调度计算openmp for循环的迭代次数

chunk=1; 
#pragma omp parallel for schedule(dynamic,chunk) private(i) 
for(i=0;i<n;i++){ 
//loop code 
} 
+0

'threadprivate'是最简单的解决方案。 –

回答

3

没有什么更容易。刚刚拆分合并parallel for指令分成两个独立的结构,它允许您之前添加额外的代码,并在循环后:

#pragma omp parallel 
{ 
    int iters = 0; 
    #pragma omp for schedule(dynamic,chunk) 
    for (int i = 0; i < n; i++) { 
     ... 
     iters++; 
    } 
    #pragma omp critical 
    printf("Thread %d did %d iterations\n", omp_get_thread_num(), iters); 
} 
+0

不应该在'printf'之前有'#pragma omp critical'。同样,OP说“在程序结束时”,所以OP可能意味着他/她想要保存结果并在以后在并行区域之外打印它们。 –

+0

“没有比这更容易的了。” 'threadprivate'更容易,也不需要改变代码的结构。 –

+0

'threadprivate'需要一个静态/全局变量,这会打开另一个蠕虫。 –

0

对每个线程使用一个私人计数器。没有其他办法。

喜欢的东西

int workload[n_threads] = {0, ...}; 
#pragma omp parallel for schedule(dynamic) private(i) 
for(int i=0;i<n;i++){ 
    //loop code 
    workload[omp_get_thread_num()]++; 
} 
+2

...假分享... –

1

如果你真的想在你的程序中的外底打印迭代次数您并行区域或其他代码(并避免虚假共享),简单的解决方案是使用threadprivate

#include <stdio.h> 
#include <omp.h> 

int iters; 
#pragma omp threadprivate(iters) 

int main(void) { 
    omp_set_dynamic(0); //Explicitly turn off dynamic threads 
    int i; 
    int n = 10000; 
    #pragma omp parallel for schedule(dynamic) 
    for(i=0; i<n; i++) { 
    iters++; 
    } 
    #pragma omp parallel 
    #pragma omp critical 
    printf("Thread %d did %d iterations\n", omp_get_thread_num(), iters); 
} 

这是一个复杂的解决方案,它还要求您更改代码的结构。

#include <stdio.h> 
#include <stdlib.h> 
#include <omp.h> 

int main(void) { 
    int i; 
    int n = 100; 
    int nthreads; 
    int *aiters; 
    #pragma omp parallel 
    { 
    nthreads = omp_get_num_threads(); 
    #pragma omp single 
    aiters = malloc(sizeof *aiters * nthreads); 
    int iters = 0; 
    #pragma omp for schedule(dynamic) 
    for(i=0; i<n; i++) { 
     iters++; 
    } 
    aiters[omp_get_thread_num()]=iters; 
    } 
    for(i=0; i<nthreads; i++) 
    printf("Thread %d did %d iterations\n", i, aiters[i]); 
    free(aiters); 
} 
+0

不保证您的第一个示例中的两个并行区域将以相同数量的线程执行。 _dyn-var_必须显式设置为_false_。 –

+0

@HristoIliev,我修正了它,我认为使用'omp_set_dynamic(0)'。我不知道可以在并行区域之间动态更改线程数量,而不必明确告诉OpenMP执行此操作。原则上可能是这样,但我不知道我是否曾经在实践中见过它。你有吗? –

+0

@HristoIliev,你怎么没有指出[这里](http://stackoverflow.com/questions/18719257/parallel-cumulative-prefix-sums-in-openmp-communicating-values-between-thread#comment27598031_18719257) “时间表(静态)具有由标准保证的特殊属性,如可重复分配模式”。如果线程数量在并行区域之间动态变化,我不能依赖具有相同可重复分布的时间表(静态)。 –