ARM Thumb/Thumb-2性能

Kat*_*och 6 arm cortex-m3

我正在使用具有Thumb-2指令集的ARM Cortex-M3控制器.

Thumb模式用于将指令压缩为16位大小.因此减少了代码的大小.但是对于普通的Thumb模式,为什么说性能会降低?

对于Thumb-2,据说根据这两个链接改进了性能:

在单个16位指令限制编译器可用的函数的情况下,可以提高性能.

Thumb-2的既定目标是实现类似于Thumb的代码密度,其性能类似于32位内存上的ARM指令集.

这个表现究竟是什么?有人可以提供一些与之相关的例子吗?

old*_*mer 8

与ARM 32位指令集进行比较时,拇指16位指令集(还没有谈到thumb2扩展)占用的空间更少,因为指令大小只有一半,但通常会有性能下降,因为它需要更多的指令与手臂做同样的事情.指令集的功能较少,大多数指令仅在寄存器r0-r7上运行.苹果与苹果比较更多指令做同样的事情是比较慢的.

现在,thumb2扩展程序采用以前未定义的拇指指令并创建32位拇指指令.了解有多组thumb2扩展.ARMv6m可能会增加几十个.ARMv7m在拇指指令集中添加了150条指令,我不知道ARMv8或未来会持有什么.因此,假设ARMv7m,他们已经弥补了您可以用拇指做什么和在ARM中可以做什么之间的差距.所以thumb2是一个简化的ARM指令集,但是并没有减少.因此,与执行相同操作的ARM相比,在thumb2(假设加拇指)中执行相同操作可能仍需要更多指令.

这给出了一个问题的味道,一个单独的指令和它的等效拇指.

ARM

and r8,r9,r10

THUMB

push {r0,r1}
mov r0,r8
mov r1,r9
and r0,r1
mov r1,r10
and r0,r1
mov r8,r0
pop {r0,r1}
Run Code Online (Sandbox Code Playgroud)

现在编译器不会这样做,编译器会知道它是以拇指为目标并通过选择其他寄存器来做不同的事情.每个指令的寄存器数量更少,功能更少:

mov r0,r1
and r0,r2
Run Code Online (Sandbox Code Playgroud)

仍然需要两个指令/执行周期和两个寄存器,而不修改操作数,并将结果放在第三个寄存器中.Thumb2有一个三个寄存器,因此您可以使用thumb2扩展返回单个指令.并且thumb2指令允许在拇指限制为r0-r7的那三个寄存器中的任何一个上使用r0-r15.

查看ARMv5架构参考手册,在每个拇指指令下,它会显示等效的ARM指令.然后转到那条ARM指令,比较一下你可以用拇指指令做的手臂指令.这是一条单向路径,拇指指令(不是thumb2)与ARM指令具有一对一的关系.所有拇指指令都有等效的臂指令.但并非所有手臂指令都有相同的拇指指令.您应该能够从本练习中看到使用拇指指令集时编译器的限制.然后获取ARMv7m架构参考手册并查看指令集,并比较"所有拇指变体"编码(包括ARMv4T的编码)和仅限于ARMv6和/或v7的编码,并查看拇指之间的功能扩展和thumb2以及thumb2只有没有拇指对应的指令.这应该阐明编译器在thumb和thumb2之间必须使用的内容.然后,您可以将thumb + thumb2与完整的ARM指令进行比较(ARMv7 AR就是它的名称?).并且看到thumb2更接近ARM,但是你失去了例如每条指令上的条件,所以拇指的条件执行变得与代码分支相比较,在ARM中你有时会有一个if-then-else而没有分支. .


小智 7

Thumb-2向原始Thumb引入了可变长度指令; 现在指令可以是16位和32位的混合.这意味着您在日常代码中保留了原始Thumb的大小优势,但现在可以在更复杂的代码中访问几乎完整的ARM功能集,但没有Thumb之前产生的ARM互通开销.

除了上述从所有寄存器操作访问完整寄存器集之外,Thumb-2还以IF-THEN(IT)块的形式添加了无分支条件执行.最初的Thumb删除了几乎所有指令上的条件执行的商标ARM功能; 现在,在Thumb-2中通过在IT指令前加上最多四条连续指令的条件来实现这一点.

此外,指令集本身也得到了极大的扩展; 例如,Cortex-M4F实现了DSP扩展以及FPv4-SP浮点扩展.事实上,我相信甚至可以在Thumb2中编码NEON.