使用 Neon 累积向量并打印到标准输出(程序集)

问题描述 投票:0回答:1

我发现很难找到在 Apple Silicon 上运行的良好、完整的汇编示例,特别是 SIMD 类型的操作,而不是不完整、过于通用的片段。

出于我自己的好奇心,我想在 M2 机器上编写一个示例......

  1. 采用一系列数字(首先内置于装配文件中)
  2. 将它们累积成一个结果(使用 SIMD 指令)
  3. 将结果输出到stdout

我有以下源代码,位于名为

test.s
...

的文件中
.global _start
.align 2

_start:
    ;;; Load numbers into x0
    ldr x0, numbers

    ;;; Load elements from array in x0 into dedicated Neon register
    st1 { v0. 4s }, [x0]

    ;;; Accumulate elements in vector using dedicated Neon instruction
    addv s0, v0.4s 

    ;;; Prepare formatted string
    adrp    x0, format@page
    add x0, x0, format@pageoff

    ;;; Add result to the stack for printing
    str s0, [sp, #-16]!

    ;;; Print string
    bl _printf
    mov x16, #1
    svc 0

numbers: .word 1, 2, 3, 4
format: .asciz "Answer: %u.\n"

...,使用以下命令组装和链接...

as -g -arch arm64 -o test.o test.s
ld -o test test.o -lSystem -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64

当我运行程序时,我本以为答案是

10
,但我得到的却不是。

我哪里做得不对?

assembly simd arm64 neon apple-silicon
1个回答
0
投票

ldr x0, numbers
将从标记为
numbers
的地址加载到
x0
(这仅起作用,因为
numbers
恰好位于同一部分中指令的足够接近的地址)。 所以
x0
中的值将不是
numbers
的地址,而是存储在那里的数据。 您最终会得到包含值
x0
0x0000000200000001
,并且后续的内存访问可能会崩溃。

您应该将

numbers
的地址放入
x0
中,并使用
adrp/add
序列,就像进一步使用
format
一样。

此外,

st1
应该是
ld1
,正如您已经提到的。

将这些行更改为

    adrp    x0, numbers@page
    add x0, x0, numbers@pageoff
    ld1 { v0.4s }, [x0]

使程序为我打印正确的值

10

© www.soinside.com 2019 - 2024. All rights reserved.