2014年(31)
分类: 嵌入式
2014-03-28 17:26:35
原文地址:最基本的C语言代码级别速度优化 作者:apple_guet
1、Short to int
描叙:在32位的程序中,使用int类型作循环体的索引变量比short类型具有更好的性能。循环体索引变量指 for (i=0; i<9; i++) 中的 i 。
背景:在32位的应用程序中使用short将导致机器码变长,同时处理器需要更长的时间处理;不仅如此,大多数编译器在未优化状况下对于short类型,总是将它转换成integer后再做各种操作,操作完后再转换为short类型,增加了一些不必要的操作。
原始代码:
unsigned short i;
for (i=0; i
{
DoSomething();
}
优化代码:
unsigned int j;
for (j=0; j
{
DoSomething();
}
2、Pointers to register
描叙:在循环体中尽量少使用指针间接寻址,可以采取一些迂回的方法,如果可能的话,先将间接寻址的内容放在某个寄存器里面,在循环体内操作完后,再回送到指针所指的内存。
背景:间接寻址将导致至少两次以上的内存操作,这是其一。其二,由于间接寻址使得指令具有前后的依赖性(只有先获得地址才能够做取内存内容的操作),编译器的优化能力将被降低,同时对处理器中流水线的乱序,调度和指令配对也会有一定的影响。
原始代码:
int i, j = 0, *a = &j;
for (i=0; i
{
*a += i;
}
优化代码:
int i, j = 0, *a = &j;
register int temp;
temp = *a;
for (i=0; i
{
temp += i;
}
*a = temp;
3、Move if statement out of loop core
描叙:如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。
背景:参考下面的代码可以看到,在原始代码中要多执行N-1次逻辑判断,而且循环影响了处理器中流水线原有的次序,降低了效率。
原始代码:
for (i=0; i
{
if (condition)
DoSomething();
else
DoOtherthing();
}
优化代码:
if (condition)
{
for (i=0; i
DoSomething();
}
else
{
for (i=0; i
DoOtherthing();
}
4、Use library
描叙:如果你要实现功能在库函数里面可以找到,那么你如果还不是高高手的话,用库函数吧。
背景:库函数一般针对你的操作系统做了大量的优化,其性能是一般代码不可比拟的。比如下面的代码中,同样的内存拷贝,性能可能相差上十倍。
原始代码:
unsigned char output[N], input[N];
for (i = 0; i < N; i++)
{
output[i] = input[i];
}
优化代码:
unsigned char output[N], input[N];
memcpy(output, input, N);
性能比较:性能将提高若干倍
5、Division to multiplication
描叙:将一个循环体内部的浮点除法操作,改成浮点乘法,或许有意想不到的效果。
背景:浮点数的除法比乘法要慢得多;如果是整数的乘法和除法是没有任何差异的,但是在适当地时候可以使用移位操作来提高效率,比如说将num乘以16的操作变为num<<4可以取得更好的效果,同理可应用于除法和求余,除法使用右移操作,求余使用%操作都可以取得不错的效果,至少在新版本的linux内核中已经在除法和求余操作上做了大量的改进。
原始代码:
int i;
double j;
for (i=0; i<0xffffff; i++)
{
j = (double)i / 3.3;
}
优化代码:
int i;
double j, k;
k = (double)1.0 / 3.3;
for (i=0; i<0xffffff; i++)
{
j = (double)i * k;
}
性能比较:局部速度大约提升85%
6、For statement
描叙:在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU 跨界循环层的次数。
背景:浮点数的除法比乘法要慢得多,如果是整数的乘法和除法是没有任何差异的,但是在适当地时候可以使用移位操作来提高效率。
原始代码:
int i;
double j;
for (i=0; i<0xffffff; i++)
{
j = (double)i / 3.3;
}
优化代码:
int i;
double j, k;
k = (double)1.0 / 3.3;
for (i=0; i<0xffffff; i++)
{
j = (double)i * k;
}
性能比较:局部速度大约提升85%