ARM在NEON执行操作时是否处于空闲状态?

12
可能看起来类似于:ARM和NEON可以同时工作吗?,但它不是,我有一些其他问题(可能是我的理解问题):
在协议栈中,当我们计算校验和时,这是在GPP上完成的,现在我将其作为函数的一部分交给了NEON:
这是我作为NEON的一部分编写的校验和函数,发布在Stack Overflow上:Neon纹理内核的校验码实现 现在,假设从Linux调用此函数。
ip_csum(){
  …
  …
  csum = do_csum(); //function call from arm
  …
  …
}


do_csum(){
  …
  …
  //NEON optimised code
  …
  …
  returns the final checksum to ip_csum/linux/ARM
}
在这种情况下,NEON在进行计算时ARM会发生什么?它会闲置吗?还是继续执行其他操作?
正如您所看到的,do_csum被调用,我们正在等待该结果(或者看起来是这样)。
注意:
1. 从cortex-a8的角度来说 2. 如您从链接中所见,do_csum使用内部函数编码 3. 使用GNU工具链进行编译 4. 如果您还涉及到多线程或其他涉及这些交互操作的概念,则会很好。
问题:
1. 在NEON执行其操作时,ARM是否闲置?(在这种特定情况下) 2. 或者,它搁置了与当前ip_csum相关的代码,并采取另一个进程/线程,直到NEON完成为止?(对于我而言,我对此发生的情况几乎一无所知) 3. 如果它正在闲置,我们如何让ARM在NEON完成之前处理其他事情?

3
ARM单元可以与NEON同时进行有用的工作。我建议阅读这篇论文,作为这种优化的一个例子:http://cr.yp.to/highspeed/neoncrypto-20120320.pdf - Marat Dukhan
1
我们需要查看实际的指令才能确定哪些内容在并行执行。你的“NEON 优化”代码可能是 NEON 指令和非 NEON 指令混合的结果。 - Guy Sirton
1
看我的答案,但你必须从指令级别而不是线程或函数级别来看事情。 - Guy Sirton
谢谢@Maratyszcza,那个链接确实很有帮助。这里有一个问题可能有点傻,当ARM调用NEON代码时,多线程/信号量/自旋锁的概念是否涉及其中? - nguns
1
在ARM和NEON单元上并行运行指令与多线程无关。这是指令级并行的一个例子 - 在同一周期内运行几个独立的指令。几乎所有现代CPU都能够在每个周期运行多个指令。然而,在同一周期内运行的指令对于CPU来说不像来自不同线程的指令那样独立,而且在许多情况下,处理器无法识别它们是独立的。 - Marat Dukhan
3个回答

13

enter image description here

(图片来自TI Wiki Cortex A8

当NEON指令在处理时,ARM(或整数流水线)不会闲置。在Cortex A8中,NEON位于处理器流水线的“末端”,指令通过流水线流动,如果它们是ARM指令,则在流水线的“开头”执行,而NEON指令则在末尾执行。每个时钟周期都将指令推送到流水线。

以下是阅读上图的一些提示:

每个周期,如果可能的话,处理器会获取一对指令(两条指令)。 获取是流水线化的,因此需要3个周期才能将指令传播到解码单元。 指令解码需要5个周期(D0-D4)。同样,这也是所有流水线操作,因此它影响延迟但不影响吞吐量。在可能的情况下,更多的指令会继续通过管道流动。 现在我们进入执行/加载存储部分。NEON指令通过该阶段流动(但这是在其他指令可能正在执行的情况下发生的)。 当我们到达NEON部分时,如果13个周期前获取的指令是一个NEON指令,则现在在NEON管道中对其进行解码和执行。 在此过程中,后续的整数指令可以同时在整数管道中执行。 该流水线是一个相当复杂的东西,有些指令是多周期的,有些具有依赖性,并且如果这些依赖关系未得到满足,则会停顿。其他事件,如分支,将刷新流水线。
如果您执行的序列是100% NEON 指令(这相当罕见,因为通常涉及一些 ARM 寄存器、控制流等),那么有一段时间整数管道没有做任何有用的事情。大多数代码都会同时并发执行这两个过程,而巧妙地编写代码可以通过正确的指令组合来最大化性能。
这个在线工具 Cortex A8 循环计数器 对于分析汇编代码的性能非常有用,并提供关于哪些单元正在执行以及哪些正在停顿的信息。

2
NEON ALUs并不一定在流水线的后面,也不一定有单独的解码/调度。它们存在于Cortex-A8上,但在许多其他实现中,它们与其他ALUs位于相同的流水线位置,并共享解码和调度。(无论如何都会点赞,因为问题指定了Cortex-A8)。 - Stephen Canon
@StephenCanon:谢谢...我在我的回答中澄清了这一点。 - Guy Sirton
谢谢。这里有一个可能很傻的问题,当ARM调用NEON代码时,多线程/信号量/自旋锁的概念是否涉及/可以被引入到图像中? - nguns
1
@Asif 不行。请看下面我的回答。 - auselen
1
@Asif:像上下文切换这样的事情需要数百个周期,所以它并不真正成为问题。理论上,您可以在处理NEON指令时等待自旋锁,但您需要以这种方式构建代码。这完全取决于处理器在最低级别读取的指令混合。 - Guy Sirton

7
在“应用程序级编程模型”中,你无法真正区分ARM和NEON单元。
虽然NEON是一个单独的硬件单元(可作为Cortex-A系列处理器的选项),但是它是由ARM核心紧密驱动的。它不是一个你可以异步通信的单独的DSP。
通过充分利用两个单元的流水线,您可以编写更好的代码,但这并不等同于拥有一个单独的核心。
NEON单元之所以存在,是因为它可以在低频率下比ARM单元更快地执行某些操作(SIMD)。
这就像有一个数学很好的朋友,每当你遇到难题时,你可以向他请教。在等待答案的同时,你可以做一些小事情,比如如果答案是这样,我应该做这个,或者如果不是,那么做另一个。但是,如果你依赖那个答案继续前进,你需要等待他回答才能继续。你也可以自己计算答案,但即使包括你们之间的通信时间,与自己做所有的数学相比,这将更快。我认为你甚至可以将这个类比扩展为“你还需要给那个朋友买午餐(能源消耗),但在许多情况下这是值得的”。

任何声称ARM内核在NEON内核处理任务时可以做其他事情的人都是在谈论指令级并行性,而不是类似任务级并行性的东西。


1
从技术上讲,ARM核心并不“驱动”NEON单元,NEON指令只是在管道下游稍后处理。 - Guy Sirton
1
是的,但从某种意义上说,您需要为NEON单元invfp寄存器设置值,而且您也需要将它们取回。即使当neon进行加载时,例如在循环中调用neon指令,所有这些都与应用程序级别程序员的观点相当耦合。 - auselen
1
是的,NEON单元没有控制流指令,因此在这方面受到限制。我想更准确地说,ARM控制执行流程... - Guy Sirton
感谢@auselen,我多么希望在SO上能够接受多个答案..!!! 在那之前+1 ;) - nguns

6

在执行NEON操作时,ARM并不处于“空闲”状态,而是控制它们。
为了充分利用两个单元的能力,可以仔细规划交错的操作序列:

loop:
SUBS r0,r0,r1  ; // ARM operation
addpq.16 q0,q0,q1  ; NEON operation
LDR r0, [r1, r2 LSL #2];   // ARM operation
vld1.32 d0, [r1]!  ; // NEON operation using ARM register
bne loop;         // ARM operation controlling the flow of both units...

ARM Cortex-A8每个时钟周期最多可以执行2条指令。如果它们都是独立的NEON操作,那么在它们之间放置一个ARM指令是没有用的。另一方面,如果知道VLD(加载)的延迟很大,可以在加载和第一次使用加载的值之间放置许多ARM指令。但在每种情况下,必须事先计划和交错使用。


不记得Cortex-A8是否特指德州仪器的实现,但在德州芯片中还有一个独立的DSP单元,可以完全并行运行于arm/neon之外。 - Aki Suihkonen
Cortex A8是ARM的IP。TI芯片,如OMAP3730和其他各种芯片,包括C64x DSP。 - Guy Sirton
1
Cortex-A8 可以在同一周期内执行两个整数指令 + 两个 NEON 指令(例如一个加载/存储和一个算术)。然而,它每个周期只能获取两个指令,但是单个指令可能需要多个周期。 - Guy Sirton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接