Android 霓虹灯代码未优化

Android 霓虹灯代码未优化,android,android-ndk,arm,simd,neon,Android,Android Ndk,Arm,Simd,Neon,我在中为Android NDK编写了一些简单的Neon内部函数。 代码如下: float32x4_t vec1; float32x4_t vec2; float32x4_t mulneon; vec1 = vld1q_f32(&a1[0]); vec2 = vld1q_f32(&a2[0]); mulneon = vmulq_f32(vec1, vec2); 我希望看到一些指示,如 vld1.32 {v0} ... vld1.32 {v1} ... vmul.f32 v0, v

我在中为Android NDK编写了一些简单的Neon内部函数。
代码如下:

float32x4_t vec1;
float32x4_t vec2;
float32x4_t mulneon;
vec1 = vld1q_f32(&a1[0]);
vec2 = vld1q_f32(&a2[0]);
mulneon = vmulq_f32(vec1, vec2);
我希望看到一些指示,如

vld1.32 {v0} ...
vld1.32 {v1} ...
vmul.f32 v0, v1, v0
但我看到的是很多ldr和str指令,然后是vmul。见下文。 我的问题是,android版本是否不支持vld1? 或者我需要启用其他优化吗

0x7f6ae33a20 <+792>:  ldr    x8, [sp, #0x198]
0x7f6ae33a24 <+796>:  ldr    q0, [x8]
0x7f6ae33a28 <+800>:  str    q0, [sp, #0x120]
0x7f6ae33a2c <+804>:  ldr    q0, [sp, #0x120]
0x7f6ae33a30 <+808>:  str    q0, [sp, #0x110]
0x7f6ae33a34 <+812>:  ldr    q0, [sp, #0x110]
0x7f6ae33a38 <+816>:  str    q0, [sp, #0x180]
0x7f6ae33a3c <+820>:  ldr    x8, [sp, #0x1a0]
0x7f6ae33a40 <+824>:  ldr    q0, [x8]
0x7f6ae33a44 <+828>:  str    q0, [sp, #0x100]
0x7f6ae33a48 <+832>:  ldr    q0, [sp, #0x100]
0x7f6ae33a4c <+836>:  str    q0, [sp, #0xf0]
0x7f6ae33a50 <+840>:  ldr    q0, [sp, #0xf0]
0x7f6ae33a54 <+844>:  str    q0, [sp, #0x170]
0x7f6ae33a58 <+848>:  ldr    x8, [sp, #0x228]
0x7f6ae33a5c <+852>:  ldr    x10, [sp, #0x198]
0x7f6ae33a60 <+856>:  add    x8, x10, x8, lsl #2
0x7f6ae33a64 <+860>:  str    x8, [sp, #0x198]
0x7f6ae33a68 <+864>:  ldr    x8, [sp, #0x250]
0x7f6ae33a6c <+868>:  ldr    x10, [sp, #0x1a0]
0x7f6ae33a70 <+872>:  add    x8, x10, x8, lsl #2
0x7f6ae33a74 <+876>:  str    x8, [sp, #0x1a0]
0x7f6ae33a78 <+880>:  ldr    q0, [sp, #0x170]
0x7f6ae33a7c <+884>:  str    q0, [sp, #0xe0]
0x7f6ae33a80 <+888>:  ldr    x8, [sp, #0x1a0]
0x7f6ae33a84 <+892>:  ldr    q0, [sp, #0xe0]
0x7f6ae33a88 <+896>:  ldr    s1, [x8]
0x7f6ae33a8c <+900>:  mov    v2.16b, v1.16b
0x7f6ae33a90 <+904>:  ins    v0.s[3], v2.s[0]
0x7f6ae33a94 <+908>:  str    q0, [sp, #0xd0]
0x7f6ae33a98 <+912>:  ldr    q0, [sp, #0xd0]
0x7f6ae33a9c <+916>:  str    q0, [sp, #0xc0]
0x7f6ae33aa0 <+920>:  ldr    q0, [sp, #0xc0]
0x7f6ae33aa4 <+924>:  str    q0, [sp, #0x170]
0x7f6ae33aa8 <+928>:  ldr    q0, [sp, #0x180]
0x7f6ae33aac <+932>:  ldr    q2, [sp, #0x170]
0x7f6ae33ab0 <+936>:  stur   q0, [x29, #-0xa0]
0x7f6ae33ab4 <+940>:  stur   q2, [x29, #-0xb0]
0x7f6ae33ab8 <+944>:  ldur   q0, [x29, #-0xa0]
0x7f6ae33abc <+948>:  ldur   q2, [x29, #-0xb0]
0x7f6ae33ac0 <+952>:  fmul   v0.4s, v0.4s, v2.4s
0x7f6ae33a20:LDRx8[sp,#0x198]
0x7f6ae33a24:ldr q0[x8]
0x7f6ae33a28:str q0[sp,#0x120]
0x7f6ae33a2c:ldr q0[sp,#0x120]
0x7f6ae33a30:str q0[sp,#0x110]
0x7f6ae33a34:ldr q0[sp,#0x110]
0x7f6ae33a38:str q0[sp,#0x180]
0x7F6AE3A3A3C:ldr x8[sp,#0x1a0]
0x7F6AE33A4:ldr q0[x8]
0x7F6AE33A4:str q0[sp,#0x100]
0x7f6ae33a48:ldr q0[sp,#0x100]
0x7F6AE33A4:str q0[sp,#0xf0]
0x7f6ae33a50:ldr q0[sp,#0xf0]
0x7f6ae33a54:str q0[sp,#0x170]
0x7f6ae33a58:ldr x8[sp,#0x228]
0x7f6ae33a5c:ldr x10[sp,#0x198]
0x7f6ae33a60:添加x8、x10、x8、lsl#2
0x7f6ae33a64:str x8[sp,#0x198]
0x7f6ae33a68:ldr x8[sp,#0x250]
0x7f6ae33a6c:ldr x10[sp,#0x1a0]
0x7f6ae33a70:添加x8、x10、x8、lsl#2
0x7F6AE3A3A74:str x8[sp,#0x1a0]
0x7f6ae33a78:ldr q0[sp,#0x170]
0x7f6ae33a7c:str q0[sp,#0xe0]
0x7f6ae33a80:ldr x8[sp,#0x1a0]
0x7f6ae33a84:ldr q0[sp,#0xe0]
0x7f6ae33a88:ldr s1[x8]
0x7f6ae33a8c:mov v2.16b,v1.16b
0x7f6ae33a90:ins v0.s[3],v2.s[0]
0x7f6ae33a94:str q0[sp,#0xd0]
0x7f6ae33a98:ldr q0[sp,#0xd0]
0x7f6ae33a9c:str q0[sp,#0xc0]
0x7f6ae33aa0:ldr q0[sp,#0xc0]
0x7f6ae33aa4:str q0[sp,#0x170]
0x7f6ae33aa8:ldr q0[sp,#0x180]
0x7f6ae33aac:ldr q2[sp,#0x170]
0x7f6ae33ab0:stur q0[x29,#-0xa0]
0x7f6ae33ab4:STURQ2[x29,#-0xb0]
0x7f6ae33ab8:ldur q0,[x29,#-0xa0]
0x7f6ae33abc:LDURQ2[x29,#-0xb0]
0x7f6ae33ac0:fmul v0.4s、v0.4s、v2.4s
问题:

  • 您似乎是在调试模式下编译的
  • 数组似乎是全局变量或非静态局部常量
  • Android Studio内置的Clang(v4.9)从一开始就非常不擅长从内部函数生成高效的机器代码
解决方案:

  • 将生成类型更改为
    Release
  • 仅使用局部变量,特别是在循环内部,如果常量数组是局部的,则将其声明为静态的
  • 不要用叮当来表示内在,或者更好的是,根本不要使用内在
问题:

  • 您似乎是在调试模式下编译的
  • 数组似乎是全局变量或非静态局部常量
  • Android Studio内置的Clang(v4.9)从一开始就非常不擅长从内部函数生成高效的机器代码
解决方案:

  • 将生成类型更改为
    Release
  • 仅使用局部变量,特别是在循环内部,如果常量数组是局部的,则将其声明为静态的
  • 不要用叮当来表示内在,或者更好的是,根本不要使用内在

您的编译标志是什么?(如果您不知道,请使用
-v
检查)现在启用,但不幸的是没有区别:(您的编译标志是什么?(如果您不知道,请使用
-v
检查)现在启用,但不幸的是没有区别:(*是,它处于调试模式。处于发布模式(启用调试支持),我看不出有多大区别。*尝试静态变量,但代码生成异常可能是由于静态变量的行为。我正在调试此部分*如果我尝试为vec1=vld1q_f32(&a1[0])编写汇编指令,比如“vld1.32{v0},[%[src1]!”它不会编译为“无法识别的指令助记符”对于vld1.32。其他汇编指令不会报告任何错误。有什么想法吗?
vld1.n
是一条
aarch32
指令。
aarch64
霓虹灯指令不是以“v”开头的。在语法上还有很多其他差异。如果你想写汇编代码,你必须同时写,和/或在中使用
abiflter
gradle文件,用于过滤掉其他体系结构,如
x86
*是的,它处于调试模式。处于发布模式(启用调试支持),我看不出有多大区别。*尝试静态变量,但代码生成异常可能是由于静态变量的行为。我正在调试此部分*如果我尝试为vec1=vld1q_f32(&a1[0])编写汇编指令,比如“vld1.32{v0},[%[src1]!”它不会编译为“无法识别的指令助记符”对于vld1.32。其他汇编指令不会报告任何错误。有什么想法吗?
vld1.n
是一条
aarch32
指令。
aarch64
霓虹灯指令不是以“v”开头的。在语法上还有很多其他差异。如果你想写汇编代码,你必须同时写,和/或在中使用
abiflter
gradle文件,以过滤掉其他体系结构,如
x86