[英]Is atomic.load() is faster than calling it normal
最近我在 c++ 中使用了很多原子序数,因为我使用线程太多并且线程安全对我来说很重要
好吧,我遇到了 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);
好吧无论如何我不知道哪个对性能更好我真的很关心速度
所以我开始考虑哪个更好地检索值并在 if 条件或其他任何地方使用它
喜欢
if(count.load() < 8 ){
// Do smth
}
或者
if(count < 8){
// Do smth
}
哪个对速度和性能更好,谢谢。
它们的含义完全相同(除非您传递非默认的 memory 订单,例如count.load(std::memory_order_acquire)
)。
我希望为所有 ISA 的所有编译器生成的程序集没有区别,当然启用了优化。 我在https://godbolt.org/上查看的代码中没有 GCC/clang/MSVC/ICC。 无论其内联到的周围代码如何,这都是正确的。
如果有任何差异,并且速度较慢或需要更多代码大小,请在您使用的任何编译器中将其报告为错过优化的编译器错误。 (除非您禁用了优化,否则对包装函数的额外调用是可能的。)
至于错误,那是因为您在尚未暗示类型的上下文中对其进行评估:作为可变参数 function ( printf
) 的操作数。
如果有足够的上下文暗示您想要来自atomic<T>
的基础 T 值(这就是atomic_uint64_t
),则调用operator T()
重载,它被记录为等效于.load()
。 分配和.store()
的交易相同。
没有任何其他功能可以让您仅访问原子 64 位 integer 的低 32 位(不幸的是); 即使在 32 位机器上,当前的编译器实际上也会 go 麻烦进行 64 位原子加载(这在某些 32 位机器上是有效的,而不是在其他机器上),然后如果你转换值,则丢弃高 32到更窄的类型。 (这是一个错过的优化,但编译器目前确实没有优化原子。)
因此.load
没有任何歧义可以解决,或者演员可以选择不同的负载。
.load()
和.store()
存在的一个原因是它们采用std::memory_order
参数,该参数默认为seq_cst
但如果您只需要原子性但只需要线程之间的 acq/rel 同步,则可能会更弱。 或者根本没有relaxed
的,只是原子性。
另一个原因是让您编写foo.load()
来提醒读者您的代码这是一个原子变量,而不仅仅是一个简单的原始类型。 出于这种风格的原因,我更喜欢count.load()
。 据推测,如果您将其类型从uint64_t
更改,您会想要更改打印方式,而不是将其转换为uint64_t
。 如果您更改其类型,使用.load()
将使编译器警告您格式字符串不匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.