【问题标题】:ARM NEON Intrinsics. What does vmulq_lane_f32 do?ARM NEON 内在函数。 vmulq_lane_f32 有什么作用?
【发布时间】:2014-05-06 23:07:04
【问题描述】:

在谷歌上我能找到的最好的是

float32x4_t vmulq_lane_f32 (float32x4_t, float32x2_t, const int)
Form of expected instruction(s): vmul.f32 q0, q0, d0[0]

查看 neon 程序员指南表明它是向量到标量乘法。但也有其他 API 可用于此目的。

float32x4_t vmulq_n_f32 (float32x4_t, float32_t)
Form of expected instruction(s): vmul.f32 q0, q0, d0[0]

所以我仍然不知道第一个 API 的目的是什么,以及其中的车道概念是什么。 编辑:以上信息来源:http://gcc.gnu.org/onlinedocs/gcc/ARM-NEON-Intrinsics.html

【问题讨论】:

  • 广播由索引参数指定的第二个向量参数的元素并将其乘以第一个向量参数。
  • 标量 floatfloat32xN_t 的一个元素在概念上可能是同一件事,但就 C 编译器而言,它们非常不同。为什么两者都支持?

标签: floating-point arm neon intrinsics


【解决方案1】:
float32x4_t vmulq_lane_f32 (float32x4_t, float32x2_t, const int)
Form of expected instruction(s): vmul.f32 q0, q0, d0[0]

应该写成

float32x4_t dst = vmulq_lane_f32 (float32x4_t q, float32x2_t d, const int c)
Form of expected instruction(s): vmul.f32 dst, q, d[c]

c 可以是 0-1。

在第二个例子中

float32x4_t vmulq_n_f32 (float32x4_t, float32_t)
Form of expected instruction(s): vmul.f32 q0, q0, d0[0]

float32_t 是非向量类型,这意味着编译器会生成必要的代码将该参数加载到向量寄存器中然后使用它,因此您可以免费获得。

使用vmulq_lane_f32,您可以明确告知要使用哪个寄存器,并且您必须在此之前确保它包含您想要的内容。

$ cat vmulq.c 
#include "arm_neon.h"

register float32x4_t a asm("q4");
register float32x2_t b asm("d10");
register float32x4_t c asm("q6");
register float32x4_t d asm("q7");

void foo() {
    c = vmulq_lane_f32(a, b, 1);
    d = vmulq_lane_f32(a, b, 0);
}

void bar() {
    a = vmulq_n_f32(a, 5);
}

$objdump -d vmulq.o

vmulq.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <foo>:
   0:   f3a8c96a    vmul.f32    q6, q4, d10[1]
   4:   f3a8e94a    vmul.f32    q7, q4, d10[0]
   8:   e12fff1e    bx  lr

0000000c <bar>:
   c:   ed9f7b01    vldr    d7, [pc, #4]    ; 18 <bar+0xc>
  10:   f3a88947    vmul.f32    q4, q4, d7[0]
  14:   e12fff1e    bx  lr
  18:   40a00000    .word   0x40a00000
  1c:   00000000    .word   0x00000000

【讨论】:

    【解决方案2】:

    float32_t 不是霓虹灯数据类型;所以float32_t 值必须在霓虹协处理器和主处理器之间传输。每当发生此类传输时,整个 neon 执行管道都会停止,因此此类传输的成本很高。

    vmulq_n_f32 将停止 neon 执行管道以传输 float32_t 值; vmulq_lane_f32 不会。

    如果您使用mmulq_lane_f32 而不是fmulq_n_f32,则可能(在一个管道不会停止的神奇彩虹世界中)运行速度最高可提高 5.5 倍。在普通的实际情况下,如果您明智地使用对齐的vldq_f32/vstq_f32 来保持vmulq_lane_f32 的馈送和流水线正常运行,您可以将运行速度提高 2 或 3 倍。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-18
      • 2011-02-20
      • 2019-09-03
      • 2012-06-30
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 2011-05-05
      相关资源
      最近更新 更多