sonic调用汇编加速的两种机制
发表于 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):
- 注册C函数 — 创建Func结构体,设置Pcsp/MaxStack
- 加载汇编 — Load() 返回函数地址
- 生成Wrapper — abi.CallC() 生成ABI转换代码
- 加载Wrapper — Load() 返回wrapper地址
- 更新指针 — *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() 调用 WrapGoC2. Linkname(静态链接模式)
2.1 核心思想
使用 `//go:linkname` 直接链接到 plan9 汇编函数,编译时绑定,无运行时加载开销。
2.2 调用流程
编译/链接阶段:
- skip_one_arm64.go: func skip_one(...) int; func __skip_one(...)
- //go:linkname __skip_one ·__skip_one(SB)
- skip_one_arm64.s: TEXT ·__skip_one(SB) 包含原始汇编
- 链接器绑定 __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

