常见的经验法则是在没有立即计算值的情况下(即你只想增加对象/迭代器),更喜欢在STL迭代器上使用预增量。这是因为通常预增量的实现比后增量更有效。
但是std :: atomic怎么样?如果我运行静态分析(使用PVS工作室),我会收到一个警告,说预增量应该更有效,但是当我查看预增量的实现时(在Visual Studio 2015上),它看起来效率低于后增量?
对STL原子值使用预增量超过后增量是否有一般规则,还是特定于实现?
答案 0 :(得分:3)
我现在无法访问Windows,但在gcc中,区别在于
__atomic_fetch_add(&_M_i, 1, memory_order_seq_cst);
和
__atomic_add_fetch(&_M_i, 1, memory_order_seq_cst);
是内置的,因此您可以假设编译器知道如何优化它。
如果你不使用结果,gcc -O3会产生
lock add DWORD PTR [rdi], 1
两者兼而有之。
如果您确实使用了结果,那么gcc -O3会产生
mov DWORD PTR [rsp-24], edi
mov eax, 1
lock xadd DWORD PTR [rsp-24], eax
add eax, 1
ret
用于预增量,并省略add eax, 1
用于后增量,所以从技术上讲,是的,预增量通过一次添加效率较低,但实际上与顺序存储器访问相比相形见绌。
TLDR:不用担心
答案 1 :(得分:1)
效率(在此级别)始终特定于实施。
例如,作为经验法则的计数器“更喜欢STL迭代器的预增量”,事实证明,实际上很少有编译器会为预增量和后增量生成不同的代码。 (后增量的虚假副本只会被优化为零。)