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

问题描述 投票:0回答:1

我有以下使用 Go 例程进行矩阵乘法的代码


func main() {
    var wg sync.WaitGroup
    var col = 100
    var row = 150
    var randMatrixA [][]int
    var randMatrixB [][]int
    chA := make(chan [][]int)
    chB := make(chan [][]int)

    wg.Add(1)
    go genMat(row, col, chA, &wg)
    wg.Add(1)
    go genMat(col, row, chB, &wg)

    wg.Wait()

    randMatrixA = <-chA
    randMatrixB = <-chB
    fmt.Println(randMatrixA)

    fmt.Println(randMatrixB)

    fmt.Println("The Go Result of Matrix Multiplication = ")
    start := time.Now()
    c := doCalc(randMatrixA, randMatrixB)
    elapsed := time.Since(start)

    fmt.Println(c)

    fmt.Printf("Time taken to calculate %s \n", elapsed)
}
func genMat(row int, col int, ch chan<- [][]int, wg *sync.WaitGroup) {
    nM := make([][]int, col)
    for i := 0; i < col; i++ {
        nM[i] = make([]int, row)
    }
    generateNums(nM)
    wg.Done()
    ch <- nM
}
func generateNums(randMatrix [][]int) {
    for i, innerArray := range randMatrix {
        for j := range innerArray {
            randMatrix[i][j] = rand.Intn(100)
        }
    }
}
func rowCount(inM [][]int) int {
    return (len(inM))
}
func colCount(inM [][]int) int {
    return (len(inM[0]))
}
func doCalc(inA [][]int, inB [][]int) [][]int {
    var i, j int
    var wg sync.WaitGroup
    chC := make(chan [][]int)
    m := rowCount(inA) // number of rows the first matrix
    p := rowCount(inB) // number of rows the second matrix
    q := colCount(inB) // number of columns the second matrix
    k := 0
    total := 0
    var nM [][]int
    wg.Add(1)
    go genMat(m, q, chC, &wg)
    nM = <-chC
    wg.Wait()
    for i = 0; i < m; i++ {
        for j = 0; j < q; j++ {
            for k = 0; k < p; k++ {
                total = total + inA[i][k]*inB[k][j]
            }
            nM[i][j] = total
            total = 0
        }
        fmt.Println()
    }
    return nM
}

我正在使用 Go Routines 来优化执行。两个 go 例程用于随机生成矩阵 A 和 Matrix B,另一个用于计算结果 Matrix C

总执行时间平均约为 2.4 毫秒。但我想让它在 1 到 2 毫秒之间,甚至更短。

任何人都可以通过利用 go 例程而不使用内置函数来建议代码中的优化领域吗:)

go concurrency matrix-multiplication goroutine
1个回答
1
投票

为什么不使用默认的库包?

https://pkg.go.dev/gonum.org/v1/gonum/mat

我实现了,它比你的算法更快(~1.1ms,多次运行结果在下面)。

代码:

package main

import (
    "fmt"
    "math/rand"
    "time"
    "gonum.org/v1/gonum/mat"
)

func main() {
    const matrixSize = 150
    matrixA := generateRandomMatrix(matrixSize, matrixSize)
    matrixB := generateRandomMatrix(matrixSize, matrixSize)

    A := mat.NewDense(matrixSize, matrixSize, matrixA)
    B := mat.NewDense(matrixSize, matrixSize, matrixB)
    C := mat.NewDense(matrixSize, matrixSize, nil)
    start := time.Now()
    C.Mul(A, B)
    elapsed := time.Since(start)
    fmt.Printf("Duration %s\n", elapsed)
}

func generateRandomMatrix(rows, cols int) []float64 {
    matrix := make([]float64, rows*cols)
    for i := range matrix {
        matrix[i] = rand.Float64()
    }
    return matrix
}

经过的持续时间(多次运行):

Duration 1.4275ms
Duration 1.0722ms
Duration 1.3446ms
Duration 1.1604ms
Duration 1.0194ms
Duration 596.3µs
Duration 1.2118ms
Duration 925.2µs
Duration 1.3754ms
© www.soinside.com 2019 - 2024. All rights reserved.