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

时间:2012-10-19 06:54:16

标签: linux embedded arm neon cortex-a8

可能看起来类似于:ARM and NEON can work in parallel?,但不是,我还有其他一些问题(可能是我理解的问题):

在协议栈中,当我们计算校验和时,这是在GPP上完成的,我现在将该任务作为函数的一部分移交给NEON:

这是我作为NEON的一部分编写的校验和函数,发布在Stack Overflow中:Checksum code implementation for Neon in Intrinsics

现在,假设从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会发生什么? ARM闲置吗?还是继续进行其他操作?

你可以看到do_csum被调用,我们正在等待那个结果(或者它看起来像这样)..

注意:

  1. 就cortex-a8而言:
  2. 从链接中可以看到
  3. do_csum是用intrinsics编码的
  4. 使用gnu工具链进行编译
  5. 如果您还采用多线程或任何其他概念或在这些相互操作发生时进入画面,那将会很好。
  6. 问题:

    1. 当NEON正在进行操作时,ARM是否处于空闲状态? (在这种特殊情况下)
    2. 或者它是否搁置了当前的ip_csum相关代码,并占用了另一个进程/线程,直到NEON完成? (我对这里发生的事情几乎是愚蠢的)
    3. 如果它处于空闲状态,我们怎样才能使ARM在其他方面工作直到NEON完成?

3 个答案:

答案 0 :(得分:14)

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寄存器,控制流等),那么有一段时间整数管道没有做任何事情有用。大多数代码将至少在某些时间同时执行两个代码,而巧妙设计的代码可以通过正确的指令组合最大化性能。

这个在线工具Cycle Counter for Cortex A8非常适合分析汇编代码的性能,并提供有关在哪些单元中执行的内容以及停止运行的信息。

答案 1 :(得分: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指令是没有用的。 OTOH如果知道VLD(加载)的延迟很大,可以在加载和首次使用加载值之间放置许多ARM指令。但在每种情况下,必须事先计划并交错使用组合使用。

答案 2 :(得分:6)

Application Level Programmers’ Model中,您无法真正区分ARM和NEON单位。

虽然NEON是一个单独的硬件单元(可作为Cortex-A系列的选件提供) 处理器),是ARM核心以严密的方式驱动它。它不是一个可以异步通信的独立DSP。

您可以通过充分利用两个单元上的管道来编写更好的代码,但这与具有单独的核心不同。

NEON单元存在是因为它可以在低频率下比ARM单元快一些操作(SIMD)。

这就像拥有一位擅长数学的朋友一样,只要你有一个难题,你就可以问他。在等待答案的同时你可以做一些小事情,比如如果答案是这样我应该这样做,或者如果没有这样做,但如果你依赖那个答案继续,你需要等待他回答才能进一步。你可以自己计算答案但是它会更快,甚至包括你们两个人之间的沟通时间,而不是自己做所有数学。我想你甚至可以将这个类比扩展为“你还需要给那位朋友买一些午餐(能量消耗),但在很多情况下它值得”。

任何说ARM核心的人都可以做其他事情,而NEON核心正在处理其中的事情是instruction-level parallelism而不是像task-level parallelism那样。