12

可能看起来类似于:ARM 和 NEON 可以并行工作吗?,但不是,我还有其他问题(我的理解可能有问题):

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

这是我作为 NEON 的一部分编写的校验和函数,发布在 Stack Overflow:Intrinsics 中 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 会发生什么?ARM 闲着吗?还是继续进行其他操作?

如您所见, do_csum 被调用,我们正在等待该结果(或者这就是它的样子)..

笔记:

  1. 说到Cortex-A8
  2. 从链接中可以看到 do_csum 是用内在函数编码的
  3. 使用 gnu 工具链编译
  4. 如果您还采用多线程或任何其他涉及或在这些交互操作发生时出现的概念,那将会很好。

问题:

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

3 回答 3

14

在此处输入图像描述

(图片来自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的在线工具Cycle Counter非常适合分析汇编代码的性能,并提供有关在哪些单元中执行的内容和停止的内容的信息。

于 2012-10-19T07:07:58.237 回答
7

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

虽然 NEON 是一个单独的硬件单元(在 Cortex-A 系列处理器上作为一个选项提供),但它是 ARM 内核以紧密的方式驱动它。它不是一个单独的 DSP,您可以以异步方式进行通信。

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

NEON 单元之所以存在,是因为它可以在低频下比 ARM 单元更快地执行一些操作(SIMD)。

这就像有一个擅长数学的朋友,当你有一个难题时,你可以问他。在等待答案时,您可以做一些小事情,例如如果答案是这个,我应该这样做,或者如果不这样做,但如果您依赖该答案继续,您需要等待他回答,然后再继续。您可以自己计算答案,但与自己计算所有数学相比,即使包括你们两个之间的通信时间也会快得多。我认为您甚至可以将这个类比扩展为“您还需要为那个朋友买一些午餐(能量消耗),但在很多情况下这是值得的”。

任何说 ARM 内核可以做其他事情而 NEON 内核正在处理它的东西的人都在谈论指令级并行性,而不是任务级并行性

于 2012-10-19T07:03:41.247 回答
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 指令。但在每种情况下,必须提前计划并交错使用组合使用。

于 2012-10-19T07:03:08.190 回答