[英]Atomic behavior of unary increment operators
Somewhere I read that unary operators are atomic by nature and so they can be used as it is in multi threaded environment. 在某处我读到一元运算符本质上是原子的,所以它们可以在多线程环境中使用。 To confirm the same, I wrote two separate programs where in 为了证实这一点,我写了两个单独的程序
I compared the disassembly of both programs and found no difference. 我比较了两个程序的反汇编,发现没有区别。 Please provide your inputs on this. 请提供您的意见。
Somewhere I read that unary operators are atomic by nature and so they can be used as it is in multi threaded environment. 在某处我读到一元运算符本质上是原子的,所以它们可以在多线程环境中使用。
That source is completely wrong. 那个来源是完全错误的。 You need to use std::atomic
(or the C equivalent) to achieve atomicity – unary operations are not special. 你需要使用std::atomic
(或C等价物)来实现原子性 - 一元操作并不特殊。
I compared the disassembly of both programs and found no difference 我比较了两个程序的反汇编,发现没有区别
That doesn't mean that the generated operations are atomic. 这并不意味着生成的操作是原子的。 There is no difference as any decent compiler will optimize x=x+1
and ++x
into the same assembly (assuming built-in types). 没有任何区别,因为任何体面的编译器都会将x=x+1
和++x
优化到同一个程序集中(假设内置类型)。
The assertion that a unary operator is necessarily atomic is a myth. 一元运算符必然是原子的断言是一个神话。
For example, ++x
requires a read and write to x
so that opens up the chance of a data race. 例如, ++x
需要对x
读写操作,以便开启数据竞争的机会。
The fact that ++x
compiles to the same code as x = x + 1
is not relevant. ++x
编译为与x = x + 1
相同的代码这一事实并不重要。
If you want to avoid data races then use atomic types, or mutual exclusion units if an appropriate atomic type is not available. 如果您想避免数据竞争,那么如果没有适当的原子类型,则使用原子类型或互斥单元。 For the avoidance of doubt, int
is not necessarily an atomic type. 为避免疑义, int
不一定是原子类型。
When writing cross platform C++, you only have atomic behavior when using std::atomic<>
. 编写跨平台C ++时,使用std::atomic<>
时只有原子行为。
It is true that on certain platforms, like Intel 64bit, the processor guarantees that inc
is atomic. 确实,在某些平台上,如Intel 64bit,处理器保证inc
是原子的。 However, please don't write code that depends on this! 但是,请不要编写依赖于此的代码! As your future debugger, I would like to know which data is intended to be shared over threads and which isn't. 作为您未来的调试器,我想知道哪些数据是通过线程共享的,哪些不是。
Using std::atomic<int>
might be a bit more work to write, however, it does guarantee that everything behaves atomically (on every platform) by either falling back to the platform requirements ( std::atomic::is_lock_free ), or by explicitly putting a lock around the access. 使用std::atomic<int>
可能需要更多的工作来编写,但是,通过回退到平台需求( std :: atomic :: is_lock_free ),它确实保证一切都在原子上(在每个平台上)。通过明确地锁定访问。 It as well insert guards in order to make sure that the caches of the other processor cores are invalidated (if the platform requires this). 它还插入防护装置以确保其他处理器核心的高速缓存无效(如果平台需要这样)。
In practice for Intel 64bit, this should give you the same assembly, if not, log a bug on your compiler. 在英特尔64位的实践中,这应该给你相同的程序集,如果没有,记录你的编译器的错误。
At the same time, some operations with ints might not be atomic (operator*=), std::atomic
simply doesn't hold those operations, requiring you to correctly work with those. 同时,一些使用int的操作可能不是原子的(operator * =), std::atomic
只是不能保存这些操作,要求你正确使用它们。
On a side note: ++x
and x = x+1
are different operations, they might be optimized to the same assembly. 旁注: ++x
和x = x+1
是不同的操作,它们可能针对同一个程序集进行了优化。 Given non-atomic platform requirements, the second suddenly is a bug which takes days to solve. 鉴于非原子平台要求,第二个突然是一个需要数天才能解决的错误。
Somewhere I read that unary operators are atomic by nature and so they can be used as it is in multi threaded environment. 在某处我读到一元运算符本质上是原子的,所以它们可以在多线程环境中使用。
That's false. 那是假的。 x++
for example requires a load of x
, an add and a store of x
. 例如, x++
需要加载x
,加载和x
的存储。 Those instructions are not atomic by nature. 这些指令本质上不是原子的。
Not true. 不对。 Even if it would be, what reason would https://en.cppreference.com/w/cpp/atomic/atomic#Type_aliases then have? 即使这样, https://en.cppreference.com/w/cpp/atomic/atomic#Type_aliases会有什么原因呢?
I think what they probably meant is that a computation on such operation is usually very minute and thus high likely to never have a race condition, which is mostly true in live code where you dont calculate x++ in 4 for loops simultaneously. 我认为它们可能意味着对这种操作的计算通常是非常微小的,因此很可能永远不会有竞争条件,这在实时代码中大多数情况下都是如此,在这种代码中你不会同时计算4 for for循环中的x ++。
You didn't specify the type of x. 您没有指定x的类型。
The atomicity of the of the operation stronglr depends on the target system. 操作stronglr的原子性取决于目标系统。 Unary operation might not be atomic on RMW systems like RISC micro controllers. 在RMW系统(如RISC微控制器)上,一元操作可能不是原子操作。
There is no single generic answer for this question. 这个问题没有一个通用的答案。
You make an assumption on the generated code, if only one instruction is generated yes it will be atomic, else no. 你对生成的代码做了一个假设,如果只生成一条指令,那么它将是原子的,否则为no。
In your case this supposes the target processor has the instruction inc <address>
and the compiler will produce it. 在您的情况下,这假设目标处理器具有指令inc <address>
,并且编译器将生成它。
Atomic behavior of unary operators 一元算子的原子行为
In C, pre/post fix ++
are not unary-operators such as & * + - ~ !
在C中,前/后修复++
不是一元运算符,例如& * + - ~ !
. 。 but part of a unary-expression . 但是一元表达的一部分 。 So the question title is inconsistent with the body. 因此问题标题与身体不一致。
Even a unary operator like +
is not atomic as access to the object (think long long
) make take multiple op code reads. 即使像+
这样的一元运算符也不是原子的,因为访问该对象(想想long long
)可以进行多个操作码读取。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.