【问题标题】:VLD3.8 in NEON ASM doesn't work like the vld3q_u8 documentation says it should?NEON ASM 中的 VLD3.8 不像 vld3q_u8 文档所说的那样工作?
【发布时间】:2016-09-21 23:03:06
【问题描述】:

根据 ARM 参考,我们有 2 个函数分别加载 8 个和 16 个 uint8_t 实例:

 uint8x16x3_t  vld3q_u8(__transfersize(48) uint8_t const * ptr);  
                                             // VLD3.8 {d0, d2, d4}, [r0]

 uint8x8x3_t vld3_u8(__transfersize(24) uint8_t const * ptr);  
                                             // VLD3.8 {d0, d1, d2}, [r0]

在 NEON 内在函数中,我尝试了 vld3q_u8,一切正常,加载了 16 * 3 个 uint8 元素;但是,当我在 NEON 程序集中使用 VLD3.8 {d0, d2, d4} 时,只加载了 8 * 3 个 uint8 元素。

在我看来,没有使用 d1、d3 和 d5 寄存器。

我想完全使用 q0(d0, d1)、q1(d2, d3) 和 q3(d4, d5) 寄存器来加载 16 * 3 的 uint8 元素。

有人可以帮忙吗?

//sample code:
vld3.8 {d0, d2, d4}, [%[A]]!
vst.3.8 {d0, d2, d4}, [%[C]]!

我正在为 32 位 ARM 架构构建它。

【问题讨论】:

标签: assembly optimization arm neon


【解决方案1】:

在我看来,d1、d3 和 d5 寄存器没有被使用

确实不是,除非您加载它们。内在函数参考不太清楚的是 Q 形式的加载/存储内在函数每个扩展为 两条 指令 - 底层 vldn/vstn 指令仅针对 D 寄存器,但可以可以连续执行此操作,也可以以 2 的步长执行此操作,这样一对指令可以按适当的顺序加载成对的寄存器。

这是一个拆解的示例,说明 vld3q_u8 内在函数在原位的实际样子:

0:   f460650f        vld3.8  {d22,d24,d26}, [r0]
4:   e2802018        add     r2, r0, #24
...
c:   f462750f        vld3.8  {d23,d25,d27}, [r2]
...

这是针对 uint8x16x3_t 变量,编译器显然已为其分配 Q11-13。

【讨论】:

  • 好的。谢谢。这是有道理的,所以这意味着即使我在内部函数中使用 vld3q_u8 或 (vld3_u8 + loop) 也需要大约相同的时间? (速度取决于汇编中 vld3.8 调用的数量)。我说的对吗?
  • 在大多数 DSP 算法中,VLD 的速度将取决于您在 L1 或 L2 缓存中保持数据热的能力(或预加载的能力),而不是指令中的一两个周期差异发行周期。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多