OpenMP:并行(i;…)和i值

OpenMP: parallel for(i;...) and i value

本文关键字:并行 OpenMP      更新时间:2023-10-16

我有以下并行代码片段:

#include <omp.h>
#include "stdio.h"
int main()
{
omp_set_num_threads(4);
    int i;
#pragma omp parallel private(i)
    {
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %dn", omp_get_thread_num(),i);
        }
#pragma omp critical
        printf("i  %d: %dn", omp_get_thread_num(), i ); 
    }
}

我认为在循环之后,每个线程的i将等于该线程循环中i的最后一个值。我希望的输出是:

A  0: 0
A  0: 1
A  0: 2
A  3: 9
A  2: 6
A  2: 7
A  2: 8
A  1: 3
A  1: 4
A  1: 5
i  0: 3
i  3: 10
i  2: 9
i  1: 6

而我得到的是

A  0: 0
A  0: 1
A  0: 2
A  3: 9
A  2: 6
A  2: 7
A  2: 8
A  1: 3
A  1: 4
A  1: 5
i  0: -1217085452
i  3: -1217085452
i  2: -1217085452
i  1: -1217085452

如何使i保持上次迭代的值?lastprivate(i)使i = 10为所有线程,这不是我想要的。

事实证明你不能。OpenMP改变了程序语义。

编译器根据一组定义良好的规则重写并行for循环。

这也意味着您不能从这样的循环中中断或返回。您也可以不直接操作循环变量。循环条件不能调用随机函数或执行任何条件表达式,简而言之: omp parallel for循环是而不是 for循环

#include <omp.h>
#include "stdio.h"
int main()
{
omp_set_num_threads(4);
#pragma omp parallel
    {
        int i;
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %dn", omp_get_thread_num(),i);
        }
#pragma omp critical
        printf("i  %d: %dn", omp_get_thread_num(), i ); 
    }
}

多亏了sehe的帖子,我想出了下面的肮脏技巧来解决这个问题

    int i, last_i;
#pragma omp parallel private(i)
    {
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %dn", omp_get_thread_num(),i);
            last_i = i;
        }
#pragma omp critical
        printf("i  %d: %dn", omp_get_thread_num(), last_i ); 
    }
}