Re: [問題] For迴圈 和 array 執行速度問題

看板C_and_CPP作者 (艾斯寇德)時間13年前 (2010/10/24 14:24), 編輯推噓1(106)
留言7則, 4人參與, 最新討論串3/4 (看更多)
我想這跟我的platform有關,使用long long總是比較慢 problem size (20000*20000) 不使用最佳化______________________________________________ start loop1 (雙層int32迴圈) loop1 time: 1.685480 sec,dummy=400000000 start loop1_longlong (雙層int64迴圈) 在型別相同的前提下跟loop2比較 loop1_longlong time: 3.018724 sec,dummy=400000000 start loop2(400000000) (一個int64迴圈) loop2 time: 2.990198 sec,dummy=400000000 start loop2_unroll(400000000) (同上,加上人工unroll) loop2_unroll time: 2.586034 sec,dummy=400000000 最佳化參數 -O __________________________________________ start loop1 loop1 time: 0.000047 sec,dummy=400000000 start loop1_longlong loop1_longlong time: 0.000041 sec,dummy=400000000 start loop2(400000000) loop2 time: 0.000004 sec,dummy=400000000 start loop2_unroll(400000000) loop2_unroll time: 0.542240 sec,dummy=400000000 以下是cat /proc/cpuinfo ______________________________________ processor : 0 vendor_id : AuthenticAMD cpu family : 15 model : 44 model name : AMD Sempron(tm) Processor 2800+ stepping : 2 cpu MHz : 1599.983 cache size : 256 KB cpuid level : 1 [中間省略] wp : yes bogomips : 3199.96 clflush size : 64 cache_alignment : 64 address sizes : 40 bits physical, 48 bits virtual power management: ts ttp tm stc OS: Linux sunneo-desktop 2.6.32-25-generic #45-Ubuntu SMP # 沒有SMP的SMP OS ... Orz GCC: gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 以下是程式碼 -------------------------------------------------------- #include <sys/time.h> #include <stdio.h> static double getTime(){ struct timeval tv; gettimeofday(&tv,0); return tv.tv_sec+((double)1e-6*tv.tv_usec); } void loop1(int maxidx){ int i; int j; int dummy = 0; double tmstart = getTime(); printf("start loop1\n"); for(i=0; i<maxidx; ++i){ for(j=0; j<maxidx; ++j){ ++dummy; } } printf("loop1 time: %lf sec,dummy=%d\n",getTime()-tmstart,dummy); } void loop1_longlong(int maxidx){ long long i; long long j; long long maxIDX = maxidx; int dummy = 0; double tmstart = getTime(); printf("start loop1\n"); for(i=0; i<maxIDX; ++i){ for(j=0; j<maxIDX; ++j){ ++dummy; } } printf("loop1 time: %lf sec,dummy=%d\n",getTime()-tmstart,dummy); } void loop2(int maxidx){ long long i; int dummy = 0; long long maxIDX = maxidx; maxIDX *= maxidx; double tmstart = getTime(); printf("start loop2(%lld)\n",maxIDX); for(i=0; i<maxIDX; ++i){ ++dummy; } printf("loop2 time: %lf sec,dummy=%d\n",getTime()-tmstart,dummy); } void loop2_unroll(int maxidx,int unroll_size){ long long i; long long unroll_ll = unroll_size; int dummy = 0; long long maxIDX = maxidx; maxIDX *= maxidx; double tmstart = getTime(); printf("start loop2_unroll(%lld)\n",maxIDX); i = maxIDX-1; while( i > 0ll){ switch(i%unroll_ll){ case 63: ++dummy; --i; case 62: ++dummy; --i; case 61: ++dummy; --i; case 60: ++dummy; --i; case 59: ++dummy; --i; case 58: ++dummy; --i; case 57: ++dummy; --i; case 56: ++dummy; --i; case 55: ++dummy; --i; case 54: ++dummy; --i; case 53: ++dummy; --i; case 52: ++dummy; --i; case 51: ++dummy; --i; case 50: ++dummy; --i; case 49: ++dummy; --i; case 48: ++dummy; --i; case 47: ++dummy; --i; case 46: ++dummy; --i; case 45: ++dummy; --i; case 44: ++dummy; --i; case 43: ++dummy; --i; case 42: ++dummy; --i; case 41: ++dummy; --i; case 40: ++dummy; --i; case 39: ++dummy; --i; case 38: ++dummy; --i; case 37: ++dummy; --i; case 36: ++dummy; --i; case 35: ++dummy; --i; case 34: ++dummy; --i; case 33: ++dummy; --i; case 32: ++dummy; --i; case 31: ++dummy; --i; case 30: ++dummy; --i; case 29: ++dummy; --i; case 28: ++dummy; --i; case 27: ++dummy; --i; case 26: ++dummy; --i; case 25: ++dummy; --i; case 24: ++dummy; --i; case 23: ++dummy; --i; case 22: ++dummy; --i; case 21: ++dummy; --i; case 20: ++dummy; --i; case 19: ++dummy; --i; case 18: ++dummy; --i; case 17: ++dummy; --i; case 16: ++dummy; --i; case 15: ++dummy; --i; case 14: ++dummy; --i; case 13: ++dummy; --i; case 12: ++dummy; --i; case 11: ++dummy; --i; case 10: ++dummy; --i; case 9: ++dummy; --i; case 8: ++dummy; --i; case 7: ++dummy; --i; case 6: ++dummy; --i; case 5: ++dummy; --i; case 4: ++dummy; --i; case 3: ++dummy; --i; case 2: ++dummy; --i; case 1: ++dummy; --i; case 0: ++dummy; --i; } } printf("loop2_unroll time: %lf sec,dummy=%d\n",getTime()-tmstart,dummy); } 我只是來賺p幣 ※ 引述《MasterChang (我愛ASM)》之銘言: : 來個隨便的測試 : 2.Process returned 0 (0x0) execution time : 3.969 s : int m = 100000, n = 100000, index = 0, i ,j; : for(i=0;i<m*n;i++) : { : index++; : } : 1.Process returned 0 (0x0) execution time : 26.813 s : for(i=0;i<m;i++) : for(j=0;j<n;j++) : { : index++; : } : case 2 比 case 1 快6.75倍。 : 不過用哪種?看程式規模和代碼是不是「熱點」來決定,如果規模小,又 : 不是熱點段落。這種事就別計較了。 : ※ 引述《genghiskii (SaoAn)》之銘言: : : 大家好 小弟我有些觀念不是很清楚想請教大家 : : 1. : : for(i=0;i<m;i++) : : for(j=0;j<n;j++) : : { : : //do something : : } : : 2. : : for(i=0;i<m*n;i++) : : { : : //do something : : } : : 有個同學跟我說2跑的會比1快,請問這是為什麼呢? 不是都是跑了m*n次? : : 另外還有個類似的問題 : : 3. : : for(i=0;i<m;i++) : : for(j=0;j<n;j++) : : { : : array_2D[i][j]=some operation; : : } : : 4. : : for(i=0;i<m;i++) : : for(j=0;j<n;j++) : : { : : array_1D[i*m+j]=some operation; : : } : : 那個同學又跟我說4比3快,但是大小一樣,只有2D跟1D的差別,請問他說的是對的嗎? : : 我原以為速度上1=2, 3=4, 但是被他這麼一說我有點被搞混了 : : 煩請各位解答 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.35.210.65

10/24 14:26, , 1F
可以用objdump -d 看看-O 之後的差異
10/24 14:26, 1F

10/24 14:32, , 2F
這種問題很有趣。有什麼地方可以應用呢?
10/24 14:32, 2F

10/24 14:38, , 3F
閒來無事想打發時間的時候可以用XD
10/24 14:38, 3F

10/24 14:43, , 4F
在程式具有多個版本 要進行排程時可以先使用組語來評估
10/24 14:43, 4F

10/24 15:33, , 5F
差異。
10/24 15:33, 5F

10/24 22:10, , 6F
由門催到底發現還是太慢 就會用到了 不過還是以asm最準
10/24 22:10, 6F

10/24 22:12, , 7F
用跑的畢竟是測試結果 可以觀察效能表現 但不保證一定對
10/24 22:12, 7F
文章代碼(AID): #1Cmz4F2m (C_and_CPP)
文章代碼(AID): #1Cmz4F2m (C_and_CPP)