亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

C語言中對于循環結構優化的一些入門級方法簡介

2020-01-26 14:48:40
字體:
來源:轉載
供稿:網友

一.代碼移動

將在循環里面多次計算,但是結果不會改變的計算,移到循環外面去。

例子:

優化前:

void lower1(char *s){int i;for(i=0;i<strlen(s);++i)   if(s[i]>='A'&&s[i]<='Z')    s[i]-=('A'-'a');}優化后:void lower2(char *s){int i;int len=strlen(s);for(int i=0;i<len;++i)  if(s[i]>='A'&&s[i]<='Z')    s[i]-=('A'-'a');}

優化前的版本,由于每次循環都要調用strlen計算s的長度,實際上的復雜度成了O(n2)了,而優化后的版本只需計算一次s的長度,因此性能上比優化前版本要好。

二.減少函數調用

例子:

優化前:

void sum1(vec_ptr v,data_t *dest){int i;int len=vec_length(v);*dest=0;for(i=0;i<len;++i){  data_t val;  get_vec_element(v,i,&val);  *dest+=val;}}

優化后:

data_t get_vec_start(vec_ptr v){return v->data;}void sum2(vec_ptr v,data_t *dest){int i;int len=vec_length(v);data_t *data=get_vec_start(v);*dest=0;for(i=0;i<len;++i)  *dest+=data[i];}

優化前的版本在每次循環中都要調用一次get_vec_element獲得相應的項,而優化后的版本只需在循環外調用一次get_vec_start獲得開始的內存地址,循環內直接訪問內存,無需調用函數。

三.減少內存訪問

例子:

優化前:

void sum2(vec_ptr v,data_t *dest){int i;int len=vec_length(v);data_t *data=get_vec_start(v);*dest=0;for(i=0;i<len;++i)  *dest+=data[i];}

優化后:

void sum3(vec_ptr v,data_t *dest){int i;int len=vec_length(v);data_t *data=get_vec_start(v);data_t acc=0;for(i=0;i<len;++i)  acc+=data[i];*dest=acc;}

優化前的版本每次迭代都要從dest讀出值再加上data[i],再將結果寫回dest。這樣的讀寫很浪費,因此每次迭代開始從dest讀出的值就是上次迭代寫回dest的指。優化后的版本通過加入acc臨時變量,它循環中累積計算出的結果,循環結束后再寫回。

這里給出兩個版本相應的匯編結果就可以很清楚看出區別:

優化前:

2015122102845375.png (704×221)

優化前的版本每次迭代都要從dest讀出值再加上data[i],再將結果寫回dest。這樣的讀寫很浪費,因此每次迭代開始從dest讀出的值就是上次迭代寫回dest的指。優化后的版本通過加入acc臨時變量,它循環中累積計算出的結果,循環結束后再寫回。

第二行和第四行分別對dest進行了讀寫。

優化后:

2015122102904746.png (677×180)

從匯編結果可以看出編譯器將acc直接放在了寄存器里,循環中無需對內存進行讀寫。

四.循環展開

循環展開可以減少循環的次數,對程序的性能帶了兩方面的提高。一是減少了對循環沒有直接貢獻的計算,比如循環計數變量的計算,分支跳轉指令的執行等。二是提供了進一步利用機器特性進行的優化的機會。

例子:

優化前的代碼見前一篇博客里的sum3.

優化后:

void sum4(vec_ptr v,data_t *dest){int i;int len=vec_length(v);int limit=len-3;data_t *data=get_vec_start(v);data_t acc=0;for(i=0;i<limit;i+=4){  acc=acc+data[i]+data[i+1];  acc=acc+data[i+2]+data[i+3];}for(;i<len;++i)  acc+=data[i];*dest=acc;}

通過循環展開,每次迭代將累加4個元素,減少了循環次數,從而減少了總的執行時間(單獨使用這種優化方法,對浮點數累乘幾乎沒有提高,但是整數累乘得益于編譯器的重關聯代碼變化會有大幅度提高)。

這種優化可以直接利用編譯器完成,將優化level設定到較高,編譯器會自動進行循環展開。使用gcc,可以顯式使用-funroll-loops選項。

五.提高并行性

現代處理器大多采用了流水線、超標量等技術,可以實現指令級并行。我們可以利用這個特性對代碼做進一步的優化。

2.1使用多個累積變量

優化代碼示例

void sum5(vec_ptr v,data_t *dest){int i;int len=vec_length(v);int limit=len-1;data_t *data=get_vec_start(v);data_t acc0=0;data_t acc1=0;for(i=0;i<limit;i+=2){  acc0+=data[i];  acc1+=data[i+1];}for(;i<len;++i)  acc0+=data[i];*dest=acc0+acc1;}

這里同時使用了循環展開和使用多個累加變量,一方面減少了循環次數,另一方面指令級并行的特性使得每次迭代的兩次加法可以并行執行?;谶@兩點可以顯著減少程序執行的時間。通過增加展開的次數和累加變量的個數,可以進一步提高程序的性能,直到機器指令執行的吞吐量的極限。

2.2重結合變換

除了使用多個累積變量顯式利用機器的指令級并行特性外,還可以對運算重新結合變換,打破順序相關性來享受指令級并行帶來的好處。

在sum4中,acc=acc+data[i]+data[i+1]的結合順序是acc=(acc+data[i])+data[i+1];

我們將之變成acc=acc+(data[i]+data[i+1]);

代碼如下:

void sum6(vec_ptr v,data_t *dest){int i;int len=vec_length(v);int limit=len-3;data_t *data=get_vec_start(v);data_t acc=0;for(i=0;i<limit;i+=4){  acc=acc+(data[i]+data[i+1]);  acc=acc+(data[i+2]+data[i+3]);}for(;i<len;++i)  acc+=data[i];*dest=acc;}

進一步增加循環展開的次數,可以進一步提高程序性能,最終也可以達到機器指令執行的吞吐量的極限。(在循環展示提到的整數乘法的性能提高就在于編譯器隱式采取了這種變換,但是由于浮點數不具備結合性,所以編譯器沒有采用,但是程序員在保證程序結果正確性的情況下,可以顯式使用這一點)。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久偷看各类女兵18女厕嘘嘘| 国产精品一区二区性色av| 日韩成人av一区| 91九色视频在线| 亚洲国产另类 国产精品国产免费| 久久国产加勒比精品无码| 亚洲字幕一区二区| 国产成人一区二区三区| 亚洲电影成人av99爱色| 亚洲成年网站在线观看| 色爱av美腿丝袜综合粉嫩av| 成人h猎奇视频网站| 亚洲xxxx18| 国产一区二区三区在线观看网站| 色婷婷av一区二区三区在线观看| 国产日韩欧美在线视频观看| 欧美激情视频网站| 亚洲国产私拍精品国模在线观看| 国语自产精品视频在线看一大j8| 日本成人黄色片| 国产美女精彩久久| 亚洲欧美国产日韩中文字幕| 中文字幕亚洲国产| 国产精品96久久久久久| 欧美裸体xxxxx| 欧美肥臀大乳一区二区免费视频| 精品自拍视频在线观看| 亚洲一区二区三区视频播放| 国产ts一区二区| 日本高清不卡的在线| 日韩av最新在线| 欧美成人激情视频| 亚洲欧美日韩精品久久亚洲区| 欧美日韩国产丝袜美女| 国产一区二区三区日韩欧美| 国产成人精品视| 久久精品电影一区二区| 色偷偷91综合久久噜噜| 久久99久久99精品免观看粉嫩| 国内精品一区二区三区| 亚洲另类欧美自拍| 欧美性猛交xxxx乱大交3| 亚洲第一免费播放区| 91精品91久久久久久| 国产日韩在线视频| 国产精品久久久久久久久久久久久久| 2019国产精品自在线拍国产不卡| 国产精品美女无圣光视频| 日韩成人av在线播放| 成人黄色激情网| 欧美日韩在线一区| 日韩av在线最新| 影音先锋欧美在线资源| 久久九九有精品国产23| 最近2019中文字幕mv免费看| 精品成人国产在线观看男人呻吟| 国产欧美精品久久久| 久久国产天堂福利天堂| 中文字幕精品一区久久久久| 日韩精品免费综合视频在线播放| 国产精品香蕉国产| 色一情一乱一区二区| 中文字幕亚洲综合久久筱田步美| 亚洲人精品午夜在线观看| 久久精品国产91精品亚洲| 国产福利精品在线| 国产精品美女www| 日韩精品在线看| 俺也去精品视频在线观看| 欧美日韩福利在线观看| 亚洲aaaaaa| 91黑丝在线观看| 欧美亚洲激情在线| 欧美日韩在线免费观看| 久久偷看各类女兵18女厕嘘嘘| 欧美一级高清免费| 欧美日韩成人网| 亚洲成**性毛茸茸| 美女福利视频一区| 欧美www视频在线观看| 日韩暖暖在线视频| 国产一区二区三区在线视频| 欧美电影免费播放| 国产精品十八以下禁看| 国产区亚洲区欧美区| 亚洲国产高清福利视频| 亚洲网站在线看| 欧美伦理91i| www国产精品视频| 亚洲午夜av电影| 国产91在线高潮白浆在线观看| 精品久久久久久中文字幕大豆网| 亚洲欧美另类国产| 中文字幕日韩欧美在线视频| 日韩黄色av网站| 亚洲精品一区av在线播放| 亚洲一级一级97网| 久久精品亚洲94久久精品| 自拍视频国产精品| 亚洲人成电影网| 亚洲一区二区三区乱码aⅴ蜜桃女| 日韩免费av片在线观看| 亚洲欧美日韩在线一区| 2019中文字幕在线免费观看| **欧美日韩vr在线| 亚洲午夜国产成人av电影男同| 欧美日韩国产限制| 精品国产美女在线| 欧美激情精品久久久| 欧美日韩国产va另类| 久99久在线视频| 亚洲欧美另类人妖| 日韩暖暖在线视频| 国产一区二区三区三区在线观看| 伊人精品在线观看| 麻豆成人在线看| 亚洲美女www午夜| 亚洲国产成人爱av在线播放| 日韩高清电影免费观看完整| 中国人与牲禽动交精品| 国内精品视频久久| 久久久免费高清电视剧观看| 777午夜精品福利在线观看| 日韩成人久久久| 8x海外华人永久免费日韩内陆视频| 91美女片黄在线观看游戏| 欧美激情在线有限公司| 亚洲小视频在线| 日韩欧美极品在线观看| 欧美色道久久88综合亚洲精品| 亚洲福利在线视频| 国产日韩精品电影| 青青青国产精品一区二区| 97在线视频国产| 亚洲黄在线观看| 欧美自拍视频在线| 日韩中文字幕欧美| 亚洲日本中文字幕| 国产一区二区三区视频免费| 国产精品视频在线播放| 欧美日韩在线第一页| 国产91在线视频| 精品一区二区电影| 亚洲综合精品一区二区| 欧美中文字幕在线观看| 欧美精品videofree1080p| 91精品久久久久久综合乱菊| 久久精品影视伊人网| 欧美亚洲另类视频| 国产精品99久久久久久久久久久久| 久久人体大胆视频| 91网站免费观看| 亚洲老头同性xxxxx| 国产91精品久久久久久| 91亚洲精品在线| 深夜精品寂寞黄网站在线观看| 久久亚洲精品网站| 亚洲综合在线做性| 国模吧一区二区| 欧美久久精品午夜青青大伊人| 性欧美xxxx| 久久久久久综合网天天| 久热精品视频在线免费观看| 欧美电影电视剧在线观看|