c++ - 如何在并行区域之外维护变量的值?

标签 c++ c openmp

一个简单的 OpenMP 程序:

#include <omp.h>
#include <iostream>

int main() {
  int var = 0;
  int var2 = 0;
  #pragma omp parallel private(var) shared(var2)
  {
    var = 1;
    int tid = omp_get_thread_num();
    printf("Inside the parallel region, var gets modified by thread #%d to %d\n",tid,var);
    if(tid == 0)
      var2 = var;
  }
  printf("Outside the parallel region, var  = %d\n", var);
  printf("Outside the parallel region, var2 = %d\n", var2);
}

结果:

Inside the parallel region, var gets modified by thread #3 to 1
Inside the parallel region, var gets modified by thread #0 to 1
Inside the parallel region, var gets modified by thread #6 to 1
Inside the parallel region, var gets modified by thread #1 to 1
Inside the parallel region, var gets modified by thread #5 to 1
Inside the parallel region, var gets modified by thread #7 to 1
Inside the parallel region, var gets modified by thread #2 to 1
Inside the parallel region, var gets modified by thread #4 to 1
Outside the parallel region, var  = 0
Outside the parallel region, var2 = 1

我想做的是将 var 的值设置为并行区域内最后修改的值。

因为它不是#pragma omp for 循环,所以lastprivate 无法使用。

在并行区域之外,var 获取其原始值 0。一个技巧是使用共享变量 var2 来存储来自主线程的修改后的值。

但这会增加开销并且似乎不是一种优雅的方法,如果我想获得由 last 线程修改的值,而不是主线程,(例如找出哪个线程最后完成),那么这个技巧将不起作用。

我是 OpenMP 的新手,所以我可能遗漏了一些东西。如果我不是,有什么方法可以克服这个棘手的事情吗?

非常感谢。

编辑:我的问题是关于如何在并行区域完成后保留私有(private)变量的最后一个值。或者,如果您能解释为什么 lastprivate 在概念上不能用于 #pragma omp parallel,我会把它作为一个完美的答案。

最佳答案

要找出哪个线程最后完成,请让每个线程将其完成时间写入一个数组。该数组的大小至少应为 omp_get_max_threads()。在并行区域内使用 omp_get_thread_num() 对其进行索引。

一旦代码离开并行区域,找到数组中的最大值。

理想情况下,数组应该对齐并填充,以便每个元素都位于单独的缓存行中,这样线程在写入完成时间时就不必绕过共享缓存行。

如果并行区域位于程序的外层,还有另一种更巧妙的方法可以利用线程私有(private)变量在顶层并行区域之间保留它们的值这一事实来做到这一点.以下是如何利用此技巧的示例。

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

double tmp;
#pragma omp threadprivate(tmp)

int main() {
    double start = omp_get_wtime();
#pragma omp parallel
    {
        sleep(1);
        tmp = omp_get_wtime();
    }
    double finish=start;
#pragma omp parallel reduction(max:finish)
    {
        if( tmp>finish ) finish = tmp;
    }
    printf("last thread took time = %g\n",finish-start);
}

关于c++ - 如何在并行区域之外维护变量的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16095390/

相关文章:

c++ - 返回的 const 引用究竟何时被销毁?

c++ - openMP 嵌套并行 for 循环与内部并行 for

c++ - 在 CPU 上并行减少数组

c++ - 打开 Mp 嵌套并行

c - 使用表单数据时看不到 C 中上传的文件

c++ - 如何 boost::fusion::for_each 添加类型以创建类型的 mpl::vector?

c++ - 我如何处理字母和负数时出错?

c++ - 找不到 FinishMonsterBuffer() 方法

c - valgrind 在打印分配的字符串时报错

c - C 中负值的处理