2011-12-12 54 views
5

有什麼辦法可以告訴編譯器,你知道某個特定變量的值必須在代碼中某個特定位置的特定範圍內,才能幫助編譯器進行優化?我正在編寫一個庫,它可以在編譯時知道一些變量的範圍,如果能夠以某種方式將此信息傳遞給編譯器以便編譯器可以使用它來進行優化,那麼它會很好用。我想增加對任何編譯器的支持,即使這些編譯器無法爲所有編譯器工作(這聽起來像某些編譯器可以作爲擴展的東西,但我沒有發現任何)。我知道我可以寫這樣的東西:如何將範圍信息傳遞給C++編譯器?

if(x < COMPILE_TIME_MIN or x > COMPILE_TIME_MAX) 
    return; 
// compiler will assume for code below that x is in range COMPILE_TIME_MIN..COMPILE_TIME_MAX 

但這是一個運行時檢查。也許有一些技巧讓編譯器做出範圍的假設,而沒有這樣的檢查?

+2

你有什麼想法可以幫助哪種類型的優化? –

+0

如果使用模板,實際上可以編譯時檢查編譯時是否知道所有的信息。 –

+0

您正在使用「編譯器」這個短語,但您永遠不會告訴我們哪一個。推測你的意思是某種版本的g ++或Visual C++,但這並不清楚。標準並沒有解決一般的優化問題,所以你可能在這裏做的任何事情都是特定於實現的。 –

回答

6

任何這樣的「提示」都是編譯器專用的。

作爲示例,Visual C++允許您使用the __assume intrinsic提供此類提示。

(其他編譯器也可以提供這樣的內部函數,但我不與其他編譯器不夠熟悉而提供任何進一步的信息。如果你有興趣,請諮詢你的編譯器的文檔)。

+3

從我自己的谷歌搜索,海灣合作委員會4.5及以上可以傳遞這個信息,同樣的語法也使用'#define __assume(cond)do {if(!(cond))__builtin_unreachable(); } while(0)' –

+0

@DrewDormann有趣。我認爲最好是在Visual C++和gcc上定義一個宏#define ASSUME_THIS_THING(x)...,將其擴展爲'__assume(x)'。最好不要用編譯器保留的名稱來定義你自己的宏(比如'__assume')。 –

+0

哇,太棒了。詹姆斯,小心把德魯的信息合併到你的答案中?然後我會標記爲已接受。 –

3

這不是標準,而是用gcc,有一個名爲__builtin_expect的命令,其宏定義爲likelyunlikely,這些命令可用於您的目的。例如,here舉例說明在內核空間中使用它們,但是__builtin_expect是gcc擴展名,並且也可以在用戶空間中使用(參見this question),即使沒有定義likelyunlikely也沒有定義。

+0

上面的評論中有一個錯誤:它應該是'__builtin_expect'。海灣合作委員會只是將期望作爲一個提示:它不會避免不符合預期的情況。 –

+0

@MattG,是的,我不知道我是怎麼寫'buildtin'的! – Shahbaz

0

我不知道任何利用這些信息的C++編譯技術,但我知道有各種各樣的靜態分析技術;常見的方式「告訴」的東西這些工具將通過assert S,例如:

assert(x > COMPILE_TIME_MIN); 
assert(x < COMPILE_TIME_MAX); 

通常這些工具還能夠分析的東西,如「如果條件」本身,所以沒有特別需要這樣做。另外,如果範圍非常小,也可以用較小尺寸的變量表示 - 例如,使用短或字符 - 並加入COMPILE_TIME_MIN。這可以幫助這些工具,但我不知道編譯本身。

最後,和所有的優化方法一樣,我建議首先分析一下你的代碼,看看它是否真的成爲瓶頸。另外,請記住,編譯器專爲優化「正常」代碼而設計。 - 手工優化當然可以提供幫助,請謹慎操作。