|
1
25
286 added an
当将两个32位值相乘时,结果的最低有效32位是相同的,无论您认为这些值是有符号的还是无符号的。换句话说,只有当你看到结果的上半部分时,有符号乘法和无符号乘法的区别才变得明显,其中一个操作数
在C语言中,算术运算的结果与操作数具有相同的类型(在对窄整数类型进行整数提升之后)。如果你乘以二
作为第二步,因为C编译器使用多操作数形式
单操作数形式
|
|
|
2
9
x86上有三种不同类型的乘法指令。第一个是
由于在C语言中,两个32位值的乘法产生32位结果,编译器通常使用第三种类型(签名不重要,低32位在有符号和无符号32x32乘法之间一致)。VC++将生成
的2个操作数(和3个操作数)版本
|
|
|
3
4
根据
http://gmplib.org/~tege/x86-timing.pdf
, the
我手边没有Visual Studio,所以我尝试用GCC来获取其他东西。我也经常得到一些变化
这是:
组装到此(使用-o2):
|
|
|
4
2
我的直觉告诉我编译器选择了
|
|
|
5
2
在我研究了这个问题之后,我发现在划分时生成的代码中存在mulq。 完整的代码将一个大的二进制数转换成十亿个块,这样它就可以很容易地转换成字符串。 C++代码:
优化生成的程序集
注意下面的MUL指令5行。 我知道,这个生成的代码是非常无意义的,实际上它看起来和编译后的代码没什么两样,但是对于32位的DIV,DIV非常慢,大约25个周期,根据这个,大约75个周期。 chart 与mul或imul(大约3或4个周期)相比,在现代个人电脑上,即使必须添加各种额外的指令,也要设法去掉div。 我不完全理解这里的优化,但是如果您想看到一个关于使用编译时和乘法除常数的理性和数学解释,请看这个 paper . 这是一个例子,是编译器利用完整的64和64位的未截断乘法的性能和能力,而不显示C++编码器的任何符号。 |
|
6
1
正如已经解释过的,C/C++不做
GCC、CLANG和ICC提供内置类型
通过MSVC,它提供了
_umul128
内在的(至少从2010年开始),它产生了
|