gpt4 book ai didi

c++ - OpenMP 原子和非原子读/写在 x86_64 上产生相同的指令

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:45:17 27 4
gpt4 key购买 nike

根据 OpenMP 规范 (v4.0),由于 i 的不同步读/写,以下程序包含可能的数据竞争:

int i{0}; // std::atomic<int> i{0};

void write() {
// #pragma omp atomic write // seq_cst
i = 1;
}

int read() {
int j;
// #pragma omp atomic read // seq_cst
j = i;
return j;
}

int main() {
#pragma omp parallel
{ /* code that calls both write() and read() */ }
}

我想到的可能的解决方案在代码中显示为注释:

  1. 保护i的读写与 #pragma omp atomic write/read ,
  2. 保护i的读写与 #pragma omp atomic write/read seq_cst ,
  3. 使用std::atomic<int>而不是 int作为 i 的一种.

这是编译器在 x86_64 上生成的指令(在所有情况下都是 -O2):

GNU g++ 4.9.2:               i = 1;        j = i;
original code: MOV MOV
#pragma omp atomic: MOV MOV
// #pragma omp atomic seq_cst: MOV MOV
#pragma omp atomic seq_cst: MOV+MFENCE MOV (see UPDATE)
std::atomic<int>: MOV+MFENCE MOV

clang++ 3.5.0: i = 1; j = i;
original code: MOV MOV
#pragma omp atomic: MOV MOV
#pragma omp atomic seq_cst: MOV MOV
std::atomic<int>: XCHG MOV

Intel icpc 16.0.1: i = 1; j = i;
original code: MOV MOV
#pragma omp atomic: * *
#pragma omp atomic seq_cst: * *
std::atomic<int>: XCHG MOV

* Multiple instructions with calls to __kmpc_atomic_xxx functions.

我想知道为什么 GNU/clang 编译器不为 #pragma omp atomic 生成任何特殊指令写。我期望与 std::atomic 类似的说明,即 MOV+MFENCEXCHG .有什么解释吗?

更新

g++ 5.3.0 生成 MFENCE对于 #pragma omp atomic write seq_cst .我相信这是正确的行为。没有 seq_cst , 它产生普通的 MOV , 这对于非 SC 原子性是足够的。

我的 Makefile 中有一个错误,g++ 4.9.2 生成 MFENCE也适用于 CS 原子写入。对不起大家。

Clang 3.5.0 未实现 OpenMP SC 原子,感谢 Hristo Iliev 指出这一点。

最佳答案

有两种可能。

  1. 编译器没有义务将包含数据竞争的 C++ 代码转换为错误的机器代码。根据机器内存模型,通常使用的指令可能已经是原子的和连贯的。将相同的 C++ 代码用于另一个架构,您可能会开始看到 pragma 导致 x86_64 上不存在的差异。

  2. 除了可能导致使用不同的指令和/或额外的内存栅栏指令之外,原子编译指示(以及 std::atomicvolatile)还限制了编译器自己的代码重新排序优化。它们可能不适用于您的简单情况,但您肯定会看到公共(public)子表达式消除(包括循环外的提升计算)可能会受到影响。

关于c++ - OpenMP 原子和非原子读/写在 x86_64 上产生相同的指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35462453/

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