我正在用矩阵乘法在 Go 中做一些性能实验,并遇到了一些意想不到的结果。
版本 1:
func newMatrix(n int) [][]int {
m := make([][]int, n)
buf := make([]int, n*n)
for i := range m {
m[i] = buf[i*n : (i+1)*n]
}
return m
}
func mult1(m1, m2, res [][]int) [][]int {
for i := range m1 {
for k := range m1[0] {
for j := range m2[0] {
res[i][j] += m1[i][k] * m2[k][j]
}
}
}
return res
}
我从线性数组创建了多个表示矩阵行的切片。
版本 2:
func mult2(m1, m2, res []int, n int) []int {
for i := 0; i < n; i++ {
for k := 0; k < n; k++ {
for j := 0; j < n; j++ {
res[i*n+j] += m1[i*n+k] * m2[k*n+j]
}
}
}
return res
}
在这个版本中,我只是使用一个线性数组并从乘法中索引到它。
将 2 个 2048x2048 矩阵相乘得到以下执行时间:
version 1: 35.550813801s
version 2: 19.090223468s
版本 2 的速度几乎是版本 2 的两倍。
我使用以下方法进行测量:
start := time.Now()
mult(m1, m2, m3)
stop := time.Now()
我知道使用切片会提供另一层间接性,这可能会影响缓存性能,但是我没想到会有如此大的差异。不幸的是,我还没有找到任何适用于 Mac 的好工具,可以分析 Go 中的缓存效率,所以我不能确定这是否是导致性能差异的原因。
所以我想我问的是这是预期的行为还是我遗漏了什么?
软硬件:Go version 1.4.2 darwin/amd64;OS X 10.10.3;2 GHz 四核 i7。
MYYA
相关分类