<p>I'm trying to fill an array or slice in parallel this way:</p>
<pre><code>package main
import (
"runtime"
)
const (
NGoRoutines = 4
)
var array [100000000]int
func main() {
c := make(chan int, NGoRoutines)
runtime.GOMAXPROCS(NGoRoutines)
for i := 0; i < NGoRoutines; i++ {
go func(id int) {
for j := id; j < len(array); j = j + NGoRoutines {
array[j] = j
}
c <- 1
}(i)
}
// wait for goroutines to finish
for i := 0; i < NGoRoutines; i++ {
<-c
}
}
</code></pre>
<p>The resulting array is as expected (0, 1, 2, 3...)</p>
<p>But i'm not gaining any performance over using just one goroutine. I wrote equivalent program in C and it works. So I assume that you can't access elements of one array in parallel in Go. What would be the best way to achieve this in Go?</p>
<hr/>**评论:**<br/><br/>teepark: <pre><p>You might break up the array into NGoRoutine contiguous sections so they aren't all writing to the same memory pages. See if that helps.</p>
<p>Also look into sync.WaitGroup, it could simplify your final wait.</p></pre>danielt0shea: <pre><p>I think the problem is the four go-routines are doing a lot of redundant work. I think you want to break the array up into NGoRoutine chunks and have each go-routine write to that section in parallel, not have them overlap. Here is a quick and dirty version that on my machine is about twice as fast as the original version:</p>
<pre><code>package main
import (
"runtime"
)
const (
NGoRoutines = 4
)
var array [100000000]int
func main() {
c := make(chan int, NGoRoutines)
runtime.GOMAXPROCS(NGoRoutines)
chunk := len(array) / NGoRoutines
for i := 0; i < NGoRoutines; i++ {
go func(start int) {
end := start + chunk
if end > len(array) {
end = len(array)
}
for j := start; j < end; j = j + 1 {
array[j] = j
}
c <- 1
}(i * chunk)
}
// wait for goroutines to finish
for i := 0; i < NGoRoutines; i++ {
<-c
}
}
</code></pre>
<p>running this code gives me:</p>
<pre><code>$ time ./parallel-fill
real 0m0.234s
user 0m0.156s
sys 0m0.266s
</code></pre>
<p>vs the original:</p>
<pre><code>$ time ./parallel-fill-orig
real 0m0.431s
user 0m0.377s
sys 0m0.235s
</code></pre>
<p>Hope that helps.</p></pre>Fwippy: <pre><p>They're running in parallel and writing to the array in parallel; I think it's just that your functions are doing so little work per loop that you really don't see much gain. </p>
<p>You can add a <code>time.Sleep()</code> call in there or a busy-loop to simulate a more complicated computation. This version here worked well for me in showing the difference in goroutines: <a href="https://play.golang.org/p/JogUNCX19d" rel="nofollow">https://play.golang.org/p/JogUNCX19d</a> (copy and paste; it won't be useful to run on playground).</p>
<p>There's also the possibility that you're running on a CPU with only one core, if your machine is old, or a raspberry pi, or similar.</p></pre>dchapes: <pre><blockquote>
<p>copy and paste</p>
</blockquote>
<p>FYI, you can add <code>.go</code> to the end of a play.golang.org link to get a download-able/save-able version of the source: <a href="https://play.golang.org/p/JogUNCX19d.go" rel="nofollow">https://play.golang.org/p/JogUNCX19d.go</a></p></pre>Fwippy: <pre><p>Nifty!</p></pre>Manbeardo: <pre><p>Also, older versions of go have GOMAXPROCS=1 by default.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传