C++:OpenMP共享内存保护

6 c++ parallel-processing multithreading openmp shared-memory

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

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

double totalTime = 0;
Run Code Online (Sandbox Code Playgroud)

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

totalTime += elapsedTime;
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Tud*_*dor 5

显然,此操作不是线程安全的,因为正如您所提到的,它涉及多个汇编程序指令。实际上,openMP甚至具有针对此类操作的特殊指令。

您将需要atomic实用性来使其成为“原子的”:

#pragma omp atomic
totalTime += elapsedTime;
Run Code Online (Sandbox Code Playgroud)

请注意,atomic仅在对存储位置进行单个更新(例如加法,增量等)时有效。

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

#pragma omp critical
{
    // atomic sequence of instructions
}
Run Code Online (Sandbox Code Playgroud)

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

double totalTime = 0;

#pragma omp parallel for reduction(+:totalTime)
for(...)
{
    ...
    totalTime += elapsedTime;
}
Run Code Online (Sandbox Code Playgroud)

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