所以我使用 c2go 将 C 代码与 Go 链接起来。C 代码要求从 Go 调用的函数的某些参数是 256 位对齐的(函数参数都是指向 Go 变量的指针)。有没有办法实现 Go(即在 Go 中为变量指定 256 对齐)?
在 Go 中,“unsafe.Alignof(f)”显示为 8 个字节对齐(对于“var f [8]float32”),即 Go 保证 f 仅对齐 8 个字节。我需要它以某种方式对齐 32 个字节。
对于好奇:C 代码正在使用 SIMD 指令(具体来说是 AVX)。我正在使用“vmovaps”指令,它需要操作数的 256 位对齐。我可以使用不需要对齐的“vmovups”,但我怀疑这会降低性能。
例如,用更多的内存换取更少的 CPU 时间,
package main
import (
"fmt"
"unsafe"
)
// Float32Align32 returns make([]float32, n) 32-byte aligned.
func Float32Align32(n int) []float32 {
// align >= size && align%size == 0
const align = 32 // SIMD AVX byte alignment
const size = unsafe.Sizeof(float32(0))
const pad = int(align/size - 1)
if n <= 0 {
return nil
}
s := make([]float32, n+pad)
p := uintptr(unsafe.Pointer(&s[0]))
i := int(((p+align-1)/align*align - p) / size)
j := i + n
return s[i:j:j]
}
func main() {
f := Float32Align32(8) // SIMD AVX
fmt.Printf(
"SIMD AVX: %T %d %d %p %g\n",
f, len(f), cap(f), &f[0], f,
)
CFuncArg := &f[0]
fmt.Println("CFuncArg:", CFuncArg)
}
Run Code Online (Sandbox Code Playgroud)
游乐场:https://play.golang.org/p/mmFnHEwGKt
输出:
SIMD AVX: []float32 8 8 0x10436080 [0 0 0 0 0 0 0 0]
CFuncArg: 0x10436080
Run Code Online (Sandbox Code Playgroud)