_mm_add_epi32的Golang汇编实现
Posted
技术标签:
【中文标题】_mm_add_epi32的Golang汇编实现【英文标题】:Golang assembly implement of _mm_add_epi32 【发布时间】:2020-08-04 08:25:40 【问题描述】:我正在尝试在 golang 程序集中实现 _mm_add_epi32
,可以选择在 avo 的帮助下实现。但我对组装知之甚少,甚至不知道如何开始。你能给我一些代码提示吗?谢谢大家。
这是等效的较慢的 golang 版本:
func add(x, y []uint32) []uint32
if len(x) != len(y)
return nil
result := make([]uint32, len(x))
for i := 0; i < len(x); i++
result[i] = x[i] + y[i]
return result
我知道paddq xmm, xmm
这个结构是我们需要的,但不知道如何将[]byte
的切片转换成256位寄存器YMM
。
【问题讨论】:
您拥有的函数与_mm_add_epi32
有点不同,因为它需要任意长度的切片。这是故意的吗?
感谢您的回复,使用[]uint32
或[8]uint32
都可以,第一个是为了与函数调用者保持数据结构的一致性。
嗯,支持任意长度的切片会使代码变得相当复杂,所以最好选择两者中的一个,这样我就可以写一个答案。
[8]uint32
已经足够好了,提前谢谢。
【参考方案1】:
下面是这样一个加法函数的例子:
// func add(x, y [8]int32) [8]int32
// q = x + y
TEXT ·add(SB),0,$0
VMOVDQU x+0(FP), Y0
VPADDD Y+32(FP), Y0, Y0
VMOVDQU Y0, q+64(FP)
VZEROUPPER
RET
在阅读此代码之前,请先熟悉this document。不幸的是,Go 风格的程序集(又名 Plan 9 风格的程序集)的文档记录很差。
数组按值传递到堆栈上。返回值作为调用者读回的额外最右边的参数传递。使用我链接到访问函数参数的文档中记录的(FP)
。
除此之外,它非常简单。语法类似于(但不等于)AT&T 语法。请注意,寄存器名称不同,必须提供大小后缀。
如您所见,为单个操作编写汇编函数是毫无意义的。采用您需要的算法并完全用汇编语言编写它可能会更好。
【讨论】:
非常感谢,我会尽快提供反馈。 谢谢@fuz,它有效!!! > 如您所见,为单个操作编写汇编函数是毫无意义的。你是对的,实际上我已经优化了我的应用程序的其他部分,这看起来像是最后可以优化的部分,所以我尝试了这个。非常感谢。 @WeiShen 如果您发布更多上下文,我也许可以提供更好的优化建议。随意提出一个新问题并将其链接到此处,以便我找到它。还可以考虑使用go tool pprof
来查找应用程序的哪些部分实际上与性能相关。
是的,我经常使用 pprof。这是 [pprof 结果](gist.github.com/shenwei356/…)
@WeiShen 不幸的是,在 cmets 中不允许换行,因此您的代码部分非常乱码。如果你能告诉我你想使用这个函数的上下文,我可能会提供更好的优化建议。正如我之前所说,最好为此提出一个新问题。以上是关于_mm_add_epi32的Golang汇编实现的主要内容,如果未能解决你的问题,请参考以下文章