【问题标题】:ARM Neon Assembler - strange pipeline issueARM Neon Assembler - 奇怪的管道问题
【发布时间】:2012-04-01 05:18:06
【问题描述】:

我正在尝试使用 Neon 指令提高用 ARM 汇编程序编写的一段代码的性能。

为了测试和计算,我使用这个计算器: http://pulsar.webshaker.net/ccc/sample-706454b3

我注意到,在“n.34-0 1c n0”行,Neon 单元似乎必须等待(?)10 个周期。这可能是什么原因,还是只是计算器中的一个错误?

我还需要一些关于如何提高 ARM/Neon Assembler 性能的一般信息。

目标是 ARM Cortex-A9。 对于编译,我使用带有内联汇编程序的最新 android-ndk。谢谢。

【问题讨论】:

    标签: android assembly android-ndk arm neon


    【解决方案1】:

    事实上,这有点复杂。 BitBank 是对的,NEON 还要等 D4。

    但您必须等待 10 个周期,因为 Neon 有一个加载/存储队列。 并且队列之前被其他指令填充

    vld1.64 d4, [r7, :64]
    

    所以当你需要D4时,你必须等待这条指令的执行 但要执行此指令,您必须执行所有之前推入 NEON 加载/存储队列的加载/存储指令。

    【讨论】:

      【解决方案2】:

      您不应该在 NEON 工作时通过 ARM 访问内存。它会导致 NEON 完全制动。

      显然,由于上述原因,您正在尝试某种具有破坏性的并行处理。

      此外,ldrb 太多了。 ARM 上的字节访问也几乎是一种罪过。

      我建议你先用 C 完全重写你的代码,只使用 32 位内存访问,然后评估它是否完全适用于 NEON,

      【讨论】:

      • 感谢您的评论。我只需要一个字节,所以如果我要一次读取 32 位,我需要再次 Shift/ANd 整个事情,这会更慢。该代码已经作为 C 和 ARM 汇编程序存在,我需要检查是否可以使用 Neon 指令加速它。理论上它应该快 30-40%。哪些操作可以并行完成。 ARM 算术和 Neon 加载/存储,但不是(?)Neon 算术和 ARM 加载/存储?
      • 你不会相信:32位读取+屏蔽比字节读取快得多。
      • 忘记并行处理。将值从 Neon 移动到 ARM 也会导致管道刷新浪费 11 个周期。当 Neon 完成整个工作时,ARM 将充当控制单元。
      • 我会尝试加载 32Bit 和掩码,但我认为之前有人测试过它并且速度较慢。好的,谢谢你的信息。就我而言,我似乎无法通过 Neon 指令提高性能:-(
      • 您为什么不尝试在 NEON 中完全重写您的函数呢? Neon 非常有能力进行整数操作,并且不需要所有耗时的掩码操作。如果您的函数在循环中包含的 if-else 少于两个,那么 Neon 就是要走的路。
      【解决方案3】:

      NEON 单元必须在该指令处等待,因为您正在引用在前一个 NEON 指令 (n.33-0 1c n0) 中加载的寄存器 (D4)。加载不是瞬时的,并且由于流水线,即使数据来自缓存,数据的可用性也会有所延迟。您需要对 ARM 和 NEON 指令重新排序,以免在加载后立即尝试使用寄存器,否则最终会浪费周期(流水线停顿)。

      【讨论】:

      • 如果缓存命中,这些危害只有 1~2 个周期。在这种情况下,情况有所不同。
      猜你喜欢
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-19
      相关资源
      最近更新 更多