當(dāng)前位置:
首頁 >
循环变量的优化
發(fā)布時間:2025/5/22
27
豆豆
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
現(xiàn)在來介紹編譯器如何識別循環(huán)變量的問題。比如前面各種關(guān)于循環(huán)的優(yōu)化中,我們?nèi)绻嬎阋蕾囅蛄?#xff0c;起碼編譯器要能夠識別循環(huán)變量,
而識別循環(huán)變量也是編譯器的一個優(yōu)化過程。
而通常編譯器所認(rèn)為的循環(huán)變量可能同我們所看到的有所不同。
通常的循環(huán)變量是狹義的,也就是說,如果這個變量在一個循環(huán)的任意兩次相鄰的迭代中變換值是常數(shù),
那么這個變量就是循環(huán)變量。最常見的循環(huán)變量是如下代碼中:
但是如果循環(huán)體中對i做了修改,那么雖然看上去i還像是一個循環(huán)變量,但是對于編譯器來說,i已經(jīng)不是循環(huán)變量了,如:
而還有一些情況,循環(huán)變量人工不容易看出來,但是編譯器確可以判斷出來,如:
其中每次迭代這三個變量都增加了3.
而對于編譯器來說,通常還可以識別一些更加復(fù)雜的循環(huán)變量,如:
所以編譯器可以識別出它們也是循環(huán)變量。(其中a,b可以是變量,只要在循環(huán)體內(nèi)部沒有被修改)
比如h每個循環(huán)改變的量為3*(a+1),u每個循環(huán)改變的量為3*a,編譯器可以通過將上面代碼改變?yōu)?
同樣,如果在編譯器優(yōu)化比較后面的部分,通常,對于數(shù)組的訪問都已經(jīng)被展開,
如代碼
我看到郭給出鏈接中一篇英文文章中介紹到對于數(shù)組,最好讓每個元素數(shù)據(jù)的大小是2的冪,這樣,計算每個元素的地址時候,
乘法就可以被移位替換掉,從而提高了速度。但是,如果那樣的數(shù)組通常都是被通過循環(huán)變量訪問的,我們可以看出來,完全沒有
必要做那樣的優(yōu)化(實際上那樣可能會消耗更多的內(nèi)存空間,從而性能更加差).
此外,有一些比較優(yōu)秀的程序員,他們知道計算機計算移位比乘法運算快,所以對于下面的代碼
做一些前面提到過的如么模變換,仿射變換之類的優(yōu)化。反而對于后面的代碼,由于通常編譯器是不會將移位運算轉(zhuǎn)化為乘法運算的,所以
通常的編譯器反而無法知道后面的i<<1也是一個循環(huán)變量,從而阻止了進一步優(yōu)化的可能。
此外,部分編譯器還會對一些循環(huán)變量之間的相乘做優(yōu)化(比如Open64),比如代碼:
我們知道 h=h0+i*step1,u=u0+i*step2;
所以h*u=h0*u0+(h0*step2+u0*step1)*i+i*i*step1*step2
分別對于i和i+1計算上面的表達式并相減,我們可以得到對于第i次迭代,h*u的變換值是
? ?h0*step2+u0*step1+step1*step2+i*2*step1*step2;
所以我們知道,上面代碼于是可以優(yōu)化成:
同樣道理,對于三個循環(huán)變量的相乘,從理論上,我們同樣可以轉(zhuǎn)化為若干次加法運算。
不過據(jù)我所知,并沒有編譯器真正這樣去做,畢竟實際中,這樣代碼的例子會非常少見。
當(dāng)然,如果換成用郭的HugeCalc代碼中大整數(shù)做循環(huán)變量的代碼,那么遇到上面的代碼編譯器
的優(yōu)化同樣無能為力了,那么就需要手工做類似的優(yōu)化了。
轉(zhuǎn)載于:https://my.oschina.net/u/218425/blog/51947
總結(jié)
- 上一篇: win7 64位IE无法运行Active
- 下一篇: magento本地安装成功后无法进入后台