You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go汇编中更高效地将全局数据加载至NEON寄存器?

问题

现有ARM64架构下Go汇编的全局数据p256one定义如下:

DATA p256one<>+0x00(SB)/8, $0x0000000000000001
DATA p256one<>+0x08(SB)/8, $0xffffffff00000000
DATA p256one<>+0x10(SB)/8, $0xffffffffffffffff
DATA p256one<>+0x18(SB)/8, $0x00000000fffffffe

GLOBL p256one<>(SB), 8, $32

当前将该全局数据加载到NEON寄存器V0、V1的方法需要6条指令:

LDP p256one<>+0x00(SB), (R0, R1)
    LDP p256one<>+0x10(SB), (R2, R3)
    VMOV R0, V0.D[0]
    VMOV R1, V0.D[1]
    VMOV R2, V1.D[0]
    VMOV R3, V1.D[1]

已知NEON的VLD1指令可以批量加载内存数据到寄存器组,比如VLD1 (R0), [V0.B16, V1.B16],但该指令无法直接引用全局符号。请问在Go汇编中,有没有更高效的方式将该全局数据加载到NEON寄存器?

高效加载方案

可以先把全局数据的地址加载到通用寄存器,再通过NEON的批量加载指令一次性完成数据填充,仅需2条核心指令(比原方案减少67%的指令数):

MOVD p256one<>(SB), R0
    VLD1 {V0.2D, V1.2D}, [R0]

细节说明

  1. 地址加载:MOVD p256one<>(SB), R0 是Go汇编针对ARM64优化的语法糖,会自动生成位置无关的寻址代码(等价于ADRP+ADD组合),正确获取全局符号的内存地址。
  2. 批量加载:VLD1 {V0.2D, V1.2D}, [R0] 会从R0指向的地址连续读取32字节数据,依次填充V0的两个64位双字寄存器和V1的两个64位双字寄存器,完美匹配p256one的32字节长度。

如果需要手动控制地址生成(比如兼容更底层的汇编规则),也可以写成:

ADRP R0, p256one<>(SB)
    ADD  R0, R0, p256one<>(SB)
    VLD1 {V0.D[0], V0.D[1], V1.D[0], V1.D[1]}, [R0]

这种写法和上面的语法糖效果完全一致,只是指令数多一条。

内容的提问来源于stack exchange,提问作者Emman Sun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:43:13