ngu*_*uns 12 linux embedded arm neon cortex-a8
可能看起来类似于: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
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下......当NEON进行计算时,ARM会发生什么?ARM闲置吗?还是继续进行其他操作?
你可以看到do_csum被调用,我们正在等待那个结果(或者它看起来像这样)..
注意:
问题:
Guy*_*ton 14
(来自TI Wiki Cortex A8的图片)
在NEON指令处理时,ARM(或更确切地说是整数流水线)不会处于空闲状态.在Cortex A8中,NEON位于处理器流水线的"末端",指令流经管道,如果它们是ARM指令,则它们在流水线的"开始"执行,最后执行NEON指令.每个时钟都会将指令推送到管道中.
以下是有关如何阅读上图的一些提示:
如果您正在执行一个100%NEON指令的序列(这是非常罕见的,因为通常涉及一些ARM寄存器,控制流等),那么有一段时间整数管道没有做任何有用的事情.大多数代码将至少在某些时间同时执行两个代码,而巧妙设计的代码可以通过正确的指令组合最大化性能.
这个用于Cortex A8的在线工具循环计数器非常适合分析汇编代码的性能,并提供有关在哪些单元中执行的内容以及停止运行的信息.
执行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...
Run Code Online (Sandbox Code Playgroud)
ARM cortex-A8可以在每个时钟周期执行最多2条指令.如果它们都是独立的NEON操作,则在它们之间放置ARM指令是没有用的.OTOH如果知道VLD(加载)的延迟很大,可以在加载和首次使用加载值之间放置许多ARM指令.但是在每种情况下,组合使用必须提前计划并交错.
在Application Level Programmers’ Model
,您无法真正区分ARM和NEON单元.
虽然NEON是一个独立的硬件单元(可作为Cortex-A系列处理器的选件),但ARM核心却以紧凑的方式驱动它.它不是一个可以以异步方式通信的独立DSP.
您可以通过充分利用两个单元上的管道来编写更好的代码,但这与具有单独的核心不同.
NEON单元就在那里,因为它可以在低频率下比ARM单元快一些操作(SIMD).
这就像拥有一位擅长数学的朋友一样,只要你有一个难题,你就可以问他.在等待答案的同时你可以做一些小事情,比如如果答案是这样我应该这样做,或者如果没有这样做,但如果你依赖那个答案继续,你需要等待他回答才能进一步.你可以自己计算答案但是它会更快,甚至包括你们两个人之间的沟通时间,而不是自己做所有数学.我想你甚至可以将这个类比扩展为"你还需要给那位朋友买一些午餐(能源消耗),但在很多情况下它值得".
任何说ARM内核的人都可以做其他事情,而NEON核心正在研究它的东西,那就是谈论指令级并行,而不是任务级并行.