原子存储.结构体 [英] Atomic store. Structures

查看:107
本文介绍了原子存储.结构体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为以下程序编译并分析了程序集输出:

I've compiled and analyzed the assembly output for:

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;
}

我想看看它实际上是如何实现的.对齐对齐的小"操作数很容易.但是,现在我们有一个更宽的操作数,因此情况更加复杂.

I want to see how does is it implemented atomic store in fact. It is easy when it comes to aligned "small" operands. But, now we have a wider operand so it is a more complicated situation.

在我的另一个问题中( x86上的原子性)@彼得·科德斯(Peter Cordes)说:

In my other question ( Atomicity on x86) @Peter Cordes said:

对于更宽的操作数,例如以原子方式将新数据写入多个 一个结构的条目,您需要用一个锁来保护它,所有 获得尊重. (您可能可以使用x86锁cmpxchg16b 使用重试循环来执行原子16b存储.请注意,这是不可能的 来模拟它而没有锁.)

For wider operands, like atomically writing new data into multiple entries of a struct, you need to protect it with a lock which all accesses to it respect. (You may be able to use x86 lock cmpxchg16b with a retry loop to do an atomic 16b store. Note that there's no way to emulate it without a lock.)

好,但这到底是什么意思?锁定是什么意思? 特别是,我知道lock是确保前缀"指令原子性的前缀.特别是@Peter Cordes说:

Ok, but what does it mean exactly? What does it mean to lock? Especially, I know that lock is a prefix that ensures about atomicity of "prefixed" instruction. Especially, @Peter Cordes said:

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

You may be able to use x86 lock cmpxchg16b with a retry loop to do an atomic 16b store

我不明白如何保持原子性?好吧,我可以想象16B的内存块可以原子方式存储吗?但是接下来的迭代呢?

I cannot understand how it is possible to keep it atomic? Ok, I can imagine that 16B chunk of memory can be stored in atomic way? But what about next iterations?

我希望我的疑问是可以理解的,因为我在表达问题时遇到了问题.

I hope that my doubts are understandable because I had a problem to express it.

我正在调试上面的程序,并且在我看来,atomic_store背后的魔力. 我想这个函数执行@Peter Cordes所说的.如果有人愿意,我可以在这里粘贴分解后的__atomic_store

I was debugging above program and, on my eye, the magic is behind atomic_store. I suppose that this function executes what @Peter Cordes said. If someone wants, I can paste here disassembled __atomic_store

推荐答案

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

You may be able to use x86 lock cmpxchg16b with a retry loop to do an atomic 16B store

我真的是说16b而不是16B吗?哎呀.我将在较大的修改中解决该问题.

Did I really say 16b instead of 16B? oops. I'll fix that as part of a larger edit.

这使您可以进行一个 16B原子存储,但是可以作为read-modify-rewrite进行操作,该操作会不断重试,直到比较部分成功为止.您不能使用此原子存储超过16B的内存.

That lets you do one 16B atomic store, but do it as a read-modify-rewrite that keeps retrying until the compare part succeeds. You can't use this to store more than 16B atomically.

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

What does it mean to lock? Especially, I know that lock is a prefix that ensures about atomicity of "prefixed" instruction.

与自旋锁/互斥锁中的锁相同,而不是lock前缀. lock前缀仅对读-修改-写指令有效;没有lock mov [mem], eax可以进行原子不对齐的存储或其他操作.英特尔在 c8> .因此,lock mov存储区也将生成负载,如果在内存映射的I/O上使用它,则其语义将有所不同. (读取可能会引起副作用).

Lock as in spinlock / mutex, not lock prefix. The lock prefix only ever works on read-modify-write instructions; there is no lock mov [mem], eax to do an atomic unaligned store or something. locked bus cycles are always read-modify-write, as documented by Intel in the docs for cmpxchg. So a lock mov store would also generate a load, which has different semantics if you use it on memory-mapped I/O. (A read can trigger side effects).

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

I've compiled and analyzed the assembly output for ...

为什么要将代码放在main()中,并将未初始化的垃圾从s存储到as中?除此之外,main在某些方面很特殊.编写一个带有arg的函数(或仅影响全局)总是更好.并且atomic<s>需要是全局的,而不是可能会被部分优化的局部变量,如果您想确保您看到的是gcc真正"的作用.

Why would you put that code in main(), and store uninitialized garbage from s into as? Besides that, main is special in a few ways. Always better to just write a function that takes an arg (or just affects a global). And the atomic<s> needs to be global, not a local that can potentially be partly optimized away, if you want to be sure you're seeing what gcc "really" does.

#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);
}

This compiles to a function call to __atomic_store, passing src and dest pointers and a size. Presumably it uses a lock somewhere, but the lock isn't part of as. (sizeof(as) == sizeof(S) == 44).

这篇关于原子存储.结构体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆