哈工大csapp-LAB3程序优化
實驗報告
實 驗(三)
題???? 目 ?????優(yōu)化??????? ???????
專?????? 業(yè) ???人工智能(未來技術)???
學 ?? 號 ???7203610716?????????????
班 ?? 級 ???20WJ102???????????????
學?????? 生 ???孫銘蔚???????????
指 導 教 師 ???劉宏偉???????????????
實 驗 地 點 ???G712?????????????
實 驗 日 期 ???2022.04.16?????????
計算學部
目? 錄
第1章 實驗基本信息....................................... - 3 -
1.1 實驗目的................................................... - 3 -
1.2 實驗環(huán)境與工具............................................. - 3 -
1.2.1 硬件環(huán)境............................................... - 3 -
1.2.2 軟件環(huán)境............................................... - 3 -
1.2.3 開發(fā)工具............................................... - 3 -
1.3 實驗預習................................................... - 3 -
第2章 實驗預習........................................... - 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)化實踐....................................... - 7 -
第5章 總結.............................................. - 8 -
5.1 請總結本次實驗的收獲....................................... - 8 -
5.2 請給出對本次實驗內容的建議................................. - 8 -
參考文獻................................................. - 9 -
第1章 實驗基本信息
1.1 實驗目的
-
- 理解程序優(yōu)化的10個維度
- 熟練利用工具進行程序的性能評價、瓶頸定位
- 掌握多種程序性能優(yōu)化的方法
- 熟練應用軟件、硬件等底層技術優(yōu)化程序性能
1.2 實驗環(huán)境與工具
1.2.1 硬件環(huán)境
硬件1概覽:
? 型號名稱: MacBook Air
? 型號標識符: MacBookAir10,1
? 芯片: Apple M1
? 核總數: 8(4性能和4能效)
? 內存: 8 GB
? 系統(tǒng)固件版本: 7429.81.3
? 操作系統(tǒng)加載程序版本: 7429.81.3
? 序列號(系統(tǒng)): C02H479LQ6L5
? 硬件UUID: B9297F28-81B7-5DB0-8760-89063F63E0E5
? 預置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 實驗預習
了解實驗的目的、實驗環(huán)境與軟硬件工具、實驗操作步驟,復習與實驗有關的理論知識。性能測試準確性的文獻查找,我了解到,流水線、超線程、超標量、向量、多核、GPU、多級CACHE、編譯優(yōu)化Ox、多進程、多線程等多種因素對程序性能均有綜合影響。
第2章 實驗預習
總分20分
2.1 程序優(yōu)化的十大方法(5分)
2.2性能優(yōu)化的方法概述(5分)
1.一般有用的優(yōu)化
2.面向編譯器的優(yōu)化
3.面向超標量CPU的優(yōu)化
4.面向向量CPU的優(yōu)化
5. CMOVxx等指令
6. 嵌入式匯編
7.面向編譯器的優(yōu)化
8.面向存儲器的優(yōu)化:
9.內存作為邏輯磁盤
10.多進程優(yōu)化
11.文件訪問優(yōu)化:帶Cache的文件訪問
12.并行計算:多線程優(yōu)化
13.網絡計算優(yōu)化
14.GPU編程、算法優(yōu)化
15.超級計算
2.3 Linux下性能測試的方法(5分)
2.4 Windows下性能測試的方法(5分)
1.在visual studio中使用調試工具:性能探測器:CPU、RAM、GPU
2.使用自己構造的函數測出程序運行時間,進而測試性能
第3章 性能優(yōu)化的方法
總分20分
逐條論述性能優(yōu)化方法名稱、原理、實現(xiàn)方案(至少10條)
3.1
1.一般有用的優(yōu)化
代碼移動
復雜指令簡化
公共子表達式
2.面向編譯器的優(yōu)化:障礙
函數副作用
內存別名
3.面向超標量CPU的優(yōu)化
流水線、超線程、多功能部件、分支預測投機執(zhí)行、亂序執(zhí)行、多核:分離的循環(huán)展開!
只有保持能夠執(zhí)行該操作的所有功能單元的流水線都是滿的,程序才能達到這個操作的吞吐量界限
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.內存作為邏輯磁盤:內存夠用的前提下。
10.多進程優(yōu)化
fork,每個進程負責各自的工作任務,通過mmap共享內存或磁盤等進行交互。
11.文件訪問優(yōu)化:帶Cache的文件訪問
12.并行計算:多線程優(yōu)化:第12章
13.網絡計算優(yōu)化:第11章、分布式計算、云計算
14.GPU編程、算法優(yōu)化
15.超級計算
?
第4章 性能優(yōu)化實踐
總分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;}} }程序的功能:
源程序功能是對給定的數組模擬圖像平滑算法,對數組的值進行更改
流程:任一點的顏色值為其上下左右4個點顏色的平均值,即: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),具有數據相關性。由于循環(huán)減少了分支預測失敗的可能性,同時增加了循環(huán)體內語句并發(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)的時候,每次可以使用更多變量參與運算,能使流水線更好地流。于是。我首先講邊緣數據存儲到數組B中。在主循環(huán)中,我設置的步長為8,我定義4個變量aft1和bef1,aft2和bef2,分別存儲8個原數據的第3、2、7、6個,每次循環(huán)更新img數組后,更新B數組。
這樣可以使硬件能讓流水線很好地運作,即使在少數情況下也只犧牲一點效率。
面向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;}}}說明:
由于數組在電腦中按行進行存儲,根據上課講過的命中和不命中的知識,通過書中知識可以知道,對于數組來說,一旦程序訪問了某個存儲單元,在不久之后,其附近的存儲單元也將被訪問,即程序在一段時間內所訪問的地址,可能集中在一定的范圍之內,這是因為指令通常是順序存放、順序執(zhí)行的,數據也一般是以向量、數組、表等形式簇聚存儲的。如果一個存儲器的位置被引用,那么將來他附近的位置也會被引用。如果其訪問順序和存儲順序一致,程序性能會提升很多。
面向Cache2(按行進行分塊):
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;}}}}說明:
根據csapp中所述,有一種有趣的技術叫做分塊,它可以改善內部循環(huán)的時間局部性。分塊的一般思想是將程序中的數據結構組織成稱為塊的大塊。(在這里,“塊”指的是應用程序級的數據塊,而不是緩存塊。)程序是結構化的,它將一個數據塊加載到L1緩存中,對該數據塊執(zhí)行所有需要的讀寫操作,然后丟棄該數據塊,加載下一個數據塊,以此類推。與用于改進空間局部性的簡單循環(huán)轉換不同,阻塞使代碼更難閱讀和理解。由于這個原因,它最適合優(yōu)化編譯器或頻繁執(zhí)行的庫例程。利用上述原理,我將數據按列分塊,我默認一個塊中有4個數據,進行試驗后發(fā)現(xiàn)性能提升不少。
面向Cache3(按列進行分塊):
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;}}}}說明:
根據csapp中所述,有一種有趣的技術叫做分塊,它可以改善內部循環(huán)的時間局部性。分塊的一般思想是將程序中的數據結構組織成稱為塊的大塊。(在這里,“塊”指的是應用程序級的數據塊,而不是緩存塊。)程序是結構化的,它將一個數據塊加載到L1緩存中,對該數據塊執(zhí)行所有需要的讀寫操作,然后丟棄該數據塊,加載下一個數據塊,以此類推。與用于改進空間局部性的簡單循環(huán)轉換不同,阻塞使代碼更難閱讀和理解。由于這個原因,它最適合優(yōu)化編譯器或頻繁執(zhí)行的庫例程。利用上述原理,我將數據按列分塊,我默認一個塊中有4個數據,進行試驗后發(fā)現(xiàn)性能提升不少。
面向Cache4(按正方形進行分塊):
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;}}}說明:
由于從效率上看,使用移位指令有更高的效率,因為移位指令占2個機器周期,而乘除法指令占4個機器周期。從硬件上看,移位對硬件更容易實現(xiàn),所以會用移位,左移一位就乘2,右移一位處以2,這種乘除法考慮移位實現(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語言中的庫函數測量程序開始到結束的時間,對各個優(yōu)化方法的時間進行比較,而且我每次運算后打印指定位置數據,發(fā)現(xiàn)均相同,證明程序沒出錯。
測試結果:
????? ??
圖1性能測試截圖
從測試結果可以看到,我采用的優(yōu)化方法確實提高了程序性能,減少了程序運行時間。
整理所有運行時間如下表:
表1:性能測試結果
| 采用方法描述 | 運行時間(s) |
| (初始狀態(tài),沒有進行任何優(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 |
| 按列對矩陣進行分塊(cache) | 0.80 |
| 按行對矩陣進行分塊(cache) | 0.77 |
| 按列對矩陣進行分塊+除法變成移位 | 0.52 |
| 按行對矩陣進行分塊+除法變成移位 | 0.47 |
| 分成4*4的塊(cache) | 0.42 |
4.4 結合自己計算機的硬件參數,分析優(yōu)化后程序的各個參數選擇依據。(15分)
我選擇結合自己計算機的硬件參數,分析優(yōu)化后程序的各個參數選擇依據。
首先我查看了自己電腦的L1、L2、L3緩存大小,如下圖所示:
對分塊進行優(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;}}}}}???????????????以下為程序運行結果:
說明:Cache的層次,一般有L1, L2, L3 (L是level的意思)的cache。通常來說L1,L2是集成 在CPU里面的(可以稱之為On-chip cache),而L3是放在CPU外面(可以稱之為Off-chip cache)。當然這個不是絕對的,不同CPU的做法可能會不太一樣。這里面應該還需要加上 register,雖然register不是cache,但是把數據放到register里面是能夠提高性能的??梢允褂脺p少D-cache miss的數量,增加有效的數據訪問的數量。這個要比I-cache優(yōu)化難一些。由于我的L1高速緩存大小為512KB,8核,所以一個核為64KB,由于long數據類型是8個字節(jié)。每個分塊的大小為128*128, 所以每個塊的miss次數是128。這樣總的miss率就是1*1922*1081/(4*128),如果分成4*4的塊,不命中率就會很高,經過實驗分成更大的塊,實驗效果不好,根據我電腦的參數,選擇128*128的塊比選擇其他參數效果更好。
對循環(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];}}}以下為運行結果:
說明:一個規(guī)律應當是被普遍認同的,那就是循環(huán)展開的程度越高,循環(huán)執(zhí)行開銷所占的比例就會越小。可是,根據實驗結果,循環(huán)展開4次的結果確實好于循環(huán)展開8次的結果,經過分析,可能是由于循環(huán)展開8次初始化過多變量,導致程序性能提升效果比循環(huán)展開4次的效果差。
4.5 還可以采取的進一步的優(yōu)化方案(5分)
正因為線程是調度的最小單位,控制好線程,也就相當于控制好了計算資源。
多線程與異步計算的關系密切,一般可以使用異步計算的,都可以用多線程來實現(xiàn),而多線程加速也依賴于異步計算,利用多線程來并行處理多個任務,提高計算資源的利用率,也可以對我們的程序進行優(yōu)化,從而提升程序性能。
程序代碼如下,可以直接運行調試:
#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),沒有進行任何優(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章 總結
5.1 請總結本次實驗的收獲
5.2 請給出對本次實驗內容的建議
實驗內容很好,就是某些問題描述不清,例如4.4題,沒有給出操作實例,可能導致很多學生不知道從何做起,希望能改進這一點,其余做的都很好。
注:本章為酌情加分項。
參考文獻
為完成本次實驗你翻閱的書籍與網站等
[1]? 林來興. 空間控制技術[M]. 北京:中國宇航出版社,1992:25-42.
[2]? 辛希孟. 信息技術與信息服務國際研討會論文集:A集[C]. 北京:中國科學出版社,1999.
[3]? 趙耀東. 新時代的工業(yè)工程師[M/OL]. 臺北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).
[4]? 諶穎. 空間交會控制理論與方法研究[D]. 哈爾濱:哈爾濱工業(yè)大學,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.
總結
以上是生活随笔為你收集整理的哈工大csapp-LAB3程序优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据挖掘:降低汽油精制过程中的辛烷值损失
- 下一篇: 记录Android开发中的问题及解决方法