猿问

使用 goroutine 进行矩阵乘法会降低性能

我正在通过 Go 中的 goroutines 优化矩阵乘法。

我的基准测试显示,每行或每元素引入并发会大大降低性能:

goos: darwin
goarch: amd64
BenchmarkMatrixDotNaive/A.MultNaive-8                            2000000               869 ns/op               0 B/op          0 allocs/op
BenchmarkMatrixDotNaive/A.ParalMultNaivePerRow-8                  100000             14467 ns/op              80 B/op          9 allocs/op
BenchmarkMatrixDotNaive/A.ParalMultNaivePerElem-8                  20000             77299 ns/op             528 B/op         65 allocs/op

我知道缓存局部性的一些基本先验知识,每个元素并发性降低性能是有道理的。但是,为什么即使在原始版本中每行仍然会降低性能?

事实上,我还写了一个 block/tiling optimization,它的 vanilla 版本(没有 goroutine 并发)甚至比 naive 版本更差(这里不存在,让我们先关注 naive)。

我在这里做错了什么?为什么?这里怎么优化?


素胚勾勒不出你
浏览 98回答 1
1回答

慕桂英546537

执行 8x8 矩阵乘法是相对较小的工作。Goroutines(虽然可能是轻量级的)确实有开销。如果他们所做的工作是“小”的,那么启动、同步和丢弃它们的开销可能会超过利用多核/线程的性能增益,并且总体而言,您可能无法通过并发执行此类小任务来获得性能(见鬼,您可能甚至比不使用 goroutines 更糟糕)。措施。如果我们将矩阵大小增加到 80x80,运行基准测试,我们已经看到在以下情况下有一些性能提升ParalMultNaivePerRow:BenchmarkMatrixDotNaive/A.MultNaive-4               2000     1054775 ns/op BenchmarkMatrixDotNaive/A.ParalMultNaivePerRow-4    2000      709367 ns/op BenchmarkMatrixDotNaive/A.ParalMultNaivePerElem-4    100    10224927 ns/op(正如您在结果中看到的,我有 4 个 CPU 内核,在您的 8 核机器上运行它可能会显示出更多的性能提升。)当行很小时,您正在使用 goroutines 来完成最少的工作,您可以通过在 goroutines 完成“微小”工作后不“丢弃”它们来提高性能,但您可以“重用”它们。
随时随地看视频慕课网APP

相关分类

Go
我要回答