我的Zynq-7000 ARM Cortex-A9处理器同时具有NEON和VFPv3扩展,Zynq-7000-TRM表示该处理器配置为具有" VFPv3的独立流水线和高级SIMD指令& #34;
到目前为止,我使用Linaro GCC 6.3-2017.05和-mfpu=neon
选项编译了我的程序,以使用SIMD指令。但是在编译器还要发布非SIMD操作的情况下,使用-mfpu=neon-vfpv3
会有所不同吗? GCC的指令选择和调度程序是否会发出两个版本的指令,以便它可以利用这两个流水线来提高CPU的利用率?
答案 0 :(得分:4)
技术上,是的。
现实,没有。
NEON在ARMv7上是可选的。
被许可人可以从下面选择一种配置:
与NEON不同,ARMv7上有不同的VFP版本,Cortex-A8上的VFP-lite是最流行的非流水线版本,因此非常慢。
因此,从技术上讲,通过编译器选项指定CPU配置和架构版本是有意义的,这样编译器就可以为该特定架构/配置生成最优化的机器代码。
实际上,现在编译器忽略了大多数这些构建选项甚至指令。
并且VFP和NEON指令被分配给不同的管道并不会有多大帮助,因为它们都共享寄存器库。
通过利用尽可能多的寄存器来提升NEON的性能将带来的不仅仅是让VFP并行运行。
这让我感到很困惑,为什么以及如此多的人如此信任免费编译器。
最好的ARM编译器可以提供价值6,000美元+ DS-5旗舰版的ARM。他们的支持非常好,但我不确定它是否能证明价格合理。
答案 1 :(得分:3)
ARM's Cortex-A9 NEON/VFP manual(Cortex™ -A9 NEON™ 媒体处理 引擎)在第3.2节中编写最佳VFP和高级SIMD代码:
以下指南可为VFP和Advanced提供显着的性能提升 SIMD代码:尽可能避免:
...
混合高级SIMD指令仅包含VFP说明。
它表示它可以与ARM或Thumb指令并行执行NEON和VFP指令(即标量整数代码),#34;除了同时加载和存储"。
如果它们意味着完全避免让它们一下子飞行,或者它们意味着避免VFP和NEON指令之间存在数据依赖关系,那么它并非100%清晰。很容易想象后者因不适用于前者的原因而变坏(例如,在不同域中的执行单元之间可能没有旁路转发)。
同一文档中的循环时序表明VFP标量指令在管道中比NEON指令花费的时间更长(即使延迟看起来相同),因此可能使用VFP对于没有代码的代码来说是一个胜利矢量化,即使使用-ffast-math
。或者,如果我正确读取此权限,NEON具有较低的延迟MUL,因此可能是长依赖链的胜利。
Cortex-A9,如果它有VFP,则具有完全流水线的VFP FPU。 e.g。
VADD / VSUB .F(Sn)或.D(Dn)((VFP):1c吞吐量。周期1需要输入,第4周期结果就绪。(4c延迟?)
VADD / VSUB Dn(NEON):1c吞吐量。第2周期需要输入,第5周期结果就绪(第6周回写)。 (所以4c或5c延迟?取决于消耗结果的东西)。
VADD / VSUB Qn(NEON):( 1个)2c吞吐量。在第2周期然后第3周期间需要输入,结果在第5周期结束,然后是第6步。(回写1c晚于此)(所以4c或5c延迟?)。
VMUL .F Sd,Sn,Sm
(VFP):1c吞吐量,第1周期所需的输入,第5周期结果准备就绪(所以5c延迟?)
还有用于乘法累加的特殊结果转发。见PDF。
答案 2 :(得分:3)
答案取决于gcc的版本,将来可能会发生变化。 current code in cortex-a9.md将NEON / VFP描述为组合单元。该行是,
(define_cpu_unit "ca9_issue_vfp_neon, cortex_a9_ls" "cortex_a9")
带有注释,
;; The Cortex-A9 core is modelled as a dual issue pipeline that has
;; the following components.
;; 1. 1 Load Store Pipeline.
;; 2. P0 / main pipeline for data processing instructions.
;; 3. P1 / Dual pipeline for Data processing instructions.
;; 4. MAC pipeline for multiply as well as multiply
;; and accumulate instructions.
;; 5. 1 VFP and an optional Neon unit.
;; The Load/Store, VFP and Neon issue pipeline are multiplexed.
;; The P0 / main pipeline and M1 stage of the MAC pipeline are
;; multiplexed.
;; The P1 / dual pipeline and M2 stage of the MAC pipeline are
;; multiplexed.
;; There are only 4 integer register read ports and hence at any point of
;; time we can't have issue down the E1 and the E2 ports unless
;; of course there are bypass paths that get exercised.
;; Both P0 and P1 have 2 stages E1 and E2.
;; Data processing instructions issue to E1 or E2 depending on
;; whether they have an early shift or not.
ca9_issue_vfp_neon
单位用于描述NEON和VFP指令。因此,调度程序在计算成本时不会知道指令可以流水线化。然而,它可能会发出两者并且你可能很幸运并且它们被流水线化。
在' arm.c'中,有许多实例使用NEON来传输数据。如果您的代码具有许多结构的浮点数,编译器可能会混合NEON和VFP代码,其中NEON用于移动数据。
exynos之类的机器有一些自定义调整,例如使用neon您的Zync CPU无法获得的字符串操作,因为它在arm.c中没有调整说明。
另外,如果您没有指定-mfpu=neon-vfpv3
,则任何-line汇编程序与' vfpv3'说明将无效。
根据GCC版本,情况会有所变化。但是,您可以在' cortex-a9.md'中查找CPU说明。查看编译器是否可能以不同方式调度指令。此外,' arm.c'文件执行指令的成本计算;如果没有在那里实现NEON成本,那么编译器将永远不会发出指令。
在使用更简单的ARMv5 DSP指令时,即使这样做有用,你会发现只有1-2%的说明会改变。在数兆字节的图像中,像这样的选项只会因为其他人给出的原因(共享寄存器,浮点上的C'语义等)而改变几百个操作码。
但是,如果-mfpu=neon-vfpv3
描述了您的CPU,为什么不将它用于嵌入式应用程序?通用选项旨在生成可在多种类型的设备上运行的代码。