如何避免指针算术中的乘法? [英] How to avoid multiplication in pointer arithmetic?

查看:190
本文介绍了如何避免指针算术中的乘法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我写

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆