如果我写
int main(int argc, char *argv[])
{
int temp[50][3];
return &temp[argc] - &temp[0];
}
并用 Visual C++ 编译它,我得到:
009360D0 55 push ebp
009360D1 8B EC mov ebp,esp
009360D3 8B 45 08 mov eax,dword ptr [argc]
009360D6 8D 0C 40 lea ecx,[eax+eax*2]
009360D9 B8 AB AA AA 2A mov eax,2AAAAAABh
009360DE C1 E1 02 shl ecx,2
009360E1 F7 E9 imul ecx
009360E3 D1 FA sar edx,1
009360E5 8B C2 mov eax,edx
009360E7 C1 E8 1F shr eax,1Fh
009360EA 03 C2 add eax,edx
009360EC 5D pop ebp
009360ED C3 ret
为什么我会得到一个imul
这里的指令而不仅仅是位移等?我觉得这很烦人,因为我正在紧密循环中进行这样的指针算术,而且我怀疑imul
正在扼杀其性能。无论如何,这应该是没有必要的。
有没有一种好的方法可以总体上防止这种情况发生,并用更便宜的操作来代替它?
Update:
在我原来的程序中,我尝试添加一个虚拟变量,使每个元素的大小成为 4 的倍数而不是 3,这样编译器就可以使用位移而不是除法。
结果?尽管数据结构更大,程序的运行时间从9.2秒减少到7.4秒。
所以是的,这确实非常慢。