【问题标题】:ARM Neon Matrix multiplication exampleARM Neon 矩阵乘法示例
【发布时间】:2017-07-02 13:19:15
【问题描述】:

我想学习霓虹灯。 我在 ARM 网站上举了这个例子:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0425/ch04s06s05.html

我想我会让它运行,然后开始试验它。吻。 该程序编译得很好(GCC),但是,在运行时遇到第一条 VST 指令时出现“分段错误”。删除 VST 指令,程序就会正常运行。 使用 GDB 一切似乎都在工作(寄存器值等),只是在内存存储过程中出现的错误。

感谢任何指导或帮助...

.global main
.func main
main:

.macro mul_col_f32 res_q, col0_d, col1_d
vmul.f32    \res_q, q8,  \col0_d[0] @ multiply col element 0 by matrix col 0
vmla.f32    \res_q, q9,  \col0_d[1] @ multiply-acc col element 1 by matrix col 1
vmla.f32    \res_q, q10, \col1_d[0] @ multiply-acc col element 2 by matrix col 2
vmla.f32    \res_q, q11, \col1_d[1] @ multiply-acc col element 3 by matrix col 3
.endm

LDR R0, =result0a
LDR R1, =result1a
LDR R2, =result2a

vld1.32  {d16-d19}, [r1]!   @ load the first eight elements of matrix 0
vld1.32  {d20-d23}, [r1]!   @ load the second eight elements of matrix 0
vld1.32  {d0-d3}, [r2]!         @ load the first eight elements of matrix 1
vld1.32  {d4-d7}, [r2]!         @ load the second eight elements of matrix 1

mul_col_f32 q12, d0, d1     @ matrix 0 * matrix 1 col 0
mul_col_f32 q13, d2, d3     @ matrix 0 * matrix 1 col 1
mul_col_f32 q14, d4, d5     @ matrix 0 * matrix 1 col 2
mul_col_f32 q15, d6, d7     @ matrix 0 * matrix 1 col 3

vst1.32  {d24-d27}, [r0]!   @ store first eight elements of result.
vst1.32  {d28-d31}, [r0]!   @ store second eight elements of result.

MOV R7, #1
SWI 0

result1a:   .word 0xFFFFFFFF    @ d16
result1b:   .word 0xEEEEEEEE    @ d16
result1c:   .word 0xDDDDDDDD    @ d17
result1d:   .word 0xCCCCCCCC    @ d17
result1e:   .word 0xBBBBBBBB    @ d18
result1f:   .word 0xAAAAAAAA    @ d18
result1g:   .word 0x99999999    @ d19
result1h:   .word 0x88888888    @ d19

result2a:   .word 0x77777777    @ d0
result2b:   .word 0x66666666    @ d0
result2c:   .word 0x55555555    @ d1
result2d:   .word 0x44444444    @ d1
result2e:   .word 0x33333333    @ d2
result2f:   .word 0x22222222    @ d2
result2g:   .word 0x11111111    @ d3
result2h:   .word 0x0F0F0F0F    @ d3

result0a:   .word 0x0       @ R0
result0b:   .word 0x0       @ R0
result0c:   .word 0x0       @ R0
result0d:   .word 0x0       @ R0
result0e:   .word 0x0       @ R0
result0f:   .word 0x0       @ R0
result0g:   .word 0x0       @ R0
result0h:   .word 0x0       @ R0

【问题讨论】:

  • 对于所有加载和存储操作,您加载和存储 16 个字(64 个字节),但只定义 8 个字(32 个字节)的空间。这在读取输入时“有效”,但在存储输出时,您将在您定义的数据区域末尾写入 32 个字节。
  • 首先,您应该强烈考虑使用 C/C++ 和内在函数而不是汇编。如今,汇编主要是一种对调试有用的“只读”语言,因此您只需查看内部代码的反汇编即可。其次,DirectXMath 包含 ARM32 和 ARM64 的内部代码路径。
  • 我已经尝试扩展数据区域,我已经优化了源,以便将结果放在空闲内存的开头,因此,更糟糕的是会覆盖原始数据。分段错误继续发生。
  • 使用 'sudo' 以超级用户身份运行文件不会导致分段错误。但是,不会计算结果 - 寄存器 q12 到 q15 都保持为零。初始值已正确加载。
  • @ChuckWalbourn 我认为您从未遇到过有能力的汇编程序员。内在函数生成的机器代码非常乏味,而且内在函数比指令本身更令人困惑。太没有意义了。

标签: assembly arm matrix-multiplication simd neon


【解决方案1】:

您尝试写入 8*8 = 64bytes,而您总共只分配了 4*8 = 32bytes。

此外,您很可能正在尝试写入由.text 声明的只读区域

你为什么不从 C/C++ 调用你的函数,传递你通过 malloc 分配的地址?

或者,您可以简单地使用堆栈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    相关资源
    最近更新 更多