本帖最后由 la45088d1 于 2020-4-12 22:22 编辑
所以一切的一切不仅让我深思到底怎么做才是最好的呢?在今天之前我对Coretx-M3的偏见就是,跳转总是3个周期,分支指令失败总是1个周期,并可能带有流水线停顿的情况,在这个偏见下,对于两段一样的代码:
1:
CMP Rx,#0x00
ITT EQ
OP1EQ Ry, Rz
OP2EQ Rm, Rn
OP3 Ra,Rb
......
2:
CBNZ Rx,Lable
OP1 Ry, Rz
OP2 Rm, Rn
Lable OP Ra,Rb
......
那么,从条件块到第3条普通指令,代码段1的执行时间无论条件成立与否总是1+2=3周期;对于代码段2,条件为假时执行周期是3,条件为真时是1+1+1=3,当真假条件概率无论如何时将得到两段代码时间一样的错误结论。而根据今天的发现我们对上述结论进行修正,代码段1的执行时间是1+1+2=4周期,无论条件成立与否;对于代码段2,条件为假时执行周期是1,条件为真时是1+1+1=3。当真假概率一致时,代码段1的平均周期是4,代码段2的平均周期是2!是不是大跌眼镜啊?分支跳转居然击败了条件执行??我们知道对于IT指令最大可以捆绑4条常规指令,所以对于代码段1的风格来说,随着条件指令越多,执行时间越长,这个时候还不如直接跳过无用的指令更好!
那么,对于不可用CBZ/CBNZ的场合呢?请看如下两段代码:
1:
CMP Rx,#imn
ITT HI
OP1HI Ry, Rz
OP2HI Rm, Rn
OP3HI Ra,Rb
OP4LS Rc,Rd
POP {Ra-Rd,Rn}
2:
CMP Rx,#imn
BLS Lable
OP1 Ry, Rz
OP2 Rm, Rn
Lable OP4 Rc,Rd
POP {Ra-Rd,Rn}
那么,从条件块到函数返回,代码段1的执行时间无论条件成立与否总是1+4=5周期;对于代码段2,条件为假时执行周期是5,条件为真时是1+3+1=5,当真假条件概率无论如何时将得到两段代码时间一样的错误结论。而根据今天的发现我们对上述结论进行修正,代码段1的执行时间是1+1+4=6周期,无论条件成立与否;对于代码段2,条件为假时执行周期是5,条件为真时是1+1+P+1=3+P,这个P有时候可能很小,也可能等于2。当真假概率一致时,代码段1的平均周期是6,代码段2的平均周期是5,按照最一般情况下P=2,因为各种原因比如分支预测器没有命中!是不是大跌眼镜啊?分支跳转还是居然击败了条件执行??所以对于代码段1的风格来说,随着条件指令越多,执行时间越长,这个时候依然是直接跳过无用的指令更好!
所以,IT指令到底有啥用,在强大的分支处理能力下,似乎没有太大的价值,也在很多情况下起不到原先的初衷消灭局部分支提高效率?
|