[英]Is there a faster alternative to if-else in this case?
while(some_condition){
if(FIRST)
{
do_this;
}
else
{
do_that;
}
}
在我的程序中, if(FIRST)
成功的可能性大約是10000中的1。在C / C ++中可以有任何替代方法,這樣我們就可以避免在while循環內的每次迭代中檢查條件,希望看到更好的性能這個案例。
好! 讓我詳細介紹一下。 我正在為信號采集和跟蹤方案編寫代碼,其中我的系統狀態將更頻繁地保持在跟蹤模式,即ACQUISITION模式。
while(signal_present)
{
if(ACQUISITION_SUCCEEDED)
{
do_tracking(); // this functions can change the state from TRACKING to ACQUISITION
}
else
{
do_acquisition(); // this function can change the state from ACQUISITION to TRACKING
}
}
所以這里發生的是系統通常保持跟蹤模式,但是當跟蹤失敗時它可以進入采集模式但不常見。(假設輸入數據的數量是無限的。)
單個分支的性能成本不會是一個大問題。 你唯一能做的就是把最可能的代碼放在第一位,保存在一些指令緩存上。 也許。 這非常深入到微優化。
嘗試優化它沒有特別好的理由。 幾乎所有現代架構都包含分支預測器 。 這些推測分支(if或者其他)將基本上采用過去的方式。 在您的情況下,推測將始終成功,消除所有開銷。 有一些不可移植的方法暗示條件采取某種方式,但任何分支預測器都可以正常工作。
您可能想要做的一件事是改進指令緩存局部性是將do_that
移出while循環(除非它是一個函數調用)。
在最近的x86處理器系統上,最終執行速度幾乎不依賴於源代碼實現。
您可以查看此頁面http://igoro.com/archive/fast-and-slow-if-statements-branch-prediction-in-modern-processors/,以查看處理器內部發生的優化量。
GCC有一個__builtin_expect
“函數”,您可以使用它來向編譯器指示可能采用的分支。 你可以像這樣使用它:
if(__builtin_expect(FIRST, 1)) …
這有用嗎? 我不知道。 我從未使用它,從未見過它(據稱在Linux內核中除外)。 GCC文檔實際上不鼓勵使用它來支持使用分析信息來實現更可靠的度量。
如果你不知道什么時候“FIRST”是真的,那么沒有。
問題是FIRST是否耗時; 也許你可以在循環(或部分循環)之前評估FIRST,然后測試布爾值。
我會稍微改變一下moonshadow的代碼
while( some_condition )
{
do_that;
if( FIRST )
{
do_this; // overwrite what you did earlier.
}
}
根據您的新信息,我會說如下:
while(some_condition)
{
while(ACQUISITION_SUCCEEDED)
{
do_tracking();
}
if (some_condition)
while(!ACQUISITION_SUCCEEDED)
{
do_acquisition();
}
}
關鍵是ACQUISITION_SUCCEEDED
狀態必須在some_condition
包含some_condition
信息(即如果some_condition
為false,它將突破內部循環 - 因此有可能突破外部循環)
這是優化中的經典之作。 如果可以的話,你應該避免將條件放在循環中。 這段代碼:
while(...)
{
if( a )
{
foo();
}
else
{
bar();
}
}
通常更好地重寫為:
if( a )
{
while(...)
{
foo();
}
}
else
{
while(...)
{
bar();
}
}
雖然並不總是這樣,但是當你嘗試優化某些東西來測量前后的性能時,你應該總是這樣。
如果與do_aquisition
的實現相比,此測試確實消耗了大量時間,那么您可以通過使用函數表來獲得提升:
typedef void (*trackfunc)(void);
trackfunc tracking_action[] = {do_acquisition, do_tracking};
while (signal_present)
{
tracking_action[ACQUISITION_STATE]();
}
這些手動優化的效果非常依賴於平台,編譯器和優化設置。
通過花時間測量和調整do_aquisition和do_tracking算法,您很可能會獲得更大的性能提升。
您可以使用您的示例進行更多有用的優化。
對do_this
和do_that
的調用/分支可能會通過優化if-then-else
語句來抵消您獲得的任何節省。
性能優化的一個規則是減少分支。 大多數處理器更喜歡執行順序代碼。 他們可以獲取一大塊順序代碼並將其拖入緩存中。 分支中斷了這種愉悅,並可能導致指令緩存的完全重新加載(這會浪費寶貴的執行時間)。
在此級別進行微量優化之前,請檢查您的設計,看看是否可以:
我確信上述步驟將比優化發布的循環獲得更多性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.