【问题标题】:Atomic store. Structures原子商店。结构
【发布时间】:2016-07-22 08:00:17
【问题描述】:

我已经编译并分析了汇编输出:

struct S{
public:
    int a,b,c,d,e,f,g,h,i,j,k;
};

int main() {
    S s;
    std::atomic<S> as;
    as.store(s);
    return 0;
}

我想看看它实际上是如何实现atomic store 的。当涉及对齐的“小”操作数时,这很容易。但是,现在我们有一个更广泛的操作数,所以情况更加复杂。

在我的另一个问题中(Atomicity on x86)@Peter Cordes 说:

对于更广泛的操作数,例如以原子方式将新数据写入多个 一个结构的条目,你需要用一个锁来保护它 访问它的尊重。 (您也许可以使用 x86 lock cmpxchg16b 使用重试循环来执行原子 16b 存储。注意没有办法 在没有锁的情况下模拟它。)

好的,但这究竟是什么意思?锁定是什么意思? 特别是,我知道lock 是一个前缀,可以确保“前缀”指令的原子性。特别是,@Peter Cordes 说:

您也许可以使用 x86 锁 cmpxchg16b 使用重试循环进行原子 16b 存储

我无法理解如何保持它的原子性?好的,我可以想象16B的内存可以以原子方式存储吗?但是下一次迭代呢?

我希望我的疑问可以理解,因为我表达起来有问题。


我正在调试上面的程序,在我看来,atomic_store 背后的魔力。 我想这个函数执行@Peter Cordes 所说的。如果有人要,我可以在这里贴上拆机__atomic_store

【问题讨论】:

  • 你说你分析了生成的机器码。那么,可以告诉我们这是如何实现的!
  • 是的,继续粘贴 __atomic_store 的反汇编。 gcc 只是使用通过引用传递的要存储的数据生成对它的调用。
  • 我错过了这里的问题吗??
  • @DavidHoelzer:不,你没有遗漏任何东西,这里没有真正的问题。我的“答案”一开始是评论,但后来我意识到它确实回答了一些问题,所以我继续做一个答案。整个事情可能应该是对我对上一个问题的回答的评论/回复。

标签: c++ multithreading assembly x86


【解决方案1】:

您可以使用带有重试循环的 x86 锁 cmpxchg16b 来执行原子 16B 存储

我真的说的是 16b 而不是 16B 吗?哎呀。我会在更大的修改中修复它。

这可以让您进行 一个 16B 原子存储,但将其作为读取-修改-重写来执行,它会不断重试,直到比较部分成功。您不能使用它以原子方式存储超过 16B。


锁定是什么意思?特别是,我知道 lock 是一个前缀,可以确保“前缀”指令的原子性。

锁定为自旋锁/互斥锁,而不是lock 前缀。 lock 前缀仅适用于读-修改-写指令;没有lock mov [mem], eax 可以进行原子未对齐存储或其他操作。 locked 总线周期始终是读-修改-写,正如英特尔在 cmpxchg 的文档中所记录的那样。所以lock mov 存储也会产生一个负载,如果你在内存映射 I/O 上使用它,它具有不同的语义。 (读取会触发副作用)。


我已经编译并分析了...的程序集输出

你为什么要把那段代码放在main() 中,并将s 中的未初始化垃圾存储到as 中?除此之外,main 在某些方面也很特别。最好只编写一个带有 arg 的函数(或仅影响全局)。 atomic&lt;s&gt; 需要是全局的,而不是可能被部分优化掉的局部,如果你想确定你看到 gcc “真正”做了什么。

#include <atomic>
struct S{ int a,b,c,d,e,f,g,h,i,j,k;  };  // or int a[11]
std::atomic<S> as;
void atomic_struct_store_zero() {
    S s = { 0 };     // initializes all members to zero
    as.store(s);
}

这个compiles to 是一个对__atomic_store 的函数调用,传递src 和dest 指针以及一个大小。大概它在某处使用了锁,但锁不是as 的一部分。 (sizeof(as) == sizeof(S) == 44)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多