C++:OpenMP 共享内存保护
C++: OpenMP shared memory protection
如果我使用共享变量,比如说双精度,来计算程序执行过程中的某种总和。这是否容易受到不稳定操作的影响?我的意思是,是否有可能多个内核以异步方式访问此变量并导致不稳定的结果?
例如:这是一个全局变量:
double totalTime = 0;
在每个内核中调用一个命令:
totalTime += elapsedTime;
最后一个操作/语句是通过获取 totalTime 的值来执行的,将其放入 CPU 寄存器,然后进行加法。我可以想象,多个内核会在同一时刻采用相同的值,然后添加新的 elapsedTime,然后由于延迟,存储在 totalTime 中的值将被错误的值覆盖。这可能吗?我该如何解决这个问题?
谢谢。
显然,此操作不是线程安全的,因为正如您自己提到的,它涉及多个汇编程序指令。事实上,openMP 甚至对这种操作有特殊的指令。
您将需要atomic
编译指示来使其"原子":
#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
值的总和,而无需显式同步。
相关文章:
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 多个"常量引用"变量可以共享同一个内存吗?
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 公共/私有/受保护是否会更改内存中结构的排列?
- 字符串共享内存映射的向量
- CUDA 使用共享内存平铺 3D 卷积实现
- 共享内存:MapViewOfFile 返回错误 5
- 在共享缓冲区内存中创建 ::std::string 对象
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- Directx 12 :在两个进程之间共享图形内存
- 有没有办法列出所有共享内存对象的名称?
- 子进程更新共享 mmap 内存,但父进程没有更改
- 检查nullptr是否100%保护内存布局不受segfault影响
- Boost.SML - 违反内存保护/分段错误
- 使用硬件内存保护对64位硬件进行数组边界检查
- C++:OpenMP 共享内存保护
- 写入/读取受内存保护的进程的内存
- 符号可见性是否保护共享库免遭滥用/破解?
- 如何保护两个进程之间共享内存中的字符串?