如何避免指针算术中的乘法? [英] How to avoid multiplication in pointer arithmetic?
问题描述
如果我写
int main(int argc, char *argv[])
{
int temp[50][3];
return &temp[argc] - &temp[0];
}
并使用Visual C ++编译,我回到:
and compile it with Visual C++, I get back:
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
正在杀死它的性能。在任何情况下,它不应该是必要的。
Why am I getting an imul
instruction here instead of just bit shifts, etc.? I find this pretty annoying, because I'm doing pointer arithmetic like this in a tight loop, and I'm suspecting imul
is killing its performance. In any case, it shouldn't be necessary.
是否有一个很好的方法来防止它,而是用更便宜的操作来替代它?
Is there a good way to prevent it in general and instead replace it with cheaper operations?
在我的原始程序中,我尝试添加一个虚拟变量,使每个元素的大小是4的倍数而不是3,所以编译器可以使用位移位
In my original program, I tried adding a dummy variable to make the size of each element a multiple of 4 instead of 3 so the compiler can use bit-shifting instead of division.
结果?即使数据结构较大,程序的运行时间也从9.2秒减少到7.4秒。
The result? Even though the data structure was bigger, the running time of the program decreased from 9.2 seconds to 7.4 seconds.
是的,这的确很慢。
推荐答案
为什么我在这里收到
imul
乘法是除以3(每个内部数组的大小),使用事实 0x2AAAAAAB
是2 31 / 3。你不能用少量的班次和添加来做到这一点;乘法真的是最快的选项。
The multiplication is to divide by 3 (the size of each inner array), using the fact that 0x2AAAAAAB
is 231/3. You can't do that with a small number of shifts and adds; multiplication really is the fastest option.
我怀疑
imul
性能。
在大多数现代平台上,整数乘法通常与简单操作一样快,因此它可能是最快的选项,可以由几个班次和添加来替换。当你有性能问题,总是测量找到真正的瓶颈;它们通常在您最不怀疑的地方。
On most modern platforms, integer multiplication is usually as fast as simpler operations, so it may be the fastest option even when it could be replaced by a couple of shifts and adds. When you have performance issues, always measure to find the real bottlenecks; they're often in the places you least suspect.
有一个很好的方法来防止它,而是用更便宜的操作
Is there a good way to prevent it in general and instead replace it with cheaper operations?
在乘法真的很昂贵的平台上:避免数组笨拙的数据结构;并避免减去指针,因为这需要按对象大小划分。
On platforms where multiplication really is expensive: avoid arrays of awkwardly sized data structures; and avoid subtracting pointers, since that requires division by the object size.
这篇关于如何避免指针算术中的乘法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!