std :: atomic <int>上的预增量与后增量

时间:2016-11-29 10:17:21

标签: c++ c++11 stl atomic

常见的经验法则是在没有立即计算值的情况下(即你只想增加对象/迭代器),更喜欢在STL迭代器上使用预增量。这是因为通常预增量的实现比后增量更有效。

但是std :: atomic怎么样?如果我运行静态分析(使用PVS工作室),我会收到一个警告,说预增量应该更有效,但是当我查看预增量的实现时(在Visual Studio 2015上),它看起来效率低于后增量?

对STL原子值使用预增量超过后增量是否有一般规则,还是特定于实现?

2 个答案:

答案 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迭代器的预增量”,事实证明,实际上很少有编译器会为预增量和后增量生成不同的代码。 (后增量的虚假副本只会被优化为零。)