Floating point ARM霓虹灯内部组件。vmulq_lane_f32做什么?

Floating point ARM霓虹灯内部组件。vmulq_lane_f32做什么?,floating-point,arm,neon,intrinsics,Floating Point,Arm,Neon,Intrinsics,在谷歌上,我能找到的最好的方法是 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 i

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

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的目的是什么,其中的车道概念是什么。 编辑:以上信息来源:

它应该写为

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

广播由索引参数指定的第二个向量参数的元素,并将其乘以第一个向量参数。标量浮点和float32xN_t的一个元素在概念上可能是相同的,但就C编译器而言,它们是非常不同的。为什么不两者都支持呢?
$ 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