看板 C_and_CPP 關於我們 聯絡資訊
hi,hi 感謝各位之前熱情的回覆讓我學到用binary方式寫檔案 我才發現原來binary的方式這麼好用 小的我有另外的問題想請教大家 在做流體計算時繁複的計算我都是丟到GPU上計算 計算的效率幾乎都是2TLOPs以上,可以發揮到顯示卡計算能力極限的70%左右 (以GTX680為例2 FLOPS/Clock × 1006 MHz × 1536 = 3.090 TFLOPS) 但是同樣的計算放到CPU上都<10GFLOPs,幾乎不到CPU計算能力極限的10% (以Ivy Bridge為例 8 FLOPS/Clock × 3.5GHz ×4 = 102.4 GFLOPS ) 乍看之下GPU好像加速幾乎上百上千倍的計算速度但其實CPU根本沒發揮真本事 在GPU的情況編譯器會把乘加合併成一條指令去做才能做到2 FLOPS/Clock 那在CPU的部分要啟用SSE指令集或AVX指令集的話是要自己去編寫嗎?還是編譯器會做? 因為我在VC2010 中加入/arch:AVX之類的指令但速度並沒有增加 我這邊做的事情基本上就是迭代計算 vector<vector<double> > V, VNew ,rho; void Jacobi() { #pragma omp parallel for for (int i = 1; i <= L; i++) #pragma omp parallel for for (int j = 1; j <= L; j++) VNew[i][j] = 0.25 * (V[i - 1][j] + V[i + 1][j] + V[i][j - 1] + V[i][j + 1] + h * h * rho[i][j]); } -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 1.170.79.135
GNUGCC:如果可以的話,以 Debug 啟動反組譯並且修改相對的組合語言 08/14 23:27
GNUGCC:碼,必竟編譯器產生的組合語言碼有部份是可以做最佳化使效率 08/14 23:29
GNUGCC:提升. 08/14 23:29
littleshan:這code看起來關鍵反而是cache 08/14 23:30
littleshan:像 V[i-1][j] 與 V[i+1][j] 這種很傷 CPU cache 的效能 08/14 23:31
littleshan:因為換算成一維的位址會差很遠,一般情況容易miss 08/14 23:34
littleshan:但GPU的cache會考慮二維甚至三維的情況 08/14 23:34
littleshan:在這方面的效能會比CPU快很多 08/14 23:35
GNUGCC:如果只處理小型資料的話可以儘量不用 vector<> 而改以內建 08/14 23:39
littleshan:vector根本沒差好嗎 08/14 23:39
littleshan:若在 CPU 上要加速,首先不要用一列一列的方式處理 08/14 23:40
GNUGCC:陣列方式,因為每呼叫一次 operator[] 與 operator +() CPU 08/14 23:40
littleshan:改用以 block 為單位 (比如 8x8) 加強 cache coherence 08/14 23:41
GNUGCC:就必需花時間計算使用與返回的堆疊空間,可以從組合語言程式 08/14 23:43
GNUGCC:看出. 08/14 23:44
littleshan:然後若要利用到SSE,在這例子中要把內層迴圈拆開 08/14 23:52
可以給點示範嗎?拆掉內層迴圈無所謂 ※ 編輯: Lepton 來自: 1.170.79.135 (08/14 23:56)
purincess:cache miss panelty比改動esp/ebp及branch miss所要花的 08/14 23:57
purincess:cycle大太多了 先如l大考慮cache會比較好 08/14 23:57
purincess: branch prediction miss^ 08/15 00:00
hi,我知道在GPU也有cache的問題但在CPU上要怎樣處理這個問題我不熟悉 請問可以給點參考資料嗎?我先google研究看看不懂再來提問好了 ※ 編輯: Lepton 來自: 1.170.79.135 (08/15 00:02)
purincess:你先參考 matrix multiplication 對 cache locality 08/15 00:05
purincess:的最佳化的一些作法和原因 可以得到一些靈感~ 08/15 00:05
azureblaze:operator[]都inline掉了沒人在返回堆疊的啦 08/15 00:32
azureblaze:最佳化開下去vector存取跟陣列一模一樣 08/15 00:33
GNUGCC:這裡的例子使用 vector<> 但沒使用到如 insert() 或是 08/15 00:42
GNUGCC:push_back() 類似的演算法函式,只單純做四則運算,這裡看到 08/15 00:43
GNUGCC:用了 operator+(), operator[](), operator*(),那為什麼不 08/15 00:46
GNUGCC:用內建的四則運算功能呢?CPU 在呼叫這些函式都需要成本考量 08/15 00:47
littleshan:它只會呼叫operator[]() 我想你是看錯了某些地方 08/15 00:50
azureblaze:http://ideone.com/r5BfvV operator[]也沒有真的叫下去 08/15 00:54
azureblaze:真的要說就是ctor效率差和unroll等最佳化做的比較不好 08/15 00:55
QQ這邊大家討論的東西好深奧我都不懂!看來我C/C++沒學好 ※ 編輯: Lepton 來自: 111.252.0.105 (08/15 01:00)
GNUGCC:哈~對不起這裡只會呼叫 operator[]() 08/15 01:13
GNUGCC:以 azureblaze 提供的組合語言碼,可以看到呼叫建構子時 CPU 08/15 01:14
GNUGCC:初使化的暫存器,然後又呼叫建構物件的函式,又是一個負擔, 08/15 01:17
GNUGCC:這些都是 CPU 在呼叫這些函式所花費的成本,如果這裡用了內 08/15 01:20
GNUGCC:建陣列的話完全不需要這些動作,而且執行檔會相對的較小. 08/15 01:21
littleshan:azureblaze你沒開最佳化對不對XD 我的連ctor都inline了 08/15 01:47
littleshan:不過也對啦 內建陣列有時候可以幫你省下delete的時間 08/15 01:53
littleshan:因為忘了呼叫嘛 XDDDDDDDDDDD 08/15 01:53
azureblaze:MSVC12好像沒最佳化那邊 08/15 02:08
bigpigbigpig:何必算上下左右座標,直接平移好位置,四片直接加, 08/15 06:08
bigpigbigpig:根本不需要計算下標及浪費時間存取,也不需要cache 08/15 06:09
GNUGCC:我覺得如果真的要最佳化,為什麼不自已來做呢? 08/15 08:43
GNUGCC:用了內建陣列就是最佳化的方法,而且也省下了配置記憶體花費 08/15 08:46
GNUGCC:的時間. 08/15 08:46
littleshan:以這例子來說轉置90度也算是個好方法了 08/15 10:45
littleshan:至於平移....我想不出有什麼不用計算下標的平移方式耶 08/15 10:46
GNUGCC:如果真的要用 vector<>, 或許 vector<int> 的 operator[]() 08/15 11:06
GNUGCC:比 vector<vector<int>> 的還要有效率,必竟 inline 只是請 08/15 11:07
GNUGCC:求,編譯器會視情況使用. 08/15 11:09
andyjy12:這麼簡單的運算,容易卡在memory bandwidth 08/15 13:09
purincess:所以要盡量降低cache miss 08/15 16:42
wuliou:這邊已經是計算機組織的問題了 和語言其實關係比較小 08/15 23:07
wuliou:簡單的說就是如何最高效率的應用硬體減少多餘步驟 08/15 23:07