2017-03-06 44 views
1

我目前正在開發一個工作,它可以按順序並行地運行圖像處理。我試圖找出工作速度作爲我的指標的一部分,但我無法在網上找到公式或有關它的更多信息,在並行計算中計算工作率Golang

有沒有人有計算工作速率所需的等式?

編輯:

這是我的主要功能,它有度量計算,如果這有幫助嗎?我知道有可能有更好的方式來獲得某些數據,但是有一些反覆試驗讓我對此有所瞭解。

runtime.GOMAXPROCS(4) 

file, err := os.Open("space.jpg") 
if err != nil { 
    log.Fatal(err) 
} 
defer file.Close() 

img, err := jpeg.Decode(file) 
if err != nil { 
    log.Fatal(os.Stderr, "%s: %v\n", "space.jpg", err) 
} 
for i:= 0; i<10; i++{ 
TSeqStart := time.Now() 
b := img.Bounds() 
imgSet := image.NewRGBA(b) 
for y := 0; y < b.Max.Y; y++ { 
    for x := 0; x < b.Max.X; x++ { 
     oldPixel := img.At(x, y) 
    r, g, b, _ := oldPixel.RGBA() 
    lum := 0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b) 
    pixel := color.Gray{uint8(lum/256)} 
    imgSet.Set(x, y, pixel) 
    } 
    } 
    TSeq := time.Since(TSeqStart) 
    //ns := TSeq.Nanoseconds() 

    avgSeq = avgSeq +TSeq 
    fmt.Printf("\nTime in ns (Sequential): " , TSeq) 
    outFile, err := os.Create("changed.jpg") 
    if err != nil { 
    log.Fatal(err) 
    } 
    defer outFile.Close() 
    jpeg.Encode(outFile, imgSet, nil) 

} 
avgSeq = avgSeq/10 

fmt.Print("\n\nAverage sequential time for 10 runs: ", avgSeq) 
    //parallel version 
    file2, err := os.Open("space.jpg") 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer file.Close() 

    img2, err := jpeg.Decode(file2) 
    if err != nil { 
     log.Fatal(os.Stderr, "%s: %v\n", "space.jpg", err) 
    } 

    for j:=1;j<=4;j++{ 
     runtime.GOMAXPROCS(j) 


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

    TParStart:= time.Now() 
    imgSet2 := imgprocess(img2, runtime.NumCPU(), splitVert(1024), rgbtogrey) 
    TPar := time.Since(TParStart) 
    //ns2 := TPar.Nanoseconds() 

    avgPar = avgPar +TPar 
    fmt.Print("\nTime in Nanoseconds (Parallel) with GOMAXPROCS set at ",j ,": " , TPar) 

    outFile2, err := os.Create("changed2.jpg") 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer outFile2.Close() 
    jpeg.Encode(outFile2, imgSet2, nil) 

     if err != nil { 
      log.Fatalf("encoding image: %v", err) 
     } 
    } 
    avgPar = avgPar/10 
    fmt.Print("\n\nAverage time for 10 runs in parallel (GOMAXPROCS:",j,"): ", avgPar) 
    var j64 time.Duration 
    j64 = time.Duration(j) 
    totalPar := j64*avgPar 
    fmt.Print("\n\nTotal Parallel time: ", totalPar) 

     speedup := avgSeq.Seconds()/avgPar.Seconds() 

     fmt.Printf("\n\nSpeed up: %f", speedup) 

     var jfloat float64 
     jfloat = float64(j) 
     theoreticalMin := avgSeq.Seconds()/jfloat 
     fmt.Print("\n\nTheoretical Minimum: ", theoreticalMin,"ms") 

    var tPFloat float64 
    tPFloat = float64(totalPar) 
     efficiency := avgSeq.Seconds()/tPFloat 
     fmt.Print("\n\n Efficiency: ", efficiency,"%") 

     overhead := totalPar - avgSeq 
     fmt.Print("\n\nOverhead time: ", overhead ,"\n") 
+0

您對衡量工作率感興趣的幅度是多少?隨着時間的推移像素可能?未經處理的原始圖像數據? –

+0

如果您已經在計算指標,您有沒有確定費率的方法?您使用什麼系統來收集指標? – JimB

+0

目前我正在運行我的圖像處理,每次運行10次並計算平均值。然後,我使用GOMAXPROCS 1運行10次並行版本,然後使用10次運行我的並行版本,設置爲2,依此類推。我也計算每次的平均時間。我正在從我收集的數據中計算總並行時間,理論最小值,加速時間和開銷時間。不過,我不確定如何計算工作費率。我發現公式費率=工作/時間,但現在肯定如何解釋這一點。 – benjano

回答

2

首先,我試圖解釋發生了什麼事情在這裏(NumCPU = 4):

package main 

import (
    "image" 
    "image/color" 
    "image/jpeg" 
    "os" 
    "testing" 
) 

func changeImage(img image.Image) { 
    b := img.Bounds() 
    imgSet := image.NewRGBA(b) 
    for y := 0; y < b.Max.Y; y++ { 
     for x := 0; x < b.Max.X; x++ { 
      oldPixel := img.At(x, y) 
      r, g, b, _ := oldPixel.RGBA() 
      lum := 0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b) 
      pixel := color.Gray{uint8(lum/256)} 
      imgSet.Set(x, y, pixel) 
     } 
    } 
} 

func BenchmarkParallel(b *testing.B) { 
    file, err := os.Open("space.jpg") 
    if err != nil { 
     b.Fatal(err) 
    } 
    defer file.Close() 
    img, err := jpeg.Decode(file) 
    if err != nil { 
     b.Fatal(err) 
    } 

    b.ReportAllocs() 
    b.RunParallel(func(pb *testing.PB) { 
     for pb.Next() { 
      changeImage(img) 
     } 
    }) 
} 

func BenchmarkSingle(b *testing.B) { 
    file, err := os.Open("space.jpg") 
    if err != nil { 
     b.Fatal(err) 
    } 
    defer file.Close() 
    img, err := jpeg.Decode(file) 
    if err != nil { 
     b.Fatal(err) 
    } 

    b.ReportAllocs() 
    b.ResetTimer() 
    for i := 0; i < b.N; i++ { 
     changeImage(img) 
    } 
} 

輸出:

$ go test -bench=. -cpu=1,2,4,6 
goos: linux 
goarch: amd64 
pkg: so/space 
BenchmarkParallel  50 22901501 ns/op  2296662 B/op  571021 allocs/op 
BenchmarkParallel-2  100 11599582 ns/op  2290637 B/op  571021 allocs/op 
BenchmarkParallel-4  200 10631362 ns/op  2287631 B/op  571021 allocs/op 
BenchmarkParallel-6  200 10916331 ns/op  2287629 B/op  571021 allocs/op 
BenchmarkSingle   50 23645522 ns/op  2284582 B/op  571021 allocs/op 
BenchmarkSingle-2  50 23158899 ns/op  2284584 B/op  571021 allocs/op 
BenchmarkSingle-4  50 31069104 ns/op  2284589 B/op  571021 allocs/op 
BenchmarkSingle-6  50 28026326 ns/op  2284586 B/op  571021 allocs/op 
PASS 
ok  so/space 14.047s 

附錄:

接下來,閱讀相關文件。

The Go image package

Package image

Package color

修正錯誤,併爲一個優化版本的改進。將優化後的版本與我們之前建立的基準進行比較。

package main 

import (
    "image" 
    "image/color" 
    "image/jpeg" 
    "os" 
    "testing" 
) 

func changeImageOpt(img image.Image) *image.RGBA { 
    b := img.Bounds() 
    imgSet := image.NewRGBA(b) 
    for y := b.Min.Y; y < b.Max.Y; y++ { 
     for x := b.Min.X; x < b.Max.X; x++ { 
      r, g, b, _ := img.At(x, y).RGBA() 
      lum := 0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b) 
      r, g, b, a := color.Gray{uint8(lum/256)}.RGBA() 
      rgba := color.RGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: uint8(a)} 
      imgSet.SetRGBA(x, y, rgba) 
     } 
    } 
    return imgSet 
} 

func BenchmarkSingleOpt(b *testing.B) { 
    file, err := os.Open("space.jpg") 
    if err != nil { 
     b.Fatal(err) 
    } 
    defer file.Close() 
    img, err := jpeg.Decode(file) 
    if err != nil { 
     b.Fatal(err) 
    } 

    b.ReportAllocs() 
    b.ResetTimer() 
    for i := 0; i < b.N; i++ { 
     changeImageOpt(img) 
    } 
} 

輸出:

$ go test -bench=Single -cpu=2 
goos: linux 
goarch: amd64 
pkg: so/space 
BenchmarkSingle-2  20 84970866 ns/op  2284584 B/op  571021 allocs/op 
BenchmarkSingleOpt-2  30 48353165 ns/op  1371010 B/op  190342 allocs/op 
PASS 
ok  so/space 4.648s 

繼文檔中的說明,我們在CPU時間和內存分配一個顯著減少。

並行基準測試(NumCPU = 4)有相應的改進。

$ go test -bench=Parallel -cpu=1,2,3,4,6 
goos: linux 
goarch: amd64 
pkg: so/space 
BenchmarkParallel  20 87135554 ns/op  2314774 B/op  571021 allocs/op 
BenchmarkParallel-2  30 46567417 ns/op  2304732 B/op  571021 allocs/op 
BenchmarkParallel-3  30 43262344 ns/op  2304736 B/op  571021 allocs/op 
BenchmarkParallel-4  30 42593397 ns/op  2304763 B/op  571021 allocs/op 
BenchmarkParallel-6  30 40803415 ns/op  2304804 B/op  571021 allocs/op 
BenchmarkParallelOpt  30 47932887 ns/op  1391139 B/op  190342 allocs/op 
BenchmarkParallelOpt-2 50 25216902 ns/op  1383094 B/op  190342 allocs/op 
BenchmarkParallelOpt-3 50 23723356 ns/op  1383099 B/op  190342 allocs/op 
BenchmarkParallelOpt-4 50 22400713 ns/op  1383101 B/op  190342 allocs/op 
BenchmarkParallelOpt-6 50 22250405 ns/op  1383100 B/op  190342 allocs/op 
PASS 
ok  so/space 19.662s 
+0

嗨,彼得,謝謝你的答案!現在全部學習並學習很多東西。親切的問候 – benjano