看板 C_and_CPP 關於我們 聯絡資訊
我剛剛嘗試了一下 平台是 g++, openmp, core i5 2500, linux 64 首先 有人提到 vector 的問題 根據我的測試是這樣(無平行) L = 1000, 50 iteration g++ -O2 g++ -g vec of vec 0.124 1.600 2D array 0.128 0.124 應該是誤差 可見 compiler 很厲害的,只要你有叫他 optimize XDD 第二,我先用 int 來代替你的 double 我認為你的程式的迴圈只要拆外層,要不然會增加不必要的 overhead #... for for () #... for <<<這個不需要 for () 一律用 g++ -O2, 2000 iteration single thread 5.300 openmp 2.254 omp 拿掉內圈 1.815 你的程式應該沒有 local variable conflict 的問題,所以這部份不考慮 不過把 int 改成 double 的話速度變這樣 single thread 4.098 openmp 懶得編譯... omp 拿掉內圈 3.567 不會變快,我推論 CPU 的 float point ALU 資源是有上限的...... 我猜用 SSE 之類的應該也不會變好? 第三 cache 的問題我想應該還好,但我不確定,因為我也不是很熟 CPU 硬體 CPU 的 cache 我想是 multi-way 的 應該不會因為你同時讀兩個 row 就互相洗掉...... 附上程式 #include <vector> using namespace std; typedef int TT; typedef vector<vector<TT> > VVD; const TT h = 10.0; void Jacobi(const VVD &V, VVD &VNew, const VVD &rho, const int L) { #pragma omp parallel for for (int i = 1; i < L-1; i++) #pragma omp parallel for for (int j = 1; j < L-1; 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]); } void Jacobi_opt(const TT *V, TT *VNew, const TT *rho, const int L) { #pragma omp parallel for for (int i = 1; i < L-1; i++) #pragma omp parallel for for (int j = 1; j < L-1; j++) VNew[i*L+j] = 0.25 * (V[(i-1)*L+j] + V[(i+1)*L+j] + V[i*L+j-1] + V[i*L+j+1] + h * h * rho[i*L+j]); } int main() { int L = 1000; int N = 2000; VVD V_v(L); VVD Vnew_v(L); VVD rho_v(L); for (int i = 0; i < L; ++i) { V_v[i].reserve(L); Vnew_v[i].reserve(L); rho_v[i].reserve(L); for (int j = 0; j < L; ++j) { V_v[i][j] = rho_v[i][j] = i*L+j; } } TT *V_ptr = new TT[L*L]; TT *Vnew_ptr = new TT[L*L]; TT *rho_ptr = new TT[L*L]; for (int i = 0; i < L*L; ++i) { V_ptr[i] = rho_ptr[i] = i; } for (int i = 0; i < N; ++i) { if (i&1) { // Jacobi(Vnew_v, V_v, rho_v, L); Jacobi_opt(Vnew_ptr, V_ptr, rho_ptr, L); } else { // Jacobi(V_v, Vnew_v, rho_v, L); Jacobi_opt(V_ptr, Vnew_ptr, rho_ptr, L); } } delete[] V_ptr; delete[] Vnew_ptr; delete[] rho_ptr; return 0; } ※ 引述《Lepton (輕子)》之銘言: : 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]); : } -- Time waits for no one. ↑ (。A。)ハァ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.217.11
littleshan:先推一下實驗精神 08/15 23:56
b98901056:強強林必推 08/16 10:23