开发者
sonic调用汇编加速的两种机制

sonic调用汇编加速的两种机制

编译DevKitgo

发表于 2026/05/29

0

概述

sonic项目实现了两种 Go 调用平台汇编的机制:

  • JIT动态调用 WrapGoc
  • 静态链接 Linkname

1. WrapGoc(动态调用模式)

1.1 核心思想

通过 `loader.WrapGoC()` 将汇编代码(raw bytes)加载到 Go runtime,生成 Go↔C ABI 转换的 wrapper。

1.2 调用流程

初始化阶段 (Use):

  1. 注册C函数 — 创建Func结构体,设置Pcsp/MaxStack
  2. 加载汇编 — Load() 返回函数地址
  3. 生成Wrapper — abi.CallC() 生成ABI转换代码
  4. 加载Wrapper — Load() 返回wrapper地址
  5. 更新指针 — *F_skip_one = wrapper地址

运行时调用:

Go应用 —F_skip_one— Wrapper(ABI转换) — 汇编实现

1.3 关键文件

sve_wrapgoc/
├── skip_one.go           # Go wrapper声明
├── skip_one_subr.go      # 元数据: _cfunc_skip_one
├── skip_one_text_arm64.go # 汇编字节码
└── native_export_arm64.go  # Use() 调用 WrapGoC

2. Linkname(静态链接模式)

2.1 核心思想

使用 `//go:linkname` 直接链接到 plan9 汇编函数,编译时绑定,无运行时加载开销。

2.2 调用流程

编译/链接阶段:

  1. skip_one_arm64.go: func skip_one(...) int; func __skip_one(...)
  2. //go:linkname __skip_one ·__skip_one(SB)
  3. skip_one_arm64.s: TEXT ·__skip_one(SB) 包含原始汇编
  4. 链接器绑定 __skip_one — ·__skip_one(SB)

运行时调用:

Go应用 — skip_one — __skip_one — 汇编实现

2.3 关键文件

sve_linkname/
├── skip_one_arm64.go     # Go声明 + //go:linkname
├── skip_one_arm64.s      # plan9汇编
├── skip_one_subr_arm64.go # 地址自举
└── native_export_arm64.go  # Use() 调用 Linkname


本页内容