雙重for迴圈語句塊的優化
雙重迴圈語句的書寫,是有講究的。不同的書寫方式,效率會大不一樣。有如下程式碼模組:
typename tArray[20][600];
uint32 uIdxI = 0; //uint32 is short for unsigned int
uint32 uIdxJ = 0;
for (uIdxI = 0; uIdxI < 20; uIdxI++)
{
for (uIdxJ = 0; uIdxJ < 600; uIdxJ++)
{
tArray[uIdxI][uIdxJ] = ...; //assign value
}//for, uIdxJ
}//for, uIdxI
對於以行優先儲存方式的計算機來說,上述雙重迴圈的執行效率最高。首先,現代的CPU的體系架構大多都用了預測分支技術,如果雙重迴圈中外迴圈次數為nNumA,內迴圈次數為nNumB,則總體上預測失敗次數為2 * nNumA + 2,在保證執行結果無誤的前提下要保證外迴圈次數比內迴圈次數小。
其次,現代的計算機體系的儲存技術至少都用了局部儲存思想,即CPU提取記憶體的一個位置的資料放到cache中的同時,也會把其附近的資料也提取到cache中,如果記憶體以行優先儲存方式,則提取tArray[0][0]位置的資料的同時,則也會順便把"tArray[0][1], tArray[0][2], tArray[0][3], tArray[0][4]..."等資料提取出來。
上面提到了兩個原理,其中第二個原理要比第一個原理重要,因為“CPU訪問cache的速度要遠高於訪問記憶體的速度,一般CPU訪問SRAM的速度比訪問DRAM快1000倍”,分支預測失敗頂多是對指令進行調整,而指令本身就是CPU所有,無需訪問速度,但是資料則是在記憶體中,速度就很慢了。
所以,如果作業系統對陣列的儲存方式是以列優先儲存方式安排的,則上述程式碼中內迴圈應該放到外面去。