原子地读取非原子变量? [英] Read a non-atomic variable, atomically?

查看:65
本文介绍了原子地读取非原子变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非原子的62位double,它在一个线程中有规律地递增.此访问不必是原子的.但是,此变量有时会被另一个线程读取(而不是写入).如果我在64位边界上对齐变量,则读取的内容是原子的.

但是,有什么方法可以确保在增量过程中途不读取变量?我可以调用一个CPU指令来对管道进行序列化吗?记忆障碍?

我考虑过在我的关键线程中声明变量atomic,并使用 std :: memory_order :: memory_order_relaxed (在稀有线程中使用更严格的内存屏障),但这似乎同样昂贵

解决方案

自从您标记了x86,这将是特定于x86的.

增量基本上是三个部分,分别是读取,添加和写入.增量不是原子的,但是所有三个步骤(我想加法都不算,总之是不可见的),只要变量不跨越缓存行边界(此条件比必须对齐要弱)就可以了.保持自然对齐,直到P6必须对齐为止.

因此您已经无法读取残缺的值.最糟糕的是,在读取变量和写入新值之间会覆盖该变量,但您只能读取它.

I have a non-atomic 62-bit double which is incremented in one thread regularly. This access does not need to be atomic. However, this variable is occasionally read (not written) by another thread. If I align the variable on a 64-bit boundary the read is atomic.

However, is there any way I can ensure I do not read the variable mid-way during the increment? Could I call a CPU instruction which serialises the pipeline or something? Memory barrier?

I thought of declaring the variable atomic and using std::memory_order::memory_order_relaxed in my critical thread (and a stricter memory barrier in the rare thread), but it seems to be just as expensive.

解决方案

Since you tagged x86, this will be x86-specific.

An increment is essentially three parts, read, add, write. The increment is not atomic, but all three steps (the add doesn't count I suppose, it's not observable anyway) of it are as long as the variable does not cross a cache line boundary (this condition is weaker than having to be aligned to its natural alignment, it has been like this as of P6, before that quadwords had to be aligned).

So you already can't read a torn value. The worst you could do is overwrite the variable in between the moments where it is read and the new value is written, but you're only reading it.

这篇关于原子地读取非原子变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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