使用没有内置函数的Go例程优化矩阵乘法

ht4b089n  于 2023-11-14  发布在  Go
关注(0)|答案(1)|浏览(109)

我有下面的代码使用Go语言的矩阵乘法

  1. func main() {
  2. var wg sync.WaitGroup
  3. var col = 100
  4. var row = 150
  5. var randMatrixA [][]int
  6. var randMatrixB [][]int
  7. chA := make(chan [][]int)
  8. chB := make(chan [][]int)
  9. wg.Add(1)
  10. go genMat(row, col, chA, &wg)
  11. wg.Add(1)
  12. go genMat(col, row, chB, &wg)
  13. wg.Wait()
  14. randMatrixA = <-chA
  15. randMatrixB = <-chB
  16. fmt.Println(randMatrixA)
  17. fmt.Println(randMatrixB)
  18. fmt.Println("The Go Result of Matrix Multiplication = ")
  19. start := time.Now()
  20. c := doCalc(randMatrixA, randMatrixB)
  21. elapsed := time.Since(start)
  22. fmt.Println(c)
  23. fmt.Printf("Time taken to calculate %s \n", elapsed)
  24. }
  25. func genMat(row int, col int, ch chan<- [][]int, wg *sync.WaitGroup) {
  26. nM := make([][]int, col)
  27. for i := 0; i < col; i++ {
  28. nM[i] = make([]int, row)
  29. }
  30. generateNums(nM)
  31. wg.Done()
  32. ch <- nM
  33. }
  34. func generateNums(randMatrix [][]int) {
  35. for i, innerArray := range randMatrix {
  36. for j := range innerArray {
  37. randMatrix[i][j] = rand.Intn(100)
  38. }
  39. }
  40. }
  41. func rowCount(inM [][]int) int {
  42. return (len(inM))
  43. }
  44. func colCount(inM [][]int) int {
  45. return (len(inM[0]))
  46. }
  47. func doCalc(inA [][]int, inB [][]int) [][]int {
  48. var i, j int
  49. var wg sync.WaitGroup
  50. chC := make(chan [][]int)
  51. m := rowCount(inA) // number of rows the first matrix
  52. p := rowCount(inB) // number of rows the second matrix
  53. q := colCount(inB) // number of columns the second matrix
  54. k := 0
  55. total := 0
  56. var nM [][]int
  57. wg.Add(1)
  58. go genMat(m, q, chC, &wg)
  59. nM = <-chC
  60. wg.Wait()
  61. for i = 0; i < m; i++ {
  62. for j = 0; j < q; j++ {
  63. for k = 0; k < p; k++ {
  64. total = total + inA[i][k]*inB[k][j]
  65. }
  66. nM[i][j] = total
  67. total = 0
  68. }
  69. fmt.Println()
  70. }
  71. return nM
  72. }

字符集
我使用Go例程来优化执行。两个go例程随机生成matrixA和MatrixB,另一个计算结果MatrixC
总执行时间平均约为2.4 ms,但我希望它在1到2 ms之间,甚至更短。
有没有人可以通过使用go例程而不使用内置函数来建议代码中的优化区域:)

qnyhuwrf

qnyhuwrf1#

为什么不使用默认库包?https://pkg.go.dev/gonum.org/v1/gonum/mat
我实现了,它比你的算法快(~1.1ms,多次运行结果如下)。

验证码:

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "time"
  6. "gonum.org/v1/gonum/mat"
  7. )
  8. func main() {
  9. const matrixSize = 150
  10. matrixA := generateRandomMatrix(matrixSize, matrixSize)
  11. matrixB := generateRandomMatrix(matrixSize, matrixSize)
  12. A := mat.NewDense(matrixSize, matrixSize, matrixA)
  13. B := mat.NewDense(matrixSize, matrixSize, matrixB)
  14. C := mat.NewDense(matrixSize, matrixSize, nil)
  15. start := time.Now()
  16. C.Mul(A, B)
  17. elapsed := time.Since(start)
  18. fmt.Printf("Duration %s\n", elapsed)
  19. }
  20. func generateRandomMatrix(rows, cols int) []float64 {
  21. matrix := make([]float64, rows*cols)
  22. for i := range matrix {
  23. matrix[i] = rand.Float64()
  24. }
  25. return matrix
  26. }

字符集

运行时间(多次运行):

  1. Duration 1.4275ms
  2. Duration 1.0722ms
  3. Duration 1.3446ms
  4. Duration 1.1604ms
  5. Duration 1.0194ms
  6. Duration 596.3µs
  7. Duration 1.2118ms
  8. Duration 925.2µs
  9. Duration 1.3754ms

展开查看全部

相关问题