gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:57:33 26 4
gpt4 key购买 nike

一个简单的 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com