vol*_*evo 16 c++ cpu instruction-set minimum
编程中一种非常常见的模式是在某种更新后将值限制在最大值.我想知道的是,如果以下两段代码之间存在差异,并且是否应该首选:
value += increment;
value = std::min(value, valueMax);
Run Code Online (Sandbox Code Playgroud)
VS
value += increment;
if (value > valueMax)
value = valueMax;
Run Code Online (Sandbox Code Playgroud)
我的想法是,这取决于CPU是否有获取两个值并产生最小值的指令.如果是这样,对std :: min的调用应该导致该指令并避免不必要的分支.如果不是,则第二个版本在值<= valueMax时避免不必要的赋值.
我对这种事情不是很了解,但我确信有老派的黑客大佬会知道这一点.我问他们:哪个更好?
gre*_*rep 11
现代编译器非常智能,可以在两种情况下生成相同的代码.例如,32位GCC生成:
addl %esi, %edi
cmpl %edx, %edi
movl %edi, %eax
cmovgl %edx, %eax
Run Code Online (Sandbox Code Playgroud)
64位Clang:
%1 = add nsw i32 %increment, %value
%2 = icmp sgt i32 %1, %valueMax
%value = select i1 %2, i32 %valueMax, i32 %1
Run Code Online (Sandbox Code Playgroud)
在 VC10 版本上,对于以下代码,我们有以下程序集:
int main(int argc, char *argv[])
{
int dummyValue = 0, valueMax = 3000, value = valueMax + 1;
cin >> valueMax;
cin >> value;
dummyValue = std::min(value, valueMax);
cout << dummyValue;
cin >> valueMax;
cin >> value;
if (value > valueMax)
dummyValue = valueMax;
cout << dummyValue;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
生成:
24: dummyValue = std::min(value, valueMax);
00E112AF mov eax,dword ptr [valueMax]
00E112B2 cmp eax,dword ptr [value]
00E112B5 lea edx,[value]
00E112B8 lea ecx,[valueMax]
00E112BB cmovge ecx,edx // <-- this is our conditional assignment
00E112BE mov esi,dword ptr [ecx]
Run Code Online (Sandbox Code Playgroud)
和
if (value > valueMax)
dummyValue = valueMax
00E112ED mov eax,dword ptr [valueMax]
00E112F0 cmp dword ptr [value],eax
00E112F3 mov ecx,dword ptr ds:[0E13038h]
00E112F9 cmovg esi,eax
Run Code Online (Sandbox Code Playgroud)
因此这两种情况都针对cmovgeorcmovg指令进行了优化。
我仍然会同意,std::min因为它比if声明更能显示意图。它已经过优化并且更具可读性。