软件方法的指令级并行——基本块内的指令级并行

5.2 软件方法的指令级并行——基本块内的指令级并行

基本块是指一段顺序执行的代码,除了入口处没有其他转入分支,除了出口处没有其他转出分支

考虑一下C语言代码:

for (i = 1; i <= 1000; i++) {
    x[i] = x[i] + s;
}

基本块对应的汇编程序为:

Loop:   LD      F0,0(R1)
        ADDD    F4,F0,F2
        SD      0(R1),F4
        DADDI   R1,R1,#-8
        BNEZ    R1,Loop

遵循以下指令延迟规定:

这里写图片描述

那么可以直接分析基本块汇编程序的指令周期延迟(共9个周期):

1Loop:  LD      F0,0(R1)
2       <stall>
3       ADDD    F4,F0,F2
4       <stall>
5       <stall>
6       SD      0(R1),F4
7       DADDI   R1,R1,#-8
8       <stall>
9       BNEZ    R1,Loop

5.2.1 静态调度

静态调度是指通过改变指令顺序而不改变指令间数据相关来改善指令延迟,把上述R1的递减改到前面并利用延迟槽技术(设置延迟槽为1)可以让上述基本快代码压缩到6个周期完成:

1Loop:  LD      F0,0(R1)
2       DADDI   R1,R1,#-8
3       ADDD    F4,F0,F2
4       <stall>
5       BNEZ    R1,Loop
6       SD      8(R1),F4

说明:

  • DADDI让R1递减提前,那么SD中存储位置是R1+8而不是R1
  • 延迟槽是无论分支是否成功都要执行的指令

5.2.2 循环展开

静态调度能够大幅提升基本快执行效率(50%),但是还有一个周期的停顿不能消除,那么由此引入另一种块内消除延迟方法——循环展开

循环展开是将循环中多个基本块展开成一个基本块从而填充stall间隙的方法

将上段基本块做4段展开,并做调度:

1Loop:  LD      F0,0(R1)
2       LD      F6,-8(R1)
3       LD      F10,-16(R1)
4       LD      F14,-24(R1)
5       ADDD    F4,F0,F2
6       ADDD    F8,F6,F2
7       ADDD    F12,F10,F2
8       ADDD    F16,F14,F2
9       SD      0(R1),F4
10      SD      -8(R1),F8
11      DADDI   R1,R1,#-32
12      SD      16(R1),F12
13      BNEZ    R1,Loop
14      SD      8(R1),F16

平均每个次循环仅需要14/4=3.5个cycle,性能大幅增加!

参考文章:循环级并行性概念 - CSDN

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值