[英]Is atomic.load() is faster than calling it normal
Recently I have been using atomic numbers alot in c++ as i use threading too much and thread safe is important to me最近我在 c++ 中使用了很多原子序数,因为我使用线程太多并且线程安全对我来说很重要
Well, I had a problem with printf() function here is an example好吧,我遇到了 printf() function 的问题,这是一个例子
atomic_uint64_t count = {0}
printf("%lu",count);
// It gives error couple of errors like atomic(cost atomic&) = delete; and use of deleted function atomic so i had to write it like this to make it work
printf("%lu",count.load());
// Or
printf("%lu",(uint64_t)count);
Well anyways i don't which is better for performance i really care about the speed好吧无论如何我不知道哪个对性能更好我真的很关心速度
So i started to thinking about which is better to retrieve the value and use it in if conditions or anywhere else所以我开始考虑哪个更好地检索值并在 if 条件或其他任何地方使用它
Like喜欢
if(count.load() < 8 ){
// Do smth
}
or或者
if(count < 8){
// Do smth
}
Which is better for speed and performance and thanks.哪个对速度和性能更好,谢谢。
They're exactly identical in their meaning (unless you pass a non-default memory order like count.load(std::memory_order_acquire)
).它们的含义完全相同(除非您传递非默认的 memory 订单,例如
count.load(std::memory_order_acquire)
)。
I'd expect there to be no difference in the generated assembly for all compilers across all ISAs, with optimization enabled of course.我希望为所有 ISA 的所有编译器生成的程序集没有区别,当然启用了优化。 There isn't for GCC/clang/MSVC/ICC in code I've looked at on https://godbolt.org/ .
我在https://godbolt.org/上查看的代码中没有 GCC/clang/MSVC/ICC。 This is true regardless of surrounding code its inlining into.
无论其内联到的周围代码如何,这都是正确的。
If there is ever a difference, and one is slower or takes more code-size, report that as a missed-optimization compiler bug in whatever compiler you're using.如果有任何差异,并且速度较慢或需要更多代码大小,请在您使用的任何编译器中将其报告为错过优化的编译器错误。 (Unless you had optimization disabled, then an extra level of calls to wrapper functions is possible.)
(除非您禁用了优化,否则对包装函数的额外调用是可能的。)
As for the error, that's because you're evaluating it in a context that doesn't already imply a type: as an operand for a variadic function ( printf
).至于错误,那是因为您在尚未暗示类型的上下文中对其进行评估:作为可变参数 function (
printf
) 的操作数。
If there's enough context to imply that you want the underlying T value from an atomic<T>
(which is what atomic_uint64_t
is), then the operator T()
overload is called, which is documented as being equivalent to .load()
.如果有足够的上下文暗示您想要来自
atomic<T>
的基础 T 值(这就是atomic_uint64_t
),则调用operator T()
重载,它被记录为等效于.load()
。 Same deal for assignment and .store()
.分配和
.store()
的交易相同。
There aren't any other functions that let you access only the low 32 bits of an atomic 64-bit integer (unfortunately);没有任何其他功能可以让您仅访问原子 64 位 integer 的低 32 位(不幸的是); even on a 32-bit machine, current compilers will actually go to the trouble of doing a 64-bit atomic load (which is efficient on some 32-bit machines, not on others), then discarding the high 32 if you cast the value to a narrower type.
即使在 32 位机器上,当前的编译器实际上也会 go 麻烦进行 64 位原子加载(这在某些 32 位机器上是有效的,而不是在其他机器上),然后如果你转换值,则丢弃高 32到更窄的类型。 (This is a missed-optimization, but compilers truly don't optimize atomics for the moment.)
(这是一个错过的优化,但编译器目前确实没有优化原子。)
So there's no ambiguity being resolved by .load
, or any way a cast can pick a different load.因此
.load
没有任何歧义可以解决,或者演员可以选择不同的负载。
One reason for the existence of .load()
and .store()
is that they take a std::memory_order
parameter, which is defaulted to seq_cst
but can be weaker if you just need atomicity but only acq/rel synchronization between threads. .load()
和.store()
存在的一个原因是它们采用std::memory_order
参数,该参数默认为seq_cst
但如果您只需要原子性但只需要线程之间的 acq/rel 同步,则可能会更弱。 Or none at all with relaxed
, just atomicity.或者根本没有
relaxed
的,只是原子性。
Another reason is to let you write foo.load()
to remind readers of you code that this is an atomic variable, not just a plain primitive type.另一个原因是让您编写
foo.load()
来提醒读者您的代码这是一个原子变量,而不仅仅是一个简单的原始类型。 For that style reason I'd prefer count.load()
.出于这种风格的原因,我更喜欢
count.load()
。 Presumably if you changed its type away from uint64_t
, you'd want to change how you printed it, not still cast it to uint64_t
.据推测,如果您将其类型从
uint64_t
更改,您会想要更改打印方式,而不是将其转换为uint64_t
。 Using .load()
will let the compiler warn you about the format-string mismatch if you change its type.如果您更改其类型,使用
.load()
将使编译器警告您格式字符串不匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.