可能看起来类似于: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被调用,我们正在等待那个结果(或者它看起来像这样)..
注意:
问题:
答案 0 :(得分:14)
(图片来自TI Wiki Cortex A8)
当NEON指令正在处理时,ARM(或更确切地说是整数流水线)不会处于空闲状态。在Cortex A8中,NEON位于处理器流水线的“末端”,指令流经管道,如果它们是ARM指令,则它们在流水线的“开始”执行,最后执行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那样。