Go中的地址对齐

Sak*_*ain 6 c x86 simd go avx

所以我使用 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”,但我怀疑这会降低性能。

pet*_*rSO 1

例如,用更多的内存换取更少的 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)