Sag*_*ian 10 c c++ optimization assembly post-increment
我想知道两种增量形式之间是否存在差异.一些链接说i ++比i = i + 1更快;
另外作为人之一,我的观察对于汇编代码也是一样的.请检查图像,其中汇编代码对于i ++和i = i + 1都是相同的 -
还有另一个链接说,之前的增量运算符比加法和赋值更快,但现在编译器优化i ++和i = i + 1相同.
是否有任何官方文件/文件我们可以参考确认什么是正确的?(我通常会使用信用卡和一个人在stackoverflow上接受的答案数量.在我提供的链接上找不到任何此类信息).
Ale*_*lke 15
实际上,如果你使用C++,那么习惯于编写代码会好得多++i
.原因很简单:i++
需要一份副本.
a = ++i; // a is set to the result of i+1
a = i++; // make a copy of i, compute i+1, save the copy of i in a
Run Code Online (Sandbox Code Playgroud)
如果没有优化,汇编代码将如下所示:
a = ++i; a = i++;
MOV eax, (i) MOV eax, (i)
PUSH eax
ADD eax, 1 ADD eax, 1
MOV (i), eax MOV (i), eax
POP eax
MOV (a), eax MOV (a), eax
Run Code Online (Sandbox Code Playgroud)
现在,通过优化,结果在C中是相同的,其中++
运算符仅适用于整数和指针.
在++
和--
正在那里,因为大多数处理器有一个INC
和DEC
指令的时间C编写的.因此,如果您要使用索引寄存器,则将应用以下指令:
char a[256];
...init 'a' in some way...
int sum =0;
for(int i = 0; i < 100; ++i)
{
sum += a[i];
}
Run Code Online (Sandbox Code Playgroud)
这可以通过INC
(6502)中的简单来完成:
LDA #00
LDY #00
LOOP:
CLC
ADC ($80),Y
INY <-- ++i or i++
CPY #100
BCC LOOP
Run Code Online (Sandbox Code Playgroud)
请注意,在C中我们有另一种表示法来增加变量:
i += 1;
Run Code Online (Sandbox Code Playgroud)
如果您需要将寄存器增加1以上,这是实用的:
i += 3;
Run Code Online (Sandbox Code Playgroud)
或者每次加倍注册:
i += i; // (equivalent to i *= 2; or i <<= 1; in C++)
Run Code Online (Sandbox Code Playgroud)
问:为什么INC
并DEC
没有与所有的80x86使用?
曾经有时间ADD reg, 1
和SUB reg, 1
指令比INC reg
和DEC reg
.在过去,它更快,因为指令更小,我们没有缓存(或非常少).今天,任何一条指令都可能大致相同.
从下面的评论来看,"缓慢"的原因是FLAGS注册:
从另一个更新的评论来看,英特尔文档中引用的缓慢似乎已在较新的处理器中得到修复.因此,如果事先知道,这些指令的使用或不使用应取决于目标处理器.
正如在评论中指出phresnel,之间的差异i++
,并++i
很可能不清楚了很多人.对于整数,优化实际上是微不足道的,即使使用-O0也肯定会发生.但是,在C++中,这是一个不同的故事.有一个类有两个增量运算符清楚地表明需要一个副本i++
(即使data_
只是一个整数,但在这种情况下你也可以这样做:return data_++
- 它仍然需要一个隐藏良好的副本!):
class A
{
public:
A& operator ++ () // ++i -- no copy
{
...apply the ++ operation to 'data_'...
return *this; // return a reference to this
}
A operator ++ (int) // i++ -- needs a temporary copy
{
// remember that the 'int' is totally ignored in the function,
// its only purpose is to distinguish '++i' from 'i++'
A copy = *this; // here we need a copy
++*this;
return copy; // and here we return said copy
}
private:
some_type_t data_;
};
Run Code Online (Sandbox Code Playgroud)
请注意,现代C++编译器不会在i++
函数中生成两个副本,因为可以优化返回值,而无需额外的副本.
这两种情况下之间的差可以被示出为清楚地较慢,如果使用i++
如上述是否有性能差异之间我++和在C++ ++ i的?(菲涅耳提到的链接)
没有官方文件.c规范没有声明i ++必须比i + 1更快,因此编译器/优化器可以自由地做他们喜欢的事情(并且他们可以根据周围的代码和优化级别做出不同的选择).
我使用i ++是因为我阅读速度更快,错误输入的字符更少.