为什么有条件执行的指令不存在于以后的ARM指令集中?

fad*_*bee 17 assembly arm computer-architecture conditional-execution

天真的,有条件执行的指令对我来说似乎是一个好主意.

当我阅读更多关于ARM(和类似ARM)的指令集(Thumb2,Unicore,AArch64)时,我发现它们都缺少条件执行的位.

为什么每个都缺少条件执行?

条件执行当时是错误的,还是后续的更改使得它成为指令位的昂贵浪费?

aus*_*len 22

一般声称现代系统具有更好的分支预测器,并且编译器更先进,因此它们在指令编码空间上的成本是不合理的.

这来自ARMv8指令集概述

A64指令集不包括谓词或条件执行的概念.基准测试表明,现代分支预测器运行良好,预测执行指令不能提供足够的好处来证明其大量使用操作码空间,以及高级实现中的实现成本.

它继续下去

提供了一组非常小的"条件数据处理"指令.这些指令是无条件执行的,但使用条件标志作为指令的额外输入.已经证明该集合在条件分支预测不良或者效率低的情况下是有益的.

另一篇名为" 针对ARM处理器的更多寄存器的交易条件执行"的论文声称:

...条件执行占用宝贵的指令空间,因为条件被编码到每个32位ARM指令上的4位条件代码选择器中.此外,在现代嵌入式应用程序中,只有很小比例的指令实际上是条件化的,而条件执行甚至可能不会导致现代嵌入式处理器的性能提升.

  • 此外,预测不能很好地执行无序执行:它可能需要*四个*数据流源操作数(谓词,目标寄存器的当前值[如果谓词为假,则需要]和两个源寄存器值)检查是否有空房.AArch64的预测指令只需要三个源(OoO机器更可能支持[例如,支持FMA],并且更容易破解为2源μops[如Alpha 21264对CMOV所做的那样]). (6认同)

phu*_*clv 9

其中一个原因是因为编码.

拇指来说,你不能将更多的4位压入16位紧密的空间,而3位高位的寄存器甚至没有足够的空间,它们必须简化为只有8位寄存器的子集.请注意,在thumb2中,您有一条单独的IT(E)指令,用于选择接下来的4条指令的条件.但是,由于上述原因,您无法将条件存储在同一条指令中.

对于AArch64,与32位ARM相比,寄存器的数量增加了一倍,但同样,对于寄存器的新3位高位,您没有任何剩余位.如果要使用旧编码,则必须从窄12位立即或4位条件"借用".与其他RISC架构(如MIPS)相比,12位太小,并且减少了它使一切变得更糟,因此删除条件是更好的选择.因为分支预测变得越来越先进,所以它不会成为问题

  • AArch64确实包含了很多谓词指令,例如条件增量和选择,它比x86的CMOV更强大。在适当的地方,它肯定仍然是为高效的无分支代码设计的。但是它们只是ALU指令,不是谓词存储或谓词加载,它们使您可以无分支地进行条件加载或从可能无效的指针进行存储。 (2认同)

Aki*_*nen 5

条件执行是许多辅助或位错误例程的实现的一个很好的选择,例如排序,列表或树操作,数字到字符串转换,sqrt或长除法.我们可以在路由器中添加UART驱动程序并提取位字段.那些具有高分支到非分支比率,也具有稍高的不可预测性.

但是,一旦超出最低级别的服务(或通过使用更高级别的语言来提高抽象级别),代码看起来就完全不同了:不同条件分支内的代码块更多地包含移动数据和调用子例程.这些额外的4位的好处迅速消失.它不仅是个人发展,而且是文化:文化编程从非结构化(基础,Fortran,汇编)发展到结构.在不同的指令集架构中也更好地支持不同的编程范例.

技术上的妥协可能是将五位"cond.S"字段压缩为四种或三种最常用的组合.

  • “这不仅是个人发展,也是文化发展。” - *什么?* (2认同)

小智 5

说条件执行在ARMv8中不存在有些误导。问题是要了解为什么您不想执行某些指令。也许在ARM早期,实际的不执行指令很重要(对于功能或其他方面),但是今天,此功能的重要性在于它允许您避免小笨拙跳转的分支,例如a =(b> 0?1:2)。这种事情比您想象的要普遍得多-从概念上讲,它是MAX / MIN或ABS之类的(尽管对于某些CPU,可能会有执行这些特定任务的指令)。

在ARMv8中,虽然没有通用的有条件执行的指令,但是有一些指令可以执行我正在描述的特定任务,即允许您避免为短暂的笨拙跳转而分支;CSEL是最明显的示例,尽管还有其他情况(例如条件的条件设置)可以处理其他常见模式(在这种情况下,C短路表达评估的模式)。

恕我直言,ARM在这里所做的是最有意义的。他们提取了条件执行的功能,该功能在现代CPU上仍然很有价值(避免使用许多分支),同时更改了实现的细节以匹配现代CPU的微体系结构。