【问题标题】:Neon code not optimized霓虹灯代码未优化
【发布时间】:2017-12-20 12:18:36
【问题描述】:

我为 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

【问题讨论】:

  • 你的编译标志是什么? (如果您不知道,请咨询-v
  • 现已启用,但遗憾的是没有区别 :(

标签: android android-ndk arm simd neon


【解决方案1】:

问题:

  • 看来您是在调试模式下编译的。
  • 似乎数组是全局变量或非静态局部常量。
  • 首先,Android Studio 内置 Clang (v4.9) 在从内部函数生成高效机器代码方面非常糟糕。

解决方案:

  • 将构建类型更改为Release
  • 仅使用局部变量,尤其是在循环内部,如果常量数组是局部的,则将它们声明为静态。
  • 不要将 Clang 用于内在函数,或者更好的是,根本不要使用内在函数。

【讨论】:

  • * 是的,它处于调试模式。在发布模式下(启用调试支持),我看不出有什么不同。 * 尝试静态变量,但代码生成异常可能是由于静态变量的行为。我正在调试这部分 * 如果我尝试为 vec1 = vld1q_f32(&a1[0]) 编写汇编指令,例如“vld1.32 {v0}, [%[src1]]!”它不会编译并声明“无法识别” vld1.32 的指令助记符。其他汇编指令不报告任何错误。有什么想法吗?
  • vld1.n 是一个aarch32 指令。 aarch64 NEON 指令不以“v”开头。语法上还有很多其他差​​异。如果要编写汇编代码,则必须同时编写,和/或在 gradle 文件中使用 abiflter,以过滤掉其他架构,例如 x86
猜你喜欢
  • 2012-01-01
  • 2016-01-30
  • 2014-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
  • 1970-01-01
  • 2015-02-14
相关资源
最近更新 更多