亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語言中對(duì)于循環(huán)結(jié)構(gòu)優(yōu)化的一些入門級(jí)方法簡(jiǎn)介

 更新時(shí)間:2015年12月02日 10:39:18   作者:lisperl  
這篇文章主要介紹了C語言中對(duì)于循環(huán)結(jié)構(gòu)優(yōu)化的一些入門級(jí)方法,包括算法設(shè)計(jì)的改進(jìn)來提高一些并行性等方法,要的朋友可以參考下

一.代碼移動(dòng)

將在循環(huán)里面多次計(jì)算,但是結(jié)果不會(huì)改變的計(jì)算,移到循環(huán)外面去。

例子:

優(yōu)化前:

void lower1(char *s){
int i;
for(i=0;i<strlen(s);++i)
   if(s[i]>='A'&&s[i]<='Z')
    s[i]-=('A'-'a');
}
優(yōu)化后:
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');
}

優(yōu)化前的版本,由于每次循環(huán)都要調(diào)用strlen計(jì)算s的長度,實(shí)際上的復(fù)雜度成了O(n2)了,而優(yōu)化后的版本只需計(jì)算一次s的長度,因此性能上比優(yōu)化前版本要好。

二.減少函數(shù)調(diào)用

例子:

優(yōu)化前:

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;
}
}

優(yōu)化后:

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];
}

優(yōu)化前的版本在每次循環(huán)中都要調(diào)用一次get_vec_element獲得相應(yīng)的項(xiàng),而優(yōu)化后的版本只需在循環(huán)外調(diào)用一次get_vec_start獲得開始的內(nèi)存地址,循環(huán)內(nèi)直接訪問內(nèi)存,無需調(diào)用函數(shù)。

三.減少內(nèi)存訪問

例子:

優(yōu)化前:

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];
}

優(yōu)化后:

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;
}

優(yōu)化前的版本每次迭代都要從dest讀出值再加上data[i],再將結(jié)果寫回dest。這樣的讀寫很浪費(fèi),因此每次迭代開始從dest讀出的值就是上次迭代寫回dest的指。優(yōu)化后的版本通過加入acc臨時(shí)變量,它循環(huán)中累積計(jì)算出的結(jié)果,循環(huán)結(jié)束后再寫回。

這里給出兩個(gè)版本相應(yīng)的匯編結(jié)果就可以很清楚看出區(qū)別:

優(yōu)化前:

2015122102845375.png (704×221)

優(yōu)化前的版本每次迭代都要從dest讀出值再加上data[i],再將結(jié)果寫回dest。這樣的讀寫很浪費(fèi),因此每次迭代開始從dest讀出的值就是上次迭代寫回dest的指。優(yōu)化后的版本通過加入acc臨時(shí)變量,它循環(huán)中累積計(jì)算出的結(jié)果,循環(huán)結(jié)束后再寫回。

第二行和第四行分別對(duì)dest進(jìn)行了讀寫。

優(yōu)化后:

2015122102904746.png (677×180)

從匯編結(jié)果可以看出編譯器將acc直接放在了寄存器里,循環(huán)中無需對(duì)內(nèi)存進(jìn)行讀寫。

四.循環(huán)展開

循環(huán)展開可以減少循環(huán)的次數(shù),對(duì)程序的性能帶了兩方面的提高。一是減少了對(duì)循環(huán)沒有直接貢獻(xiàn)的計(jì)算,比如循環(huán)計(jì)數(shù)變量的計(jì)算,分支跳轉(zhuǎn)指令的執(zhí)行等。二是提供了進(jìn)一步利用機(jī)器特性進(jìn)行的優(yōu)化的機(jī)會(huì)。

例子:

優(yōu)化前的代碼見前一篇博客里的sum3.

優(yōu)化后:

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;
}

通過循環(huán)展開,每次迭代將累加4個(gè)元素,減少了循環(huán)次數(shù),從而減少了總的執(zhí)行時(shí)間(單獨(dú)使用這種優(yōu)化方法,對(duì)浮點(diǎn)數(shù)累乘幾乎沒有提高,但是整數(shù)累乘得益于編譯器的重關(guān)聯(lián)代碼變化會(huì)有大幅度提高)。

這種優(yōu)化可以直接利用編譯器完成,將優(yōu)化level設(shè)定到較高,編譯器會(huì)自動(dòng)進(jìn)行循環(huán)展開。使用gcc,可以顯式使用-funroll-loops選項(xiàng)。

五.提高并行性

現(xiàn)代處理器大多采用了流水線、超標(biāo)量等技術(shù),可以實(shí)現(xiàn)指令級(jí)并行。我們可以利用這個(gè)特性對(duì)代碼做進(jìn)一步的優(yōu)化。

2.1使用多個(gè)累積變量

優(yōu)化代碼示例

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;
}

這里同時(shí)使用了循環(huán)展開和使用多個(gè)累加變量,一方面減少了循環(huán)次數(shù),另一方面指令級(jí)并行的特性使得每次迭代的兩次加法可以并行執(zhí)行。基于這兩點(diǎn)可以顯著減少程序執(zhí)行的時(shí)間。通過增加展開的次數(shù)和累加變量的個(gè)數(shù),可以進(jìn)一步提高程序的性能,直到機(jī)器指令執(zhí)行的吞吐量的極限。

2.2重結(jié)合變換

除了使用多個(gè)累積變量顯式利用機(jī)器的指令級(jí)并行特性外,還可以對(duì)運(yùn)算重新結(jié)合變換,打破順序相關(guān)性來享受指令級(jí)并行帶來的好處。

在sum4中,acc=acc+data[i]+data[i+1]的結(jié)合順序是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;
}

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

相關(guān)文章

  • C++設(shè)計(jì)模式編程中簡(jiǎn)單工廠與工廠方法模式的實(shí)例對(duì)比

    C++設(shè)計(jì)模式編程中簡(jiǎn)單工廠與工廠方法模式的實(shí)例對(duì)比

    這篇文章主要介紹了C++設(shè)計(jì)模式編程中簡(jiǎn)單工廠與工廠方法模式的實(shí)例對(duì)比,文中最后對(duì)兩種模式的優(yōu)缺點(diǎn)總結(jié)也比較詳細(xì),需要的朋友可以參考下
    2016-03-03
  • C和MFC巧妙獲取外網(wǎng)IP的兩種實(shí)現(xiàn)方法

    C和MFC巧妙獲取外網(wǎng)IP的兩種實(shí)現(xiàn)方法

    這篇文章主要介紹了C和MFC巧妙獲取外網(wǎng)IP的兩種實(shí)現(xiàn)方法,功能非常的實(shí)用,需要的朋友可以參考下
    2014-07-07
  • C++ 智能指針代碼解析

    C++ 智能指針代碼解析

    這篇文章主要介紹了c++ 智能指針基礎(chǔ)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下,希望能給你帶來幫助
    2021-10-10
  • linux下C/C++學(xué)生信息管理系統(tǒng)

    linux下C/C++學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了linux下c/c++學(xué)生信息管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 關(guān)于C++虛繼承的內(nèi)存模型問題

    關(guān)于C++虛繼承的內(nèi)存模型問題

    C++虛繼承的內(nèi)存模型是一個(gè)老生常談的話題,實(shí)現(xiàn)方法主要依賴于編譯器,本文從多個(gè)角度通過代碼詳解C++中虛繼承的內(nèi)存模型知識(shí),感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • C++中的多態(tài)詳談

    C++中的多態(tài)詳談

    多態(tài)通俗來說就是多種形態(tài),本文通過實(shí)例代碼給大家介紹C++中的多態(tài)定義及實(shí)現(xiàn),通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-05-05
  • 詳解C++中的isunordered函數(shù)

    詳解C++中的isunordered函數(shù)

    這篇文章主要介紹了C++中的isunordered函數(shù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • C語言實(shí)現(xiàn)大整數(shù)加減運(yùn)算詳解

    C語言實(shí)現(xiàn)大整數(shù)加減運(yùn)算詳解

    大數(shù)運(yùn)算,顧名思義,就是很大的數(shù)值的數(shù)進(jìn)行一系列的運(yùn)算。本文通過實(shí)例演示如何進(jìn)行C語言中的大整數(shù)加減運(yùn)算,有需要的可以參考借鑒。
    2016-08-08
  • C語言Easyx實(shí)現(xiàn)貪吃蛇詳解

    C語言Easyx實(shí)現(xiàn)貪吃蛇詳解

    這篇文章主要為大家詳細(xì)介紹了基于easyx的C++實(shí)現(xiàn)貪吃蛇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C語言數(shù)組詳細(xì)介紹

    C語言數(shù)組詳細(xì)介紹

    大家好,本篇文章主要講的是C語言數(shù)組詳細(xì)介紹,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01

最新評(píng)論