Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 为什么goroutine在多核上分配较慢?_Multithreading_Go - Fatal编程技术网

Multithreading 为什么goroutine在多核上分配较慢?

Multithreading 为什么goroutine在多核上分配较慢?,multithreading,go,Multithreading,Go,我在围棋中做了一些实验,发现了一些非常奇怪的东西。当我在计算机上运行以下代码时,它将在约0.5秒内执行 package main import ( "fmt" "runtime" "time" ) func waitAround(die chan bool) { <- die } func main() { var startMemory runtime.MemStats runtime.ReadMemStats(&startMemory) star

我在围棋中做了一些实验,发现了一些非常奇怪的东西。当我在计算机上运行以下代码时,它将在约0.5秒内执行

package main

import (
  "fmt"
  "runtime"
  "time"
)
func waitAround(die chan bool) {
  <- die
}
func main() {
  var startMemory runtime.MemStats
  runtime.ReadMemStats(&startMemory)

  start := time.Now()
  cpus := runtime.NumCPU()
  runtime.GOMAXPROCS(cpus)
  die := make(chan bool)
  count := 100000
  for i := 0; i < count; i++ {
    go waitAround(die)
  }
  elapsed := time.Since(start)

  var endMemory runtime.MemStats
  runtime.ReadMemStats(&endMemory)

  fmt.Printf("Started %d goroutines\n%d CPUs\n%f seconds\n",
    count, cpus, elapsed.Seconds())
  fmt.Printf("Memory before %d\nmemory after %d\n", startMemory.Alloc,
    endMemory.Alloc)
  fmt.Printf("%d goroutines running\n", runtime.NumGoroutine())
  fmt.Printf("%d bytes per goroutine\n", (endMemory.Alloc - startMemory.Alloc)/uint64(runtime.NumGoroutine()))

  close(die)
}
主程序包
进口(
“fmt”
“运行时”
“时间”
)
func waitAround(die chan bool){

在多核上衡量性能总是很困难的,除非在多核上工作会带来很大的工作量。问题是代码需要在线程和核之间共享,这意味着虽然可能不会有很大的开销,但仍然有很大的开销,特别是对于简单的代码,降低了整体性能


就像你提到的,如果你做一些CPU密集型的事情,情况会完全不同。

在单核上运行时,goroutine分配和切换只是一个内部会计问题。goroutine从不被抢占,因此切换逻辑非常简单且非常快。更重要的是,在这种情况下,你的in例程根本不屈服,因此Goroutine在终止之前甚至从未开始执行。您分配结构,然后将其删除,就是这样。(edit对于较新版本的go,这可能不正确,但对于只有一个进程的go,它肯定更有序)

但是当你在多个线程上映射例程时,你会突然涉及到操作系统级别的上下文切换,这是一个数量级的速度慢和复杂度高的问题。即使你在多个内核上,也有很多工作要做。另外,现在你的gouroutines可能在程序终止之前就已经运行了


尝试在这两种情况下对程序进行扫描,看看它的行为有何不同。

我意识到goroutines没有做任何事情,如果我不得不等待例程真正做些什么,情况可能会有所不同。
--宾果。