我使用GCC編譯器在C/C++中測試各種優化。我目前有一個循環與多個嵌套if語句。條件是在程序執行開始時計算的。它看起來有點像這樣:使用GCC優化C/C++循環中的嵌套if語句
bool conditionA = getA();
bool conditionB = getB();
bool conditionC = getC();
//Etc.
startTiming();
do {
if(conditionA) {
doATrueStuff();
if(conditionB) {
//Etc.
} else {
//Etc.
}
} else {
doAFalseStuff();
if(conditionB) {
//Etc.
} else {
//Etc.
}
}
} while (testCondition());
endTiming();
哪裏doATrueStuff()
是做一些簡單的數值計算所以在調用它沒有開銷的內聯函數。
不幸的是,這些條件不能事先定義,它們必須在運行時計算。我們甚至無法可靠地預測它們是真的還是錯的機會。 getA()
不妨是rand()%2
。但一旦計算出來,它們的價值從不改變。
有兩個解決方案,我認爲,其中之一是用於調用循環內的相應功能全局函數指針,就像這樣:
void (*ptrA)(void);
//Etc.
int main(int argc, char **argv) {
//...
if (conditionA) {
ptrA=&aTrueFunc;
} else {
ptrA=&aFalseFunc;
}
//...
do {
(*ptrA)();
} while (testCondition());
//...
}
這樣我可以消除從所有分支循環,然後我會有多個函數調用的開銷放緩我。
或者我可以簡單地對條件的每個組合不同的循環,這樣的事情:
if(conditionA) {
if(conditionB) {
do {
//Do A == true B == true stuff
} while (testCondition());
} else {
do {
//Do A == true B == false stuff
} while (testCondition());
}
} else {
//Etc.
}
不過是少了很多優雅,並得到不可能一個如此高效地完成,一旦一個人開始有太多許多條件,因爲在X條件下需要編寫2^X個循環。
有沒有更優雅/更快的方式來優化?
這裏甚至還有什麼意思嗎?或者編譯器是否會明白,在循環過程中條件不會改變並優化它本身?
出於好奇,是否還有另一種編程語言可以使編寫這樣的代碼更容易/可能?或者只有在程序加載到內存後才能使用程序集來更改程序的指令?
第一個想法似乎沒有比原來的更多的函數調用。 –
如果條件在循環內部沒有改變,那麼CPU可能會很好地進行分支預測。 – Carlton
看來你已經有了2^X個不同的塊。 – Jarod42