gpt4 book ai didi

c++ - MSVC 为某些乘法和除法生成奇怪/缓慢的二进制文件

转载 作者:搜寻专家 更新时间:2023-10-31 01:57:29 27 4
gpt4 key购买 nike

我使用 MSVC 2010 SP1 并且有以下 C++ 代码行:

int32_t c = (int64_t(a)*int64_t(b))>>2;

ab 不是常量时,MSVC 会正确生成 32 位的 imulshr​​d 指令。但是当 ab 是常量时,它会生成对 _allmull 的调用,而不是 imul 指令。这有什么理由吗?我怎样才能强制/引导它始终生成好的代码?困扰我的是为什么当它有更多的编译时信息时它会生成更糟糕的代码。我发现 _allmull 函数执行 64 位乘法,但我认为在这种情况下不需要它。

我还注意到对于一行 int32_t c = (int64_t(a)*int64_t(b))/4; 它甚至生成 _alldiv 以除以 4。

编辑:这似乎是一个编译器错误。我填了一个bug report .

最佳答案

部分相关:如果您想确保利用 imul 执行 32x32=>64 位乘法的能力,您可以使用 Int32x32To64 “假 API”(实际上是一个宏):

Multiplies two signed 32-bit integers, returning a signed 64-bit integer result. The function performs optimally on 32-bit Windows.

This function is implemented on all platforms by optimal inline code: a single multiply instruction that returns a 64-bit result.

顺便问一下,您是否启用了优化?如果启用优化后编译器无法自行解决问题,我会感到非常困惑。


编辑:

有趣的是,在 winnt.h 中寻找 Int32x32To64,您会发现,对于 x86:

//
// The x86 C compiler understands inline assembler. Therefore, inline functions
// that employ inline assembler are used for shifts of 0..31. The multiplies
// rely on the compiler recognizing the cast of the multiplicand to int64 to
// generate the optimal code inline.
//

#define Int32x32To64( a, b ) (LONGLONG)((LONGLONG)(LONG)(a) * (LONG)(b))
#define UInt32x32To64( a, b ) (ULONGLONG)((ULONGLONG)(DWORD)(a) * (DWORD)(b))

因此,如果平台 SDK 相信编译器会做正确的事情,它肯定会生成 imul


再次编辑:

如果你需要确保得到一个imul,你可以使用__emul compiler intrinsic .

关于c++ - MSVC 为某些乘法和除法生成奇怪/缓慢的二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5569317/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com