我目前正在嘗試爲我的圖書館創建高度優化的可重用函數。舉例來說,我寫的函數「是2的冪」的方式如下:對於x64而不是內聯彙編可以使用「自定義內部函數」嗎?
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 [email protected]_power_o
lea rax, QWORD PTR [rcx-1]
test rax, rcx
jne SHORT [email protected]_power_o
mov al, 1
ret 0
[email protected]_power_o:
xor al, al
ret 0
is_power_of_two ENDP
我還發現,從這裏實施:"The bit twiddler",這將彙編編碼爲64位,如下所示:
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」作爲自定義內部函數或類似的東西,以便它可以內聯使用嗎?或者,是否有可能以某種方式強制編譯器生成函數的低分支版本?
GCC和ICC仍允許內聯組件 – hirschhornsalz 2011-04-04 11:50:32
通過使用&代替&&避免分支。 – 2011-04-04 18:29:46
@drhirsch:謝謝,我牢記在心。 @Hans Passant:我已經嘗試過了,但是會導致代碼變慢(太多指令)。 – 2011-04-05 07:10:25