第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 goroutine 和通道的“矩陣乘法”

使用 goroutine 和通道的“矩陣乘法”

Go
倚天杖 2022-04-20 19:25:01
當(dāng)我使用 1 個 goroutine、2 個 goroutine、3 個等等時,我有一個大學(xué)項(xiàng)目來測試矩陣乘法的時間差。我必須使用渠道。我的問題是,無論我添加多少 goroutine,編譯時間幾乎總是相同的。也許有人能說出問題出在哪里。也許發(fā)送時間很長,并且一直在發(fā)送。代碼如下package mainimport (    "fmt"    "math/rand"    "time")const length = 1000var start time.Timevar rez [length][length]intfunc main() {    const threadlength = 1    toCalcRow := make(chan []int)    toCalcColumn := make(chan []int)    dummy1 := make(chan int)    dummy2 := make(chan int)    var row [length + 1]int    var column [length + 1]int    var a [length][length]int    var b [length][length]int    for i := 0; i < length; i++ {        for j := 0; j < length; j++ {            a[i][j] = rand.Intn(10)            b[i][j] = rand.Intn(10)        }    }    for i := 0; i < threadlength; i++ {        go Calc(toCalcRow, toCalcColumn, dummy1, dummy2)    }    start = time.Now()    for i := 0; i < length; i++ {        for j := 0; j < length; j++ {            row[0] = i            column[0] = j            for k := 0; k < length; k++ {                row[k+1] = a[i][j]                column[k+1] = b[i][k]            }            rowSlices := make([]int, len(row))            columnSlices := make([]int, len(column))            copy(rowSlices, row[:])            copy(columnSlices, column[:])            toCalcRow <- rowSlices            toCalcColumn <- columnSlices        }    }    dummy1 <- -1    for i := 0; i < length; i++ {        for j := 0; j < length; j++ {            fmt.Print(rez[i][j])            fmt.Print(" ")        }        fmt.Println(" ")    }    <-dummy2    close(toCalcRow)    close(toCalcColumn)    close(dummy1)}func Calc(chin1 <-chan []int, chin2 <-chan []int, dummy <-chan int, dummy1 chan<- int) {loop:    for {        select {        case row := <-chin1:            column := <-chin2            var sum [3]int            sum[0] = row[0]            sum[1] = column[0]            for i := 1; i < len(row); i++ {                sum[2] += row[i] * column[i]            }
查看完整描述

2 回答

?
慕妹3146593

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超9個贊

您看不到差異,因?yàn)闇?zhǔn)備數(shù)據(jù)以傳遞給 go 例程是您的瓶頸。它比執(zhí)行計算更慢或一樣快。


傳遞行和列的副本不是一個好的策略。這正在扼殺表演。


go 例程可以直接從只讀輸入矩陣中讀取數(shù)據(jù)。這里沒有可能的競爭條件。


輸出也一樣。如果 go 例程計算行和列的乘積,它會將結(jié)果寫入不同的單元格。這里也沒有可能的競爭條件。


要做的事情如下。定義一個包含兩個字段的結(jié)構(gòu),一個用于行,一個用于要相乘的列。


用所有可能的行和列組合填充緩沖通道,以從 (0,0) 乘到 (n-1,m-1)。


go 例程使用通道中的結(jié)構(gòu),執(zhí)行計算并將結(jié)果直接寫入輸出矩陣。


然后,您還有一個 done 通道向主 go 例程發(fā)出計算已完成的信號。當(dāng) goroutine 完成對結(jié)構(gòu) (n-1,m-1) 的處理時,它會關(guān)閉 done 通道。


編寫完所有結(jié)構(gòu)后,主 go 例程在 done 通道上等待。一旦完成通道關(guān)閉,它就會打印經(jīng)過的時間。我們可以使用一個等待組來等待所有的 goroutine 終止他們的計算。


然后,您可以從一個 goroutine 開始,并增加 goroutine 的數(shù)量,以查看處理時間的影響。


見代碼:


package main


import (

    "fmt"

    "math/rand"

    "sync"

    "time"

)


type pair struct {

    row, col int

}


const length = 1000


var start time.Time

var rez [length][length]int


func main() {

    const threadlength = 1

    pairs := make(chan pair, 1000)

    var wg sync.WaitGroup

    var a [length][length]int

    var b [length][length]int

    for i := 0; i < length; i++ {

        for j := 0; j < length; j++ {

            a[i][j] = rand.Intn(10)

            b[i][j] = rand.Intn(10)

        }

    }

    wg.Add(threadlength)

    for i := 0; i < threadlength; i++ {

        go Calc(pairs, &a, &b, &rez, &wg)

    }

    start = time.Now()

    for i := 0; i < length; i++ {

        for j := 0; j < length; j++ {

            pairs <- pair{row: i, col: j}

        }

    }

    close(pairs)

    wg.Wait()

    elapsed := time.Since(start)

    fmt.Println("Binomial took ", elapsed)


    for i := 0; i < length; i++ {

        for j := 0; j < length; j++ {

            fmt.Print(rez[i][j])

            fmt.Print(" ")

        }

        fmt.Println(" ")

    }

}


func Calc(pairs chan pair, a, b, rez *[length][length]int, wg *sync.WaitGroup) {

    for {

        pair, ok := <-pairs

        if !ok {

            break

        }

        rez[pair.row][pair.col] = 0

        for i := 0; i < length; i++ {

            rez[pair.row][pair.col] += a[pair.row][i] * b[i][pair.col]

        }

    }

    wg.Done()

}


查看完整回答
反對 回復(fù) 2022-04-20
?
慕哥6287543

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超10個贊

您的代碼很難理解(調(diào)用變量 dummy1/dummy2 會讓人感到困惑,特別是當(dāng)它們在 中獲得不同的名稱時Calc)并且添加一些注釋會使它更容易理解。


首先是一個錯誤。在發(fā)送要計算的數(shù)據(jù)之后dummy1 <- -1,我相信您希望這會等待所有計算完成。但是,當(dāng)您有多個 goroutine 時,情況不一定如此。通道將被其中一個 goroutine 耗盡,并打印出計時信息;其他 goroutine 仍將運(yùn)行(并且可能尚未完成計算)。


在時間方面,我懷疑您向 go 例程發(fā)送數(shù)據(jù)的方式會減慢速度;您發(fā)送行,然后發(fā)送列;因?yàn)橥ǖ罌]有緩沖,所以 goroutine 將在等待列時阻塞(切換回主 goroutine 以發(fā)送列)。這種來回會減慢你的 goroutines 獲取數(shù)據(jù)的速度,并且可以很好地解釋為什么添加額外的 goroutines 影響有限(如果你使用緩沖通道也會變得危險)。


我已將您的代碼(注意可能存在錯誤,而且遠(yuǎn)非完美?。┲貥?gòu)為確實(shí)顯示出差異的東西(在我的計算機(jī)上 1 goroutine = 10s; 5 = 7s):


package main


import (

    "fmt"

    "math/rand"

    "sync"

    "time"

)


const length = 1000


var start time.Time

var rez [length][length]int


// toMultiply will hold details of what the goroutine will be multiplying (one row and one column)

type toMultiply struct {

    rowNo    int

    columnNo int

    row      []int

    column   []int

}


func main() {

    const noOfGoRoutines = 5


    // Build up a matrix of dimensions (length) x (length)

    var a [length][length]int

    var b [length][length]int

    for i := 0; i < length; i++ {

        for j := 0; j < length; j++ {

            a[i][j] = rand.Intn(10)

            b[i][j] = rand.Intn(10)

        }

    }


    // Setup completed so start the clock...

    start = time.Now()


    // Start off threadlength go routines to multiply each row/column

    toCalc := make(chan toMultiply)

    var wg sync.WaitGroup

    wg.Add(noOfGoRoutines)

    for i := 0; i < noOfGoRoutines; i++ {

        go func() {

            Calc(toCalc)

            wg.Done()

        }()

    }


    // Begin the multiplication.

    start = time.Now()

    for i := 0; i < length; i++ {

        for j := 0; j < length; j++ {

            tm := toMultiply{

                rowNo:    i,

                columnNo: j,

                row:      make([]int, length),

                column:   make([]int, length),

            }


            for k := 0; k < length; k++ {

                tm.row[k] = a[i][j]

                tm.column[k] = b[i][k]

            }

            toCalc <- tm

        }

    }


    // All of the data has been sent to the chanel; now we need to wait for all of the

    // goroutines to complete

    close(toCalc)

    wg.Wait()


    fmt.Println("Binomial took ", time.Since(start))


    // The full result should be in tz

    for i := 0; i < length; i++ {

        for j := 0; j < length; j++ {

            //fmt.Print(rez[i][j])

            //fmt.Print(" ")

        }

        //fmt.Println(" ")

    }

}


// Calc - Multiply a row from one matrix with a column from another

func Calc(toCalc <-chan toMultiply) {

    for tc := range toCalc {

        var result int

        for i := 0; i < len(tc.row); i++ {

            result += tc.row[i] * tc.column[i]

        }

        // warning - the below should work in this case but be careful writing to global variables from goroutines

        rez[tc.rowNo][tc.columnNo] = result

    }

}


查看完整回答
反對 回復(fù) 2022-04-20
  • 2 回答
  • 0 關(guān)注
  • 136 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號