我正在爲ARM9處理器編寫一些日誌記錄C代碼。如果存在動態模塊,該代碼將記錄一些數據。該模塊通常不會出現在生產版本中,但日誌代碼將始終編譯進來。想法是,如果客戶遇到錯誤,我們可以加載此模塊,並且日誌記錄代碼將轉儲調試信息。使用RVCT4.0對Arm9進行靜態分支預測
當模塊不存在時,日誌代碼必須產生最小的影響,因此每個週期都會計數。在一般情況下,日誌代碼看起來是這樣的:
__inline void log_some_stuff(Provider *pProvider, other args go here...)
{
if (NULL == pProvider)
return;
... logging code goes here ...
}
隨着優化,RVCT 4.0生成的代碼如下所示:
ldr r4,[r0,#0x2C] ; pProvider,[r0,#44]
cmp r4,#0x0 ; pProvider,#0
beq 0x23BB4BE (usually taken)
... logging code goes here...
... regular code starts at 0x23BB4BE
該處理器沒有分支預測,我的理解是,每次採取分支時都會有2個週期的懲罰(如果不採取分支則不會受到懲罰)。
我想普通的情況下,其中NULL == pProvider
,快速的情況下,分支不採取。我如何使RVCT 4.0生成這樣的代碼?
我使用__builtin_expect
如下嘗試:
if (__builtin_expect(NULL == pProvider, 1))
return;
不幸的是,這對生成的代碼沒有任何影響。我錯誤地使用了__builtin_expect
嗎?有沒有另一種方法(希望沒有內聯彙編)?
此代碼沒有意義。如果pProvider是第一個arg,並且在不被解引用的情況下針對NULL進行檢查,則編譯器不需要ldr,因爲pProvider已經在r0中。看起來您正在查看Provider類型的偏移量。 – 2011-03-23 06:21:16
@變長編碼器,日誌功能是內聯的,所以不用擔心參數。 ldr指令從某些數據結構中提取pProvider。如果函數未被內聯,則會在調用之前發生。 – 2011-03-23 16:31:20
作爲參考,RVCT 3.0文檔表明支持[__builtin_expect](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0202h/Cjabddedbde.html) – 2011-03-23 16:34:56