国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

哈工大csapp-LAB3程序優(yōu)化

這篇具有很好參考價值的文章主要介紹了哈工大csapp-LAB3程序優(yōu)化。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

實(shí)驗(yàn)報告

實(shí) 驗(yàn)(三)

題???? 目 ?????優(yōu)化??????? ???????

專?????? 業(yè) ???人工智能(未來技術(shù))???

學(xué)  ?? 號 ???7203610716?????????????

班  ?? 級 ???20WJ102???????????????

學(xué)?????? 生 ???孫銘蔚???????????    

指 導(dǎo) 教 師 ???劉宏偉???????????????   

實(shí) 驗(yàn) 地 點(diǎn) ???G712?????????????    

實(shí) 驗(yàn) 日 期 ???2022.04.16?????????    

計算學(xué)部

?

第1章 實(shí)驗(yàn)基本信息....................................... - 3 -

1.1 實(shí)驗(yàn)?zāi)康?.................................................. - 3 -

1.2 實(shí)驗(yàn)環(huán)境與工具............................................. - 3 -

1.2.1 硬件環(huán)境............................................... - 3 -

1.2.2 軟件環(huán)境............................................... - 3 -

1.2.3 開發(fā)工具............................................... - 3 -

1.3 實(shí)驗(yàn)預(yù)習(xí)................................................... - 3 -

第2章 實(shí)驗(yàn)預(yù)習(xí)........................................... - 4 -

2.1 程序優(yōu)化的十大方法(5分).................................. - 4 -

2.2性能優(yōu)化的方法概述(5分).................................. - 4 -

2.3 Linux下性能測試的方法(5分)............................... - 4 -

2.4 Windows下性能測試的方法(5分).............................. - 4 -

第3章 性能優(yōu)化的方法..................................... - 5 -

第4章 性能優(yōu)化實(shí)踐....................................... - 7 -

第5章 總結(jié).............................................. - 8 -

5.1 請總結(jié)本次實(shí)驗(yàn)的收獲....................................... - 8 -

5.2 請給出對本次實(shí)驗(yàn)內(nèi)容的建議................................. - 8 -

參考文獻(xiàn)................................................. - 9 -

第1章 實(shí)驗(yàn)基本信息

1.1 實(shí)驗(yàn)?zāi)康?/h3>
    • 理解程序優(yōu)化的10個維度
    • 熟練利用工具進(jìn)行程序的性能評價、瓶頸定位
    • 掌握多種程序性能優(yōu)化的方法
    • 熟練應(yīng)用軟件、硬件等底層技術(shù)優(yōu)化程序性能

1.2 實(shí)驗(yàn)環(huán)境與工具

1.2.1 硬件環(huán)境

硬件1概覽:

? 型號名稱: MacBook Air

? 型號標(biāo)識符: MacBookAir10,1

? 芯片: Apple M1

? 核總數(shù): 8(4性能和4能效)

? 內(nèi)存: 8 GB

? 系統(tǒng)固件版本: 7429.81.3

? 操作系統(tǒng)加載程序版本: 7429.81.3

? 序列號(系統(tǒng)): C02H479LQ6L5

? 硬件UUID: B9297F28-81B7-5DB0-8760-89063F63E0E5

? 預(yù)置UDID: 00008103-001205960108801E

? 激活鎖狀態(tài): 已啟用

硬件2概覽:

64 位操作系統(tǒng), 基于 x64 的處理器

AMD Ryzen 7 4800H with Radeon Graphics??????????? 2.90 GHz

LAPTOP-CSSCDDGT

1.2.2 軟件環(huán)境

Windows下Visual Studio 2020以上64位

Windows下Perf、VS的性能探測器

Ubuntu下oprofiler、gprof

1.2.3 開發(fā)工具

Visual Studio 2022 64位;vs code 64位

1.3 實(shí)驗(yàn)預(yù)習(xí)

了解實(shí)驗(yàn)的目的、實(shí)驗(yàn)環(huán)境與軟硬件工具、實(shí)驗(yàn)操作步驟,復(fù)習(xí)與實(shí)驗(yàn)有關(guān)的理論知識。性能測試準(zhǔn)確性的文獻(xiàn)查找,我了解到,流水線、超線程、超標(biāo)量、向量、多核、GPU、多級CACHE、編譯優(yōu)化Ox、多進(jìn)程、多線程等多種因素對程序性能均有綜合影響。

第2章 實(shí)驗(yàn)預(yù)習(xí)

總分20分

2.1 程序優(yōu)化的十大方法(5分)

  1. 優(yōu)化性能
  2. 減少空間占用,減少運(yùn)行內(nèi)存
  3. 美化UI界面
  4. 更加正確
  5. 增加程序可靠性
  6. 增加可移植性
  7. 有更強(qiáng)大功能
  8. 使用方便
  9. 更加符合編程規(guī)范和接口規(guī)范
  10. 更加易懂,加注釋、模塊化

2.2性能優(yōu)化的方法概述(5分)

1.一般有用的優(yōu)化

2.面向編譯器的優(yōu)化

3.面向超標(biāo)量CPU的優(yōu)化

4.面向向量CPU的優(yōu)化

5. CMOVxx等指令

6. 嵌入式匯編

7.面向編譯器的優(yōu)化

8.面向存儲器的優(yōu)化:

9.內(nèi)存作為邏輯磁盤

10.多進(jìn)程優(yōu)化

11.文件訪問優(yōu)化:帶Cache的文件訪問

12.并行計算:多線程優(yōu)化

13.網(wǎng)絡(luò)計算優(yōu)化

14.GPU編程、算法優(yōu)化

15.超級計算

2.3 Linux下性能測試的方法(5分)

  1. linux下使用Oprofile等工具
  2. 使用自己構(gòu)造的函數(shù)測出程序運(yùn)行時間,進(jìn)而測試性能

2.4 Windows下性能測試的方法(5分)

1.在visual studio中使用調(diào)試工具:性能探測器:CPU、RAM、GPU

2.使用自己構(gòu)造的函數(shù)測出程序運(yùn)行時間,進(jìn)而測試性能

第3章 性能優(yōu)化的方法

總分20分

逐條論述性能優(yōu)化方法名稱、原理、實(shí)現(xiàn)方案(至少10條)

3.1

1.一般有用的優(yōu)化

代碼移動

復(fù)雜指令簡化

公共子表達(dá)式

2.面向編譯器的優(yōu)化:障礙

函數(shù)副作用

內(nèi)存別名

3.面向超標(biāo)量CPU的優(yōu)化

流水線、超線程、多功能部件、分支預(yù)測投機(jī)執(zhí)行、亂序執(zhí)行、多核:分離的循環(huán)展開!

只有保持能夠執(zhí)行該操作的所有功能單元的流水線都是滿的,程序才能達(dá)到這個操作的吞吐量界限

4.面向向量CPU的優(yōu)化:MMX/SSE/AVR

5. CMOVxx等指令

代替test/cmp+jxx

6. 嵌入式匯編

7.面向編譯器的優(yōu)化

Ox:0 1 2 3 g

8.面向存儲器的優(yōu)化:Cache無處不在

重新排列提高空間局部性

分塊提高時間局部性

9.內(nèi)存作為邏輯磁盤:內(nèi)存夠用的前提下。

10.多進(jìn)程優(yōu)化

fork,每個進(jìn)程負(fù)責(zé)各自的工作任務(wù),通過mmap共享內(nèi)存或磁盤等進(jìn)行交互。

11.文件訪問優(yōu)化:帶Cache的文件訪問

12.并行計算:多線程優(yōu)化:第12章

13.網(wǎng)絡(luò)計算優(yōu)化:第11章、分布式計算、云計算

14.GPU編程、算法優(yōu)化

15.超級計算
?

第4章 性能優(yōu)化實(shí)踐

總分60分

4.1 原始程序及說明(10分)

void putong(long img[1922][1082])
{
??? for(int j = 1; j < 1081; j++)
??? {
??????? for (int i = 1; i < 1921;i++)
??????? {
??????????? /* code */
??????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) / 4;
??????? }
??? }
}

程序的功能:

源程序功能是對給定的數(shù)組模擬圖像平滑算法,對數(shù)組的值進(jìn)行更改

流程:任一點(diǎn)的顏色值為其上下左右4個點(diǎn)顏色的平均值,即:img[i][j]? =?? (? img[i-1][j] + img[i+1][j] +img[i][j-1] + img[i][j+1] ) /4。

程序可能瓶頸:

1、這個程序不符合空間局部性

2、這個程序使用了占用時鐘周期較長的除法

3、這個程序沒有充分利用CPU,即流水線不是總處于滿的狀態(tài),具有數(shù)據(jù)相關(guān)性。由于循環(huán)減少了分支預(yù)測失敗的可能性,同時增加了循環(huán)體內(nèi)語句并發(fā)執(zhí)行的可能性,我們考慮使用循環(huán)展開對代碼優(yōu)化。

4.2 優(yōu)化后的程序及說明(20分)

至少包含面向CPU、Cache的兩種優(yōu)化策略(20分),額外每增加1種優(yōu)化方法加5分至第4章滿分。

面向CPU(循環(huán)展開):

void cpu(long img[1922][1082])//循環(huán)展開

{

? ? int i;

? ? long bef1,aft1,bef2,aft2;

? ? long B[1082];

? ? for (i = 0;i < 1082;i++) {

? ? ? ? B[i] = img[0][i];

? ? }

? ? for(int j=1;j<1080;j+=8)

? ? {

? ? ? ? for(int i=1;i<1921;i++)

? ? ? ? {

? ? ? ? ? ? bef1=img[i][j+1];

? ? ? ? ? ? aft1=img[i][j+2];

? ? ? ? ? ? bef2=img[i][j+5];

? ? ? ? ? ? aft2=img[i][j+6];

? ? ? ? ? ? img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef1)/4;

? ? ? ? ? ? img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft1+img[i][j])/4;

? ? ? ? ? ? img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef1+img[i][j+3])/4;

? ? ? ? ? ? img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft1+img[i][j+4])/4;

? ? ? ? ? ? img[i][j+4]=(B[j+4]+img[i+1][j+4]+img[i][j+3]+bef2)/4;

? ? ? ? ? ? img[i][j+5]=(B[j+5]+img[i+1][j+5]+aft2+img[i][j+4])/4;

? ? ? ? ? ? img[i][j+6]=(B[j+6]+img[i+1][j+6]+bef2+img[i][j+7])/4;

? ? ? ? ? ? img[i][j+7]=(B[j+7]+img[i+1][j+7]+aft2+img[i][j+8])/4;

? ? ? ? ? ? B[j] = img[i][j];

? ? ? ? ? ? B[j + 1] = img[i][j+1];

? ? ? ? ? ? B[j + 2] = img[i][j+2];

? ? ? ? ? ? B[j + 3] = img[i][j+3];

? ? ? ? ? ? B[j+4] = img[i][j+4];

? ? ? ? ? ? B[j + 5] = img[i][j+5];

? ? ? ? ? ? B[j + 6] = img[i][j+6];

? ? ? ? ? ? B[j + 7] = img[i][j+7];

? ? ? ? }



? ? }



}

說明:

顯然流水線只要流起來可以大大提高CPU的工作效率,我們在循環(huán)的時候,每次可以使用更多變量參與運(yùn)算,能使流水線更好地流。于是。我首先講邊緣數(shù)據(jù)存儲到數(shù)組B中。在主循環(huán)中,我設(shè)置的步長為8,我定義4個變量aft1bef1aft2bef2,分別存儲8個原數(shù)據(jù)的第32、7、6個,每次循環(huán)更新img數(shù)組后,更新B數(shù)組。

這樣可以使硬件能讓流水線很好地運(yùn)作,即使在少數(shù)情況下也只犧牲一點(diǎn)效率。

面向Cache1(符合空間局部性):

void cache(long img[1922][1082])

{

??? for(int i = 1; i < 1921;i++)

??? {

??????? for (int j = 1; j < 1081; j++)

??????? {

??????????? /* code */

??????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) /4;

??????? }

??? }

}

說明:

由于數(shù)組在電腦中按行進(jìn)行存儲,根據(jù)上課講過的命中和不命中的知識,通過書中知識可以知道,對于數(shù)組來說,一旦程序訪問了某個存儲單元,在不久之后,其附近的存儲單元也將被訪問,即程序在一段時間內(nèi)所訪問的地址,可能集中在一定的范圍之內(nèi),這是因?yàn)橹噶钔ǔJ琼樞虼娣?、順序?zhí)行的,數(shù)據(jù)也一般是以向量、數(shù)組、表等形式簇聚存儲的。如果一個存儲器的位置被引用,那么將來他附近的位置也會被引用。如果其訪問順序和存儲順序一致,程序性能會提升很多。

面向Cache2(按行進(jìn)行分塊):

void fenkuai_cpu_row(long img[1922][1082])

{

??? int i, j, k, kk=4, jj=4;

??? int bsize = 4;

??? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

??? int en = 1921; /* Amount that fits evenly into blocks */



??? for (jj = 1; jj < en; jj += bsize)

??? {

??????? for (i = jj; i < jj + bsize; i++)

??????? {

??????????? for (j = 1; j < 1081; j++)

??????????? {

??????????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) / 4;



??????????? }

??????? }

??? }

}

說明:

根據(jù)csapp中所述,有一種有趣的技術(shù)叫做分塊,它可以改善內(nèi)部循環(huán)的時間局部性。分塊的一般思想是將程序中的數(shù)據(jù)結(jié)構(gòu)組織成稱為塊的大塊。(在這里,指的是應(yīng)用程序級的數(shù)據(jù)塊,而不是緩存塊。)程序是結(jié)構(gòu)化的,它將一個數(shù)據(jù)塊加載到L1緩存中,對該數(shù)據(jù)塊執(zhí)行所有需要的讀寫操作,然后丟棄該數(shù)據(jù)塊,加載下一個數(shù)據(jù)塊,以此類推。與用于改進(jìn)空間局部性的簡單循環(huán)轉(zhuǎn)換不同,阻塞使代碼更難閱讀和理解。由于這個原因,它最適合優(yōu)化編譯器或頻繁執(zhí)行的庫例程。利用上述原理,我將數(shù)據(jù)按列分塊,我默認(rèn)一個塊中有4個數(shù)據(jù),進(jìn)行試驗(yàn)后發(fā)現(xiàn)性能提升不少。

面向Cache3(按列進(jìn)行分塊):

void fenkuai_cpu_col(long img[1922][1082])

{

??? int i, j, k, kk=4, jj=4;

??? int bsize = 4;

??? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

??? int en = 1081; /* Amount that fits evenly into blocks */





??? for (jj = 1; jj < en; jj += bsize)

??? {

??????? for (i = 1; i < 1921; i++)

??????? {

??????????? for (j = jj; j < jj + bsize; j++)

??????????? {

??????????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) / 4;



??????? ????}

??????? }

??? }

}

說明:

根據(jù)csapp中所述,有一種有趣的技術(shù)叫做分塊,它可以改善內(nèi)部循環(huán)的時間局部性。分塊的一般思想是將程序中的數(shù)據(jù)結(jié)構(gòu)組織成稱為塊的大塊。(在這里,指的是應(yīng)用程序級的數(shù)據(jù)塊,而不是緩存塊。)程序是結(jié)構(gòu)化的,它將一個數(shù)據(jù)塊加載到L1緩存中,對該數(shù)據(jù)塊執(zhí)行所有需要的讀寫操作,然后丟棄該數(shù)據(jù)塊,加載下一個數(shù)據(jù)塊,以此類推。與用于改進(jìn)空間局部性的簡單循環(huán)轉(zhuǎn)換不同,阻塞使代碼更難閱讀和理解。由于這個原因,它最適合優(yōu)化編譯器或頻繁執(zhí)行的庫例程。利用上述原理,我將數(shù)據(jù)按列分塊,我默認(rèn)一個塊中有4個數(shù)據(jù),進(jìn)行試驗(yàn)后發(fā)現(xiàn)性能提升不少。

面向Cache4(按正方形進(jìn)行分塊):

void fenkuai_cpu_row4(long img[1922][1082])

{

? ? int i, j, k, kk = 4, jj = 4;

? ? int bsize = 4;

? ? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

? ? int M = 1081, N = 1921;

? ? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

? ? int en = 1921; /* Amount that fits evenly into blocks */



? ? for (int ii = 1; ii < N; ii += bsize)

? ? {

? ? ? ? for (int jj = 1; jj < M; jj += bsize)

? ? ? ? {

? ? ? ? ? ? for (int i = ii; i < ((ii + bsize) > N ? N : ii + bsize); i++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? for (int j = jj; j < ((jj + bsize) > M ? M : jj + bsize); j++)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? img[i][j] = (img[i - 1][j] + img[i + 1][j] + img[i][j - 1] + img[i][j + 1]) / 4;



? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? }

}



一般的優(yōu)化方法(除法變成移位操作):

void cache1(long img[1922][1082])

{

??? for(int j = 1; j < 1081; j++)

??? {

??????? for (int i = 1; i < 1921;i++)

??????? {

??????????? /* code */

??????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) >> 2;

??????? }

??? }

}

說明:

由于從效率上看,使用移位指令有更高的效率,因?yàn)?/span>移位指令2個機(jī)器周期,而乘除法指令占4個機(jī)器周期。從硬件上看,移位對硬件更容易實(shí)現(xiàn),所以會用移位,左移一位就乘2,右移一位處以2,這種乘除法考慮移位實(shí)現(xiàn)會更快。

整合所有方法:

void success(long img[1922][1082])

{

? ??int i;

??? long bef,aft;

??? long B[1082];

??? for (i = 0;i < 1082;i++) {

??????? B[i] = img[0][i];//存儲邊界值

??? }

??? for(int i=1;i<1921;i++)

??? {

??????? for(int j=1;j<1081;j+=4)

??????? {

??????????? bef=img[i][j+1];

??????????? aft=img[i][j+2];

????? ??????img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef)>>2;

??????????? img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft+img[i][j])>>2;

??????????? img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef+img[i][j+3])>>2;

??????????? img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft+img[i][j+4])>>2;

? ??????????B[j] = img[i][j];

??????????? B[j + 1] = img[i][j+1];

??????????? B[j + 2] = img[i][j+2];

??????????? B[j + 3] = img[i][j+3];

??????? }

??? }

}

4.3 優(yōu)化前后的性能測試(10分)

測試方法:

使用C語言中的庫函數(shù)測量程序開始到結(jié)束的時間,對各個優(yōu)化方法的時間進(jìn)行比較,而且我每次運(yùn)算后打印指定位置數(shù)據(jù),發(fā)現(xiàn)均相同,證明程序沒出錯。

測試結(jié)果:

????? ??

圖1性能測試截圖

從測試結(jié)果可以看到,我采用的優(yōu)化方法確實(shí)提高了程序性能,減少了程序運(yùn)行時間。

整理所有運(yùn)行時間如下表:

表1:性能測試結(jié)果

采用方法描述

運(yùn)行時間(s)

(初始狀態(tài),沒有進(jìn)行任何優(yōu)化,局部性很差)

0.86

after (一般有用的優(yōu)化,除法變?yōu)橐莆徊僮?

0.55

after cache(空間局部性)

0.78

after cpu(循環(huán)展開8)

0.46

(整合所有非分塊的優(yōu)化方案)

0.42

按列對矩陣進(jìn)行分塊(cache)

0.80

按行對矩陣進(jìn)行分塊(cache)

0.77

按列對矩陣進(jìn)行分塊+除法變成移位

0.52

按行對矩陣進(jìn)行分塊+除法變成移位

0.47

分成4*4的塊(cache)

0.42

4.4 結(jié)合自己計算機(jī)的硬件參數(shù),分析優(yōu)化后程序的各個參數(shù)選擇依據(jù)。(15分)

我選擇結(jié)合自己計算機(jī)的硬件參數(shù),分析優(yōu)化后程序的各個參數(shù)選擇依據(jù)。

首先我查看了自己電腦的L1、L2、L3緩存大小,如下圖所示:

對分塊進(jìn)行優(yōu)化:

程序如下:

void fenkuai_cpu_row128(long img[1922][1082])

{



??? int bsize = 128;

??? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

??? int en = 1081; /* Amount that fits evenly into blocks */

??? int M = 1081, N = 1921;





? for (int jj = 1; jj < M; jj += bsize)

??? {

??? for (int ii = 1; ii < N; ii += bsize)

??????? {

??????????? for (int j = jj; j < ((jj + bsize) > M ? M : jj + bsize); j++)

??????????? {

??????????????? for (int i = ii; i < ((ii + bsize) > N ? N : ii + bsize); i++)

??????????????? {

??????????????????? img[i][j] = (img[i - 1][j] + img[i + 1][j] + img[i][j - 1] + img[i][j + 1]) / 4;



??????????????? }

??????????? }

??????? }

??? }

}???????????????

以下為程序運(yùn)行結(jié)果:

說明:Cache的層次,一般有L1, L2, L3 (L是level的意思)的cache。通常來說L1,L2是集成 在CPU里面的(可以稱之為On-chip cache),而L3是放在CPU外面(可以稱之為Off-chip cache)。當(dāng)然這個不是絕對的,不同CPU的做法可能會不太一樣。這里面應(yīng)該還需要加上 register,雖然register不是cache,但是把數(shù)據(jù)放到register里面是能夠提高性能的??梢允褂脺p少D-cache miss的數(shù)量,增加有效的數(shù)據(jù)訪問的數(shù)量。這個要比I-cache優(yōu)化難一些。由于我的L1高速緩存大小為512KB,8核,所以一個核為64KB,由于long數(shù)據(jù)類型是8個字節(jié)。每個分塊的大小為128*128, 所以每個塊的miss次數(shù)是128。這樣總的miss率就是1*1922*1081/(4*128),如果分成4*4的塊,不命中率就會很高,經(jīng)過實(shí)驗(yàn)分成更大的塊,實(shí)驗(yàn)效果不好,根據(jù)我電腦的參數(shù),選擇128*128的塊比選擇其他參數(shù)效果更好。

對循環(huán)展開優(yōu)化:

void success(long img[1922][1082])

{

? ? int i;

? ? long bef,aft;

? ? long B[1082];

? ? for (i = 0;i < 1082;i++) {

? ? ? ? B[i] = img[0][i];//瀛樺偍杈圭晫鍊?

? ? }

? ? for(int i=1;i<1921;i++)

? ? {

? ? ? ? for(int j=1;j<1081;j+=4)

? ? ? ? {

? ? ? ? ? ? bef=img[i][j+1];

? ? ? ? ? ? aft=img[i][j+2];

? ? ? ? ? ? img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef)/4;

? ? ? ? ? ? img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft+img[i][j])/4;

? ? ? ? ? ? img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef+img[i][j+3])/4;

? ? ? ? ? ? img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft+img[i][j+4])/4;

? ? ? ? ? ? B[j] = img[i][j];

? ? ? ? ? ? B[j + 1] = img[i][j+1];

? ? ? ? ? ? B[j + 2] = img[i][j+2];

? ? ? ? ? ? B[j + 3] = img[i][j+3];

? ? ? ? }



? ? }



}

以下為運(yùn)行結(jié)果:

說明:一個規(guī)律應(yīng)當(dāng)是被普遍認(rèn)同的,那就是循環(huán)展開的程度越高,循環(huán)執(zhí)行開銷所占的比例就會越小??墒?,根據(jù)實(shí)驗(yàn)結(jié)果,循環(huán)展開4次的結(jié)果確實(shí)好于循環(huán)展開8次的結(jié)果,經(jīng)過分析,可能是由于循環(huán)展開8次初始化過多變量,導(dǎo)致程序性能提升效果比循環(huán)展開4次的效果差。

4.5 還可以采取的進(jìn)一步的優(yōu)化方案(5分)

正因?yàn)榫€程是調(diào)度的最小單位,控制好線程,也就相當(dāng)于控制好了計算資源。

多線程與異步計算的關(guān)系密切,一般可以使用異步計算的,都可以用多線程來實(shí)現(xiàn),而多線程加速也依賴于異步計算,利用多線程來并行處理多個任務(wù),提高計算資源的利用率,也可以對我們的程序進(jìn)行優(yōu)化,從而提升程序性能。

程序代碼如下,可以直接運(yùn)行調(diào)試:

#include "stdio.h"

#include<time.h>

#include "math.h"

long img[1922][1082];

// void timecmp(long img[1922][1082])

void test (long img[1922][1082])

{

??? // printf("\n");

??? for(int k=0;k<1900;k+=500)

??? {

??????? printf("%ld\t",img[k][1000]);

??? }

??? printf("\n");

}

void putong(long img[1922][1082])

{

??? for(int j = 1; j < 1081; j++)

??? {

??????? for (int i = 1; i < 1921;i++)

??????? {

??????????? /* code */

??????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) / 4;

??????? }

??? }

}

void cache1(long img[1922][1082])

{

??? for(int j = 1; j < 1081; j++)

??? {

??????? for (int i = 1; i < 1921;i++)

??????? {

??????????? /* code */

??????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) >> 2;

??????? }

??? }

}

void cache(long img[1922][1082])

{

??? for(int i = 1; i < 1921;i++)

??? {

??????? for (int j = 1; j < 1081; j++)

??????? {

??????????? /* code */

??????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) /4;

??????? }

??? }

}

void cpu(long img[1922][1082])//循環(huán)展開

{

??? int i;

??? long bef,aft;

??? long B[1082];

??? for (i = 0;i < 1082;i++) {

??????? B[i] = img[0][i];//存儲邊界值

??? }

??? for(int j=1;j<1080;j+=4)

??? {

??????? for(int i=1;i<1921;i++)

??????? {

??????????? bef=img[i][j+1];

??????????? aft=img[i][j+2];

??????????? img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef)/4;

??????????? img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft+img[i][j])/4;

??????????? img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef+img[i][j+3])/4;

??????????? img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft+img[i][j+4])/4;

??????????? B[j] = img[i][j];

??????????? B[j + 1] = img[i][j+1];

??????????? B[j + 2] = img[i][j+2];

??????????? B[j + 3] = img[i][j+3];

??????? }



??? }



}

void fenkuai_cpu_row(long img[1922][1082])

{

??? int i, j, k, kk=4, jj=4;

??? int bsize = 4;

??? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

??? int en = 1921; /* Amount that fits evenly into blocks */





??? for (jj = 1; jj < en; jj += bsize)

??? {

????? ??for (i = jj; i < jj + bsize; i++)

??????? {



??????????? for (j = 1; j < 1081; j++)

??????????? {

??????????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) /4;



??????????? }

??????? }

??? }

}

void fenkuai_cpu_row_yi(long img[1922][1082])

{

??? int i, j, k, kk=4, jj=4;

??? int bsize = 4;

??? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

??? int en = 1921; /* Amount that fits evenly into blocks */





??? for (jj = 1; jj < en; jj += bsize)

??? {

??????? for (i = jj; i < jj + bsize; i++)

??????? {



??????????? for (j = 1; j < 1081; j++)

??????????? {

??????????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) >>2;



??????????? }

??????? }

??? }

}

void fenkuai_cpu_col(long img[1922][1082])

{

??? int i, j, k, kk=4, jj=4;

??? int bsize = 4;

??? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

??? int en = 1081; /* Amount that fits evenly into blocks */





??? for (jj = 1; jj < en; jj += bsize)

??? {

??????? for (i = 1; i < 1921; i++)

??????? {

??????????? for (j = jj; j < jj + bsize; j++)

??????????? {

??????????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) /4;



??????????? }

??????? }

??? }

}

void fenkuai_cpu_col_yi(long img[1922][1082])

{

??? int i, j, k, kk=4, jj=4;

??? int bsize = 4;

??? // int en = bsize * (1922/bsize); /* Amount that fits evenly into blocks */

??? int en = 1081; /* Amount that fits evenly into blocks */





??? for (jj = 1; jj < en; jj += bsize)

??? {

??????? for (i = 1; i < 1921; i++)

??????? {

??????????? for (j = jj; j < jj + bsize; j++)

??????????? {

??????????????? img[i][j] = (img[i-1][j] + img[i+1][j]+img[i][j-1] + img[i][j+1] ) >>2;



??????????? }

??????? }

??? }

}

void success(long img[1922][1082])

{

??? int i;

??? long bef,aft;

??? long B[1082];

??? for (i = 0;i < 1082;i++) {

??????? B[i] = img[0][i];//存儲邊界值

??? }

??? for(int i=1;i<1921;i++)

??? {

??????? for(int j=1;j<1081;j+=4)

??????? {

??????????? bef=img[i][j+1];

??????????? aft=img[i][j+2];

??????????? img[i][j]=(B[j]+img[i+1][j]+img[i][j-1]+bef)>>2;

??????????? img[i][j+1]=(B[j+1]+img[i+1][j+1]+aft+img[i][j])>>2;

??????????? img[i][j+2]=(B[j+2]+img[i+1][j+2]+bef+img[i][j+3])>>2;

??????????? img[i][j+3]=(B[j+3]+img[i+1][j+3]+aft+img[i][j+4])>>2;

??????? ????B[j] = img[i][j];

??????????? B[j + 1] = img[i][j+1];

??????????? B[j + 2] = img[i][j+2];

??????????? B[j + 3] = img[i][j+3];

??????? }



??? }



}





int main ()

{



??? printf("startle!\n");

??? int i = 0;

??? for(int i=0;i<1922;i++)

??? {

??????? for (int j = 0; j < 1082; j++)

??????? {

??????????? /* code */

??????????? img[i][j]= i+j;

??????? }



??? }

??? clock_t start_t = clock();

??? for(i=0;i<50;i++)

??????? putong(img);

??? clock_t end_t = clock();

??? test(img);



??? double sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

??? printf("(初始狀態(tài),沒有進(jìn)行任何優(yōu)化,局部性很差)cost time: %f(s)\n",sum_time);

??? start_t = clock();

??? for(i=0;i<50;i++)

??????? cache1(img);



??? end_t = clock();

??? test(img);

??? sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

??? printf("after (一般有用的優(yōu)化,除法變?yōu)橐莆徊僮?cost time: %f(s)\n",sum_time);

??? start_t = clock();

??? for(i=0;i<50;i++)

??????? cache(img);



??? end_t = clock();

??? test(img);

??? sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

??? printf("after cache(空間局部性) cost time: %f(s)\n",sum_time);

??? start_t = clock();

??? for(i=0;i<50;i++)

??????? cpu(img);



??? end_t = clock();

??? test(img);

??? sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

??? printf("after cpu(循環(huán)展開) cost time: %f(s)\n",sum_time);

??? start_t = clock();

??? for(i=0;i<50;i++)

??????? success(img);



??? end_t = clock();

??? test(img);

??? sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

??? printf("(整合所有非分塊的優(yōu)化方案)cost time: %f(s)\n",sum_time);

??? start_t = clock();

??? for(i=0;i<50;i++)

??????? fenkuai_cpu_col(img);

??? end_t = clock();

??? test(img);

??? sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

??? printf("(分塊col)cost time: %f(s)\n",sum_time);

??? start_t = clock();

??? for(i=0;i<50;i++)

??????? fenkuai_cpu_row(img);

??? end_t = clock();

? ??test(img);

??? sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

??? printf("(分塊row)cost time: %f(s)\n",sum_time);

??? start_t = clock();

??? for(i=0;i<50;i++)

??????? fenkuai_cpu_col_yi(img);

??? end_t = clock();

??? test(img);

??? sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

??? printf("(分塊col+移位)cost time: %f(s)\n",sum_time);

??? start_t = clock();

??? for(i=0;i<50;i++)

??????? fenkuai_cpu_row_yi(img);

??? end_t = clock();

??? test(img);

??? sum_time=((double)(end_t-start_t))/CLOCKS_PER_SEC;

?? ?printf("(分塊row+移位)cost time: %f(s)\n",sum_time);



}

第5章 總結(jié)

5.1 請總結(jié)本次實(shí)驗(yàn)的收獲

  1. 實(shí)驗(yàn)了很多優(yōu)化方案,對老師課上內(nèi)容理解更透徹
  2. 解決啦以前對程序性能的疑惑,即為什么時間復(fù)雜度高的程序運(yùn)行有時候更快
  3. 掌握時間函數(shù)使用方法
  4. 提升數(shù)學(xué)思維,鍛煉編程能力
  5. 了解了圖像平滑算法
  1. 總的來說,這個實(shí)驗(yàn)收獲還是很多的。尤其是對miss次數(shù)的定量分析,讓我很受益。之前學(xué)習(xí)算法之類的,只會大概估計一下復(fù)雜度的等級,完全定量地對程序分析對我來說還是比較少。在其他方面,如怎樣寫出對緩存友好的代碼,也有不少收獲。

5.2 請給出對本次實(shí)驗(yàn)內(nèi)容的建議

實(shí)驗(yàn)內(nèi)容很好,就是某些問題描述不清,例如4.4題,沒有給出操作實(shí)例,可能導(dǎo)致很多學(xué)生不知道從何做起,希望能改進(jìn)這一點(diǎn),其余做的都很好。

注:本章為酌情加分項(xiàng)。

參考文獻(xiàn)

為完成本次實(shí)驗(yàn)?zāi)惴喌臅c網(wǎng)站等

[1]? 林來興. 空間控制技術(shù)[M]. 北京:中國宇航出版社,1992:25-42.

[2]? 辛希孟. 信息技術(shù)與信息服務(wù)國際研討會論文集:A集[C]. 北京:中國科學(xué)出版社,1999.

[3]? 趙耀東. 新時代的工業(yè)工程師[M/OL]. 臺北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).

[4]? 諶穎. 空間交會控制理論與方法研究[D]. 哈爾濱:哈爾濱工業(yè)大學(xué),1992:8-13.

[5]? KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.

[6]? CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.文章來源地址http://www.zghlxwxcb.cn/news/detail-423831.html

 

到了這里,關(guān)于哈工大csapp-LAB3程序優(yōu)化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 哈工大 計算機(jī)系統(tǒng) 二進(jìn)制炸彈實(shí)驗(yàn)報告

    哈工大 計算機(jī)系統(tǒng) 二進(jìn)制炸彈實(shí)驗(yàn)報告

    實(shí)驗(yàn)報告 實(shí) 驗(yàn)(三) 題 ????目 ?Binary Bomb???? ?? ? 二進(jìn)制炸彈 ? 專?????? 業(yè) ???? 計算機(jī)學(xué)院 ???????? 學(xué) ?? 號 ? ? ? ? ? ? ? 班 ?? 級 ? ? ? ? ? ? ?? 學(xué)?????? 生 ?????? ? ? ? 指 導(dǎo) 教 師 ??????? ? ? ?? 實(shí) 驗(yàn) 地 點(diǎn) ? ? ?? 實(shí) 驗(yàn) 日 期 ????

    2023年04月15日
    瀏覽(32)
  • 哈工大計算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)一——HTTP代理服務(wù)器的設(shè)計與實(shí)現(xiàn)

    哈工大計算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)一——HTTP代理服務(wù)器的設(shè)計與實(shí)現(xiàn)

    1. 設(shè)計并實(shí)現(xiàn)一個基本 HTTP 代理服務(wù)器。 要求在指定端口接收來自客戶的 HTTP 請求并且根據(jù)其中的 URL 地址訪問該地址所指向的 HTTP 服務(wù)器(原服務(wù)器),接收 HTTP 服務(wù)器的響應(yīng)報文,并將響應(yīng)報文轉(zhuǎn)發(fā)給對應(yīng)的客戶進(jìn)行瀏覽。 2. 設(shè)計并實(shí)現(xiàn)一個支持 Cache 功能的 HTTP 代理服

    2024年02月22日
    瀏覽(30)
  • 哈工大計算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)一-HTTP代理服務(wù)器的設(shè)計與實(shí)現(xiàn)

    哈工大計算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)一-HTTP代理服務(wù)器的設(shè)計與實(shí)現(xiàn)

    當(dāng)客戶在瀏覽器中設(shè)置好Proxy Server后,你使用瀏覽器訪問所有WWW站點(diǎn)的請求都不會直接發(fā)給目的主機(jī),而是先發(fā)給代理服務(wù)器,代理服務(wù)器接受了客戶的請求以后,由代理服務(wù)器向目的主機(jī)發(fā)出請求,并接受目的主機(jī)的數(shù)據(jù),存于代理服務(wù)器的硬盤中,然后再由代理服務(wù)器將

    2023年04月24日
    瀏覽(50)
  • 哈工大計算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)四——簡單網(wǎng)絡(luò)組建配置 Cisco Packet Tracer 使用指南

    哈工大計算機(jī)網(wǎng)絡(luò)實(shí)驗(yàn)四——簡單網(wǎng)絡(luò)組建配置 Cisco Packet Tracer 使用指南

    做實(shí)驗(yàn)四時,本來希望能夠借助實(shí)驗(yàn)指導(dǎo)書上的內(nèi)容速通,但嘗試了一個上午后發(fā)現(xiàn)遍地都是bug,于是便花了半天的時間認(rèn)真學(xué)習(xí)了一下其中的運(yùn)行機(jī)制,晚上又把所有的switch全都重寫了一遍,最后終于成功。這篇博客詳細(xì)介紹了該實(shí)驗(yàn)中使用Cisco Packet Tracer組建校園網(wǎng)的過程

    2024年02月09日
    瀏覽(58)
  • 計算理論期末2022哈工大

    一、請回答關(guān)于圖靈機(jī)的問題。(15 分) 確定圖靈機(jī)的形式化定義是什么? 不確定圖靈機(jī)和確定圖靈機(jī)的區(qū)別是什么? 二、請回答設(shè)計圖靈機(jī)相關(guān)的問題(畫出狀態(tài)轉(zhuǎn)移圖即可)。(15 分) 構(gòu)造確定圖靈機(jī)識別語言 L={0m1 n | m=0, n0}。 構(gòu)造確定圖靈機(jī)識別語言 L={0n1 n | n0}。 構(gòu)造

    2024年02月10日
    瀏覽(31)
  • 哈工大近世代數(shù)期末復(fù)習(xí)

    哈工大近世代數(shù)期末復(fù)習(xí)

    近世代數(shù)是抽象代數(shù)的一個分支,是計算機(jī)科學(xué)和人工智能大數(shù)據(jù)的基礎(chǔ).? 本文內(nèi)容有點(diǎn)長,大家可以通過index來跳轉(zhuǎn)到想要看的章節(jié),第十章的總結(jié)在我的主頁里下載 method1 有單位元 有逆元 運(yùn)算滿足結(jié)合律 method2: 運(yùn)算滿足結(jié)合律 運(yùn)算滿足左右消去律 定義:滿足交換律的群 應(yīng)

    2024年02月05日
    瀏覽(25)
  • 哈工大機(jī)器學(xué)習(xí)期末復(fù)習(xí)筆記(一)

    哈工大機(jī)器學(xué)習(xí)期末復(fù)習(xí)筆記(一)

    一、貝葉斯估計 當(dāng)我們需要對一個參數(shù)進(jìn)行估計時,一種辦法是概率論與數(shù)理統(tǒng)計課程中已經(jīng)學(xué)過的極大似然估計(Maximum Likelihood Estimation,MLE)。例如,如果我們想估計扔硬幣正面朝上的概率p,可以扔N次,記錄正面朝上的次數(shù)M,再用M/N估計p。這種方法得到的參數(shù)估計是個

    2024年02月01日
    瀏覽(24)
  • 哈工大 2022春 模式識別與深度學(xué)習(xí) 期末試題

    雖然此課程未開卷考試,但往年題還是很有參考價值的,就像今年的題和2021年就有很多到相似的題。但考的知識點(diǎn)肯定比題多,考試前還是需要把PPT都過一遍的。 已知條件概率和先驗(yàn)概率,求基于最小錯誤率的貝葉斯分類器 如果你有一個朋友在外地…(HMM PPT上的原題改很少

    2024年02月09日
    瀏覽(22)
  • 2023哈工大軟件工程考研 | 395+251 | 個人經(jīng)驗(yàn)分享

    2023哈工大軟件工程考研 | 395+251 | 個人經(jīng)驗(yàn)分享

    初試成績 :395 政治 英語一 數(shù)學(xué)一 專業(yè)課 總分 71 76 130 118 395 復(fù)試成績 :251(綜合測試118 + 面試133) 排名 :軟專1/12,本部7/83,一校三區(qū)33/262 一切都拉下帷幕了,從去年二月到今年三月,已經(jīng)一年多了;中間有大起大落,有艱難曲折,但最終還算有個不錯的結(jié)果。 沒有感

    2023年04月09日
    瀏覽(33)
  • 哈工大計算機(jī)網(wǎng)絡(luò)傳輸層協(xié)議詳解之:TCP協(xié)議

    哈工大計算機(jī)網(wǎng)絡(luò)傳輸層協(xié)議詳解之:TCP協(xié)議

    哈工大計算機(jī)網(wǎng)絡(luò)課程傳輸層協(xié)議詳解之:可靠數(shù)據(jù)傳輸?shù)幕驹?哈工大計算機(jī)網(wǎng)絡(luò)課程傳輸層協(xié)議詳解之:流水線機(jī)制與滑動窗口協(xié)議 哈工大計算機(jī)網(wǎng)絡(luò)課程傳輸層協(xié)議詳解之:擁塞控制原理剖析 點(diǎn)對點(diǎn)通信 一個發(fā)送方、一個接收方 可靠的、按序的字節(jié)流 流水線機(jī)制

    2024年02月10日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包