Blackfin C语言优化
[09-12 18:28:20] 来源:http://www.88dzw.com EDA/PLD 阅读:8523次
文章摘要:在优化开关没有打开的情况下,编译器对C代码的处理是一一对应的直译,就是把C代码一句一句按照先后顺序翻译为相应的一条或者多条汇编语句。在直译的同时,编译器也会注意到对中间变量和中间结果的保护——不管他们接下来会不会被用到,他们都会被写入存储器,尽管这样做会增加很多冗余。经过这样的直译,一段C代码对应的汇编代码可能是多一个数量级的。一个典型的例子是,只有两条乘累加指令的for循环代码对应的汇编代码是几十条之多。可想而知,这样不经优化的代码执行速度是很慢的。一个参考数据是打开优化开关以后的代码运行速度平均可以提高20倍。也就是说,一个600MHz的芯片,不打开优化,相当于主频降到30MHz。所以绝大
Blackfin C语言优化,标签:eda技术,eda技术实用教程,http://www.88dzw.com在优化开关没有打开的情况下,编译器对C代码的处理是一一对应的直译,就是把C代码一句一句按照先后顺序翻译为相应的一条或者多条汇编语句。在直译的同时,编译器也会注意到对中间变量和中间结果的保护——不管他们接下来会不会被用到,他们都会被写入存储器,尽管这样做会增加很多冗余。经过这样的直译,一段C代码对应的汇编代码可能是多一个数量级的。一个典型的例子是,只有两条乘累加指令的for循环代码对应的汇编代码是几十条之多。可想而知,这样不经优化的代码执行速度是很慢的。一个参考数据是打开优化开关以后的代码运行速度平均可以提高20倍。也就是说,一个600MHz的芯片,不打开优化,相当于主频降到30MHz。所以绝大多数情况下我们要打开编译器的优化开关。
编译器的第二步走,就是对直译产生的代码进行优化,这个过程就是充分利用DSP的硬件实现指令和事件最大可能并行的过程。这里的并行既有运算单元本身的并行也有运算单元和其他功能单元的并行。以Blackfin为例,每一个core里都有两个乘法器和加法器。编译器在优化的时候第一个层次的并行是运算的并行,就是尽可能同时使用两个运算单元,做乘法就尽可能做到两个乘法器同时运算,做加法就尽可能做到两个加法器同时运算。接下来一个层次的并行是指令的并行,就是运算单元和memory存取、或者其他功能单元之间的并行,仍以Blackfin为例,在同一个cycle中,可以有两个乘累加和两个数据的存或取并发执行。这些并行都是DSP硬件本身支持的,编译器优化的工作就是充分利用DSP的硬件能力。
循环是编译器在第二步走的过程中重点处理的对象。这比较好理解,因为那些大量消耗cycle的代码往往是在循环当中的。下面我就结合编译器对循环的处理,来看看在优化的过程中程序员要怎么和编译器并肩战斗。编译器对循环处理的目标就是希望在每一次循环中尽可能的并行。为了实现这个目标,编译器采取的措施就是不停的打开循环、降低循环次数,增加循环内的指令个数,提高指令之间并发的几率。举个例子,一个100次的循环中有一个乘累加,编译器打开循环,将循环次数降低一半,循环内每次就会出现两个乘累加,编译器就有可能安排Blackfin的两个乘累加单元同时运算,从而将执行的效率提高一倍,这个优化过程叫做矢量化(Vectorization)。如果这个循环中还有加法、减法、存数、取数,或者其他运算,编译器还会安排这些指令和乘累加并发,或者这些指令之间并发,这个优化的过程也是实现软件流水线的过程(Software Pipeline)——在优化后的代码中往往出现当前的运算和以往的存数或者未来的取数并行。编译器对循环的打开可能是多次的,直到编译器有足够的指令可以充分安排并发。
说到这里我们对这位睡在上铺的兄弟已经有一些了解了,那么程序员在这个优化的过程中应该做什么呢?这就要从矢量化和软件流水线受到的限制谈起。刚才提到在优化过程中编译器一个重要的操作就是打开循环,如果循环次数是2的N次方例如8,16,32…,编译器就可以很舒服的按照需要多次打开循环。但如果在上面的例子里循环次数是101,编译器是无法打开循环的,对这个循环的优化就不能有效的展开。这个时候就需要程序员做工作了:我们可以将循环里面的运算在循环外实现一次,让循环次数变为100,从而给编译器两次打开循环的机会(2x2x25)。矢量化和软件流水线对操作数的存放也是有要求的。首先,对memory中操作数读取和计算结果存放必须是顺序(地址递增或者递减)的,如果是乱序或者随机的,不管是运算的并行和是指令的并行都很难实现。我们在编写程序和对C程序进行优化的时候就要注意到尽可能安排数据访问的顺序性。其次,根据操作数的宽度,程序员还要注意保证数据的2字对齐或者4字对齐。这有助于在指令并行执行时对操作时的有效读取。程序员可以通过在定义数据(组)的时候用编译器提供的相应编译选项来实现数据的对齐。在进行矢量化和软件流水线的过程中往往要对程序执行的顺序做局部调整,这种调整对程序整体来说虽然是微调,但在某些情况下改变原始程序执行的顺序会影响到程序执行结果的正确性。最典型的情况就是运算的操作数和结果之间存在某种联系和依赖。比方说数组中靠后的成员数值取决于靠前的成员运算的结果,这意味着数组成员之间有依赖性,不独立,从而不能实现并行计算。这在for循环中经常体现为一个运算的两个操作数指针可能是指向同一个数组的不同位置。数据独立性是到目前位置我们看到影响客户C代码优化效率最严重的因素。
- 上一篇:FPGA上同步开关噪声的分析
《Blackfin C语言优化》相关文章
- › Blackfin C语言优化
- › Atmel推出ASK/FSK收发器评估工具包 Wireless BlackBird
- › ADI公司BLACKFIN处理器
- › Blackfin处理器低功耗设计
- 在百度中搜索相关文章:Blackfin C语言优化
- 在谷歌中搜索相关文章:Blackfin C语言优化
- 在soso中搜索相关文章:Blackfin C语言优化
- 在搜狗中搜索相关文章:Blackfin C语言优化