我目前正在尝试为我的库创建高度优化的、可重用的函数。例如,我用以下方式编写函数“是 2 的幂”:
template<class IntType>
inline bool is_power_of_two( const IntType x )
{
return (x != 0) && ((x & (x - 1)) == 0);
}
这是一个可移植的、低维护的实现,作为内联 C++ 模板。此代码由 VC++ 2008 编译为以下带有分支的代码:
is_power_of_two PROC
test rcx, rcx
je SHORT $LN3@is_power_o
lea rax, QWORD PTR [rcx-1]
test rax, rcx
jne SHORT $LN3@is_power_o
mov al, 1
ret 0
$LN3@is_power_o:
xor al, al
ret 0
is_power_of_two ENDP
我还从这里找到了实现:"The bit twiddler",它将在 x64 的汇编中编码如下:
is_power_of_two_fast PROC
test rcx, rcx
je SHORT NotAPowerOfTwo
lea rax, [rcx-1]
and rax, rcx
neg rax
sbb rax, rax
inc rax
ret
NotAPowerOfTwo:
xor rax, rax
ret
is_power_of_two_fast ENDP
我在一个汇编模块(.asm 文件)中测试了与 C++ 分开编写的两个子例程,第二个的工作速度提高了 20%!
然而函数调用的开销是相当大的:如果我将第二个汇编实现“is_power_of_two_fast”与模板函数的内联版本进行比较,尽管有分支,后者更快!
不幸的是,x64 的新约定规定不允许内联汇编。应该改为使用“内在函数”。
现在的问题是:我可以将更快的版本“is_power_of_two_fast”实现为自定义内在函数或类似的东西,以便可以内联使用?或者,是否有可能以某种方式强制编译器生成函数的低分支版本?