[分享] TI C6000 优化进阶:循环最重要!

Aguilera   2020-1-2 20:15 楼主

软件流水循环

1. C6000流水线(Pipeline)

一个指令的处理过程并不是一步完成,它被分为三个阶段:取指(Fetch)、译码(Decode)、执行(Excute)。将每一个阶段放入独立的流程车间处理,形成流水线式的处理过程,可以大大加快指令的处理速度。

如图1所示,流水编排后的3个指令只需5个cycle,相比顺序执行的9个cycle大大减少,当指令数增多,流水线的优势将更加明显。

image.png

图1 简单的流水线编排示意

 

实际上,C6000架构把每一个阶段进一步划分为多个子阶段,每个子阶段消耗1个CPU cycle。

取指(4个子阶段):

  • PG: Program address generate (update program counter register)

  • PS: Program address send (to memory)

  • PW: Program (memory) access ready wait

  • PR: Program fetch packet receive (fetch packet = eight 32-bit instructions)

译码(2个子阶段):

  • DP: Instruction dispatch (or assign, to the functional units)

  • DC: Instruction decode

执行(1-10个子阶段,指令间有区别):

  • E1 – E10, where E1 is the first sub stage in the execute stage

  image.png

图2 高性能的C6000流水线

 

2. 流水线阻塞

下列两种情况出现时,流水线将被阻塞:

  • 当前为load、complex multiply等具有多个延时时隙(delay slot)的指令时,下一指令需多个cycle,等其返回结果后才能往下继续执行

  • 跳转指令出现时,CPU无法预知下一步执行哪个分支指令,因此跳转目标指令需等到跳转指令执行到E1阶段才能进入流水线

为了充分利用流水线的资源,避免delay slots造成的阻塞,C6000架构在软件和硬件上分别新增了一个处理机制:

  • 软件上:提供软件流水(software pipelining)指令编排

  • 硬件上:提供SPLOOP buffer(software pipelining loop buffer)

 

3. 软件流水

软件流水≠流水线!

软件流水技术指编译器通过重新调整指令的位置,使得原本将发生阻塞的流水线得以充分利用,其重点在“软件”两字。

例如处理下面循环:

for(i=0; i<15; i++)

{

sum += tab;

}

传统指令流程(Solution1)和软件流水编排后的指令流程(Solution2)如图3所示:

 

image.png

图3 传统编排 Vs 软件流水编排

 

从图中看到,经过软件重新编排过的指令将不再发生流水线阻塞,提升运行效率的同时也不影响代码功能的实现。

解释下有关软件流水的三个名词:

  • 流水核(Kernel):流水线被充分利用的一段代码

  • 流水填充(Prolog):流水核之前的一段填充过程代码

  • 流水排空(Epilog):流水核之后的一段排空过程代码

 

4. SPLOOP Buffer

软件流水将会带来两个主要的缺点:汇编文件代码尺寸的增加并影响代码的中断属性。

SPLOOP Buffer的出现就是为了就解决以上问题。SPLOOP Buffer是C6000内部的一个存储区域,用来装载SPLOOP指令。当一个SPLOOP 第一次被执行时,循环的相关指令被拷贝到SPLOOP Buffer中,整个循环运行过程将从这里取指执行,直到循环结束。

C6000还为SPLOOP Buffer的使用提供了专门的寄存器和操作指令,如果编程者使用汇编/线性汇编编程,需要熟悉这些指令和寄存器,并了解SPLOOP Buffer特有的执行机制(参考文献[1]),如果使用C/C++编程则由编译器自动生成相应指令。

以存储块拷贝函数为例,示意使用SPLOOP Buffer前后的编码效果:

image.png

图4 memery copy 使用SPLOOP buffer前

image.png

 

图5 memery copy 使用SPLOOP buffer后

 

*注意:SPLOOP Buffer最多只能存放14个执行包(每个执行包可含8条指令,顺序/并行),因此如果循环体较复杂将不能使用SPLOOP Buffer。

 

5. 导致软件流水编排失败的因素

在CCS开发环境中,开启-O2/-O3优化选项,编译器将自动为合适的代码进行软件流水编排,因此编程者需要注意的是使设计的循环体符合软件流水编排的条件。

下列一些因素将可能引起软件流水编排失败:

  • 汇编语句嵌入到C/C++代码中

  • 出现复杂的流控制语句如goto、break等

  • 循环中包含一个调用(内嵌函数除外)

  • 需进行软件流水编排的指令太多

  • 没有初始化循环计数器

  • 循环变量在循环过程中被修改

  • 软件流水被关闭:没有使用-O2或-O3选项;使用了-ms2或-ms3选项;使用-mu关闭了软件流水

回复评论 (1)

很好的分享。

点赞  2020-1-3 13:34
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复