C ++:OpenMP共享内存保护

时间:2012-06-11 10:03:04

标签: c++ multithreading parallel-processing openmp shared-memory

如果我使用共享变量,让我们说一个double,来计算程序执行时的某种总和。无论如何,这是否容易受到非稳定运营的影响?我的意思是,是否有可能多个核心以异步方式访问此变量并导致不稳定的结果?

例如: 这是一个全局变量:

double totalTime = 0;

并在每个核心中调用一个命令:

totalTime += elapsedTime;

通过获取totalTime的值,将其作为CPU寄存器,然后执行添加来执行最后一个操作/语句。我可以想象,不止一个核心会在同一时刻获取相同的值,然后添加新的elapsedTime,然后由于延迟,存储在totalTime中的值将被错误的值覆盖。那可能吗?我该如何解决这个问题?

谢谢。

1 个答案:

答案 0 :(得分:5)

显然,此操作不是线程安全的,因为正如您自己提到的,它涉及多个汇编程序指令。事实上,openMP甚至对这种操作有一个特殊的指令。

你需要atomic pragma才能成功,“原子”:

#pragma omp atomic
totalTime += elapsedTime;

请注意,atomic仅在您对内存位置进行单次更新时才有效,例如添加,增量等。

如果您有一系列需要原子化的指令,则必须使用critical指令:

#pragma omp critical
{
    // atomic sequence of instructions
}

编辑:这是“snemarch”的一个很好的建议:如果你在一个并行循环中反复更新全局变量totalTime,你可以考虑使用reduction子句来自动化流程并提高效率:

double totalTime = 0;

#pragma omp parallel for reduction(+:totalTime)
for(...)
{
    ...
    totalTime += elapsedTime;
}

最后totalTime将正确包含本地elapsedTime值的总和,而无需显式同步。