C語言 效能優化 === ###### tags: `Code` [TOC] --- ## 1. 提高系統clock - 藉由提升clock,以增加CPU與硬體的處理速度。例:220MHz -> 330MHz --- ## 2. 硬體運算代替CPU - 假設ISP chip設計硬體1Pixel/1T的執行速度,表示單位時間1T可以完成處理1 pixel的資料量。 - 那如果是由CPU來計算,CPU每次單位時間處理1 pixel做一個(加/減/乘/除)的運算,若假如影像處理的運算流程需有N次的(加/減/乘/除)運算,也就是說CPU需花費N倍的時間。 --- ## 3. 修改compiler參數 - ARC compile option: - "**-O6 -g0**" for fast speed - "**-Os -g0**" for small code size ```Bat= # Build.bat set CFGDIR=.\Build set CFGFILE=%CAMPROJDIR%\Build\config.mk %MAKELIB% %1 %2 %3 set CFGDIR= set CFGFILE= ``` --- ## 4. 查表法 ```C= // Old code: long factorial(int i) { if (i == 0) return 1; else return i * factorial(i - 1); } // New code static long factorial_table[] = {1, 1, 2, 6, 24, 120, 720 /* etc */}; long factorial(int i) { return factorial_table[i]; } ``` --- ## 5. 運用CPU特性 - ARC CPU的特性,一次存取32bit的資料量,因此我們的程式設計成每次處理32bit的資料的話,能夠充分利用CPU的效能。 - 如果將32bit的資料連續處理,compiler也會優化處理效能。 --- ## 6. 減少重複運算 - 程式碼中的重複運算部分,適時的利用變數暫存 ```C= // Old code for (i = 0; i < 600; i++) { for (j = 0; j < 300; j++) { if(i*5+10) // do something...; xx = i*5+10; } } // New code for (i = 0; i < 300; i++) { tmp = i*5+10; for (j = 0; j < 600; j++) { if(tmp) // do something...; xx = tmp; } } ``` --- ## 7. 展開Loop,以減少loop次數 - 原本的for loop需要執行101次,新的做法僅需要執行11次 ```C= // Old code for (i = 0; i < 100; i++) { do_stuff(i); } // New code for (i = 0; i < 100; ) { do_stuff(i); i++; do_stuff(i); i++; do_stuff(i); i++; do_stuff(i); i++; do_stuff(i); i++; do_stuff(i); i++; do_stuff(i); i++; do_stuff(i); i++; do_stuff(i); i++; do_stuff(i); i++; } ``` --- ## 8. 運算子優化,降低CPU負擔 ```C= // Old code x = w % 8; y = pow(x, 2.0); z = y * 33; for (i = 0; i < MAX; i++) { h = 14 * i; printf("%d", h); } // New code x = w & 7; /* bit-and cheaper than remainder */ y = x * x; /* mult is cheaper than power-of */ z = (y << 5) + y; /* shift & add cheaper than mult */ for (i = h = 0; i < MAX; i++) { printf("%d", h); h += 14; /* addition cheaper than mult */ } ``` --- ## 9. 簡化常數運算 ```C= // Old code for(j=0; j<uwHeigh; j++) { udAddr = udSrcAddr + ((j-1) * (360 / 2) ) // do something... } // New code for(j=0; j<uwHeigh; j++) { udAddr = udSrcAddr + ((j-1) * 180) // do something... } ``` --- ## 10. 數學方法優化 ```C= // Old code sum = 0; for (i = 1; i <= 100; i++) sum = sum + i; // New code N = 100; sum = (1+N) * N / 2; ``` --- ## 11. 減少loop裡的判斷式 ```C= // Old code for (i = 0; i < 10000; i++) { if (condition) do something...; else do something...; } // New code if (condition) { for (i = 0; i < 10000; i++) do something...; } else { for (i = 0; i < 10000; i++) do something...; } ``` --- ## 12. 配合Compiler的特性 ```C= // 例子一: // Old code float a, b, c, d, f, g; ... a = b / c * d; f = b * g / c; // New code float a, b, c, d, f, g; ... a = b / c * d; f = b / c * g; // 例子二: // Old code total = a->b->c[4]->aardvark + a->b->c[4]->baboon + a->b->c[4]->cheetah + a->b->c[4]->dog; // New code struct animals * temp = a->b->c[4]; total = temp->aardvark + temp->baboon + temp->cheetah + temp->dog; ``` --- ## 12. 融合演算法,減少Loop次數 - 如果有兩個演算法都要執行相同的Loop次數,請將這兩種演算法想辦法在相同迴圈中完成。 --- ## 13. C to Assembly code --- ## 14. 改變演算法 --- Reference === http://icps.u-strasbg.fr/~bastoul/local_copies/lee.html https://itw01.com/8P9EA6F.html https://www.itread01.com/content/1549260577.html http://stenlyho.blogspot.com/2007/04/c.html https://blog.csdn.net/ce123_zhouwei/article/details/17226977
{"metaMigratedAt":"2023-06-15T00:05:46.530Z","metaMigratedFrom":"Content","title":"C語言 效能優化","breaks":true,"contributors":"[{\"id\":\"e5d9e61d-dabc-4e0a-861b-bddaf7bcff09\",\"add\":4670,\"del\":941}]"}
    526 views