简体   繁体   English

atomic.load() 是否比正常调用更快

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM