【发布时间】:2014-03-12 06:27:36
【问题描述】:
如果我写
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 正在扼杀它的性能。无论如何,这应该是没有必要的。
有什么好的方法可以防止它,而是用更便宜的操作来代替它?
更新:
在我的原始程序中,我尝试添加一个虚拟变量以使每个元素的大小为 4 而不是 3 的倍数,以便编译器可以使用位移而不是除法。
结果?即使数据结构更大,程序的运行时间也从 9.2 秒减少到 7.4 秒。
所以是的,这确实很慢。
【问题讨论】:
-
您是否尝试过用位移位替换 mul 指令并对结果进行基准测试?
-
@larsmans:不,因为我使用的是向量迭代器(它们是下面的指针),因此我不一定可以取消引用它们来取回原始指针。如果我这样做了,我可能会不小心取消引用过去的迭代器,从而导致未定义的行为。 (检查过去的迭代器本身会增加额外的指令。)
-
嗯,优化级别是多少? gcc at -O2
-
但是,如果输入不能保证是向量迭代器,那么“将是指针”的假设是相当大胆的。
-
“我怀疑 imul 正在扼杀它的性能”......你最好检查一下。你的编译器对这些东西几乎总是正确的。
标签: c++ visual-c++ code-generation multiplication pointer-arithmetic