我們拿一個(gè)算法的代碼實(shí)現(xiàn)來(lái)舉例子,首先我們寫(xiě)一個(gè)求階乘的子函數(shù),這里我偷懶讓 ChatGPT 幫忙生成了一個(gè):
// 階乘函數(shù)
intfactorial_iterative(int n) {
int result = 1;
// 從1乘到n
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
// 示例
int main() {
int result_iterative = factorial_iterative(5);
printf("5的階乘是: %dn", result_iterative);
return 0;
}
這種簡(jiǎn)單的迭代算法的優(yōu)點(diǎn)是比較容易理解,一眼就可以看出程序員想干什么。
但這樣寫(xiě)出來(lái)的程序缺點(diǎn)也很大,就是運(yùn)行效率非常低,我們?cè)谒惴ň帉?xiě)中最怕的就是for 循環(huán),因?yàn)檫@里面會(huì)存在大量的比較和跳轉(zhuǎn),同時(shí)最容易產(chǎn)生一些代碼被無(wú)效的循環(huán)執(zhí)行。
這些缺點(diǎn)有的會(huì)被編譯器的優(yōu)化措施給規(guī)避掉,比如編譯器可以把一些需要內(nèi)存訪問(wèn)的變量先放到寄存器中,等計(jì)算完結(jié)果后,再把結(jié)果從寄存器中轉(zhuǎn)移到內(nèi)存中,因?yàn)?CPU 讀取寄存器比讀取內(nèi)存可快多了。
但是編譯器也不是萬(wàn)能的,有些優(yōu)化他就做不到。比如,我們改成下面展開(kāi)的樣子,超標(biāo)量的流水線就開(kāi)始起作用了。
// 階乘函數(shù)
intfactorial_iterative(int n) {
int result0 = 1, result1 = 1, result2 = 1,result3 = 1;
// 從1乘到n
for (int i = 1; i < n; i += 4) {
result0 *= i;
result1 *= i + 1;
result2 *= i + 2;
result3 *= i + 3;
}
return (result0 * result1 * result2 * result3);
}
首先,我們假設(shè)開(kāi)啟了編譯器優(yōu)化,編譯器已經(jīng)把所有內(nèi)存訪問(wèn)的變量在函數(shù)開(kāi)始都?xì)w置到了寄存器中,那么這時(shí)候我們可以看到,4 個(gè) result 的乘法語(yǔ)句是相互獨(dú)立的,他們的計(jì)算過(guò)程不依賴(lài)于其他 3 個(gè)語(yǔ)句的計(jì)算結(jié)果。
這就好比安排了四個(gè)人,給他們算 4 個(gè)單獨(dú)的式子,假設(shè)他們計(jì)算能力相同,于是他們會(huì)在同一段時(shí)間后跑到黑板上來(lái)互相乘一下算個(gè)總的結(jié)果。
而如果我們只是簡(jiǎn)單的做循環(huán)展開(kāi),不增加新的寄存器變量,也就是不加人的情況下是怎么樣的呢?
// 階乘函數(shù)
intfactorial_iterative(int n) {
int result = 1;
// 從1乘到n
for (int i = 1; i < n; i += 4) {
result *= i;
result *= i + 1;
result *= i + 2;
result *= i + 3;
}
return (result * result * result * result);
}
這里只放了一個(gè)聰明的孩子做算式,不過(guò)你看他要做的 4 個(gè)算式,其中后一個(gè)算式總要用到前一個(gè)算式的結(jié)果,他即便再聰明也得一個(gè)一個(gè)的算。
這就是超標(biāo)量流水線的用處,當(dāng)然展開(kāi)多少還需要我們自己衡量,本質(zhì)上也是用空間換時(shí)間,另外寄存器可是稀缺資源。
-
處理器
+關(guān)注
關(guān)注
68文章
19048瀏覽量
228525 -
mcu
+關(guān)注
關(guān)注
146文章
16812瀏覽量
349444 -
代碼
+關(guān)注
關(guān)注
30文章
4700瀏覽量
68108 -
編譯器
+關(guān)注
關(guān)注
1文章
1608瀏覽量
48979
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論