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中的值将被错误的值覆盖.那可能吗?我该如何解决这个问题?
谢谢.
显然,此操作不是线程安全的,因为正如您所提到的,它涉及多个汇编程序指令。实际上,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值的总和,而无需显式同步。
| 归档时间: |
|
| 查看次数: |
1399 次 |
| 最近记录: |