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}]"}