【发布时间】:2013-06-01 11:27:13
【问题描述】:
我有一个程序,它依赖于左旋转指令的性能。
在 MSVC 下,它工作得相当好,只需将 _rotl() 内部函数定义为向左旋转的目标。
在 GCC for Linux 下,它也运行良好。在这里定义等效的软件构造 rotl32(x,r) = ((x << r) | (x >> (32 - r))) 就足够了,编译器足够聪明地识别出这是一个 32 位左移,并自动将其替换为其内在等效项(公平地说,MSVC 也能够使检测)。
在 MinGW 下,没有那么多。当 MinGW 使用 GCC 作为其核心时,这一点就更加有趣了。 MinGW 可以编译 windows 内在函数_rotl,但不会明显触发相应的内在函数。软件版本似乎也未被检测到,但公平地说,它仍然比_rotl 快。最终结果是性能降低了 10 倍,所以这绝对是显着的。
注意:测试 MinGW 的 GCC 版本是 4.6.2
【问题讨论】:
-
您能否发布一个示例以及生成的程序集(使用
-S和-O2选项)?我对 MinGW 4.6.1 和 4.7.2 的测试表明它将使用rol(或有时是ror)指令来实现对内联rotl32()函数的调用,该函数仅返回您给出的表达式 - 只要因为所涉及的论点是unsigned。这似乎是一个明智的要求,因为您的表达式对于负值(以及使用有符号类型时的一些非负值)具有未定义的行为。 -
然而,
_rotl()'intrinsic' 显然是作为对 MinGW 中库函数的非内联函数调用实现的。 -
所有输入都是uint32_t
-
请注意,虽然微型计算机的编译器过去的设计方式总是将
rotl32的给定定义视为评估x|0或x|x(可能是任意选择)以防万一r为 0,无论选择哪个值都无关紧要,因为两者都会评估为x,这样的处理方式不再流行。相反,有必要将|右侧的部分替换为(x >> (31-r) >> 1)或(x >> ((-r) & 31))等替代结构,以使程序可以安全地用于优化编译器,即使后一种形式可能... -
...在许多编译器上速度较慢且难以阅读。