新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 高效率嵌入式程序开发技巧

高效率嵌入式程序开发技巧

作者: 时间:2009-07-20 来源:网络 收藏

通常,工程师总是竭力避免使用冗余变量,以精简程序。一般情况下这样做是正确的,但是也有例外,如下所示:
int f(void);
int g(void);
file://f()和g()不访问全局变量errs
int errs; file://全局变量
void test1(void)
{ errs += f();
errs += g();
}
void test2(void)
{ int localerrs = errs;
// 定义冗余的局部变量
localerrs += f();
localerrs += g();
errs = localerrs;
}
在第一种情况test1()里,每次访问全局变量errs时都要先从相应的存储器下载到寄存器里,经f()或g()函数调用后再存储回原来的存储器里面。在该例子中,一共要进行两次这样的下载/存储操作。而在第二种情况test2()里,局部变量localerrs被分配以寄存器,这样一来,整个函数就只需要一次下载/存储全局变量存储器了。尽量节省存储器访问的次数,对于提高系统性能非常有用。

循环程序的处理
计数循环是程序中常用的流程控制结构。在C中,类似下面的for循环比比皆是:
for(loop=1;loop=limit;loop++)

这种累加计数的方法符合一般的自然思维习惯,所以比下面的递减计数方法使用更多:
for(loop=limit;loop!=0; loop--)
这两者在逻辑上并没有效率差异,但是映射到具体的体系结构中,就产生了很大的不同。

累加法比递减法多用了一条指令,当循环次数比较多的时候,这两段代码就会在性能上产生明显的差异。分析其本质原因,在于当进行一个非零常数比较时,必须用专门的CMP指令来执行;而当一个变量与零进行比较时,ARM指令可以直接利用条件执行的特性(NE)来进行判断。很多时候循环展开由编译器自动完成,不过应注意对中间变量或结果被更改的循环,编译程序往往拒绝展开,这时候就需要工程师自己来做展开工作了。

尤其值得注意的是,在有内部指令cache的CPU上(如ARM946ES芯片),因为循环展开的代码很大,往往会出现高速缓冲存储器溢出。这时展开的代码会频繁地在CPU的高速缓冲存储器和内存之间来回调用,又因为高速缓冲存储器速度很高,所以此时循环展开反而会变慢。同时,循环展开会影响矢量运算优化。

ARM处理器核对NZ(零比较转移)有特别的指令处理,速度非常快,如果你的循环对方向不敏感,可以由大向小循环。需要注意的是,如果指针操作使用了i值,这种方法可能引起指针索引超界的严重错误(i = MAX+1)。当然你可以通过对i做加减运算来纠正,但是如果这样就没有提的作用了。

结语
本文对ARM总结了一些编程。在实际的系统开发中,可以大大的提高系统的性能,特别是在多媒体和通信等复杂度高的应用中,对程序设计具有指导意义。

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

上一页 1 2 下一页

评论


相关推荐

技术专区

关闭