M
M
markinaras2022-01-04 20:25:47
go
markinaras, 2022-01-04 20:25:47

Why does Go with goroutines run on a single core?

I wrote a test to check the work of the processor with goroutines. I expected all kernels to boot. And in this I saw that while 1 core plows 100%, then the rest are resting. Maybe someone knows what is wrong?

package main

import (
  "fmt"
  "runtime"
  "sync"
)

var wg sync.WaitGroup

func main() {
runtime.GOMAXPROCS(8)
arr:=[]int{1343434,1343434300,234343400,334343434000,400434340,203434340,4232,23545,15535,353535,33434434,5334345,3533434345,3535}
  for _,el:=range arr{
    wg.Add(1)
    go test(el)
  }
  wg.Wait()
}

func test(el int){
  for i:=0;i<el;i++{
  el=el-1
  }
  defer wg.Done()
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Evgeny Mamonov, 2022-01-05
@markinaras

Goroutines run on different processors as they should, your fourth number is too big, all goroutines finish executing, but one continues to run. Therefore, it seems that they all work on the same core.
To make sure of this, let's add two fmt.Printf to make it look like this

package main

import (
    "fmt"
    "runtime"
    "sync"
)

var wg sync.WaitGroup

func main() {
    runtime.GOMAXPROCS(8)
    arr := []int{1343434, 1343434300, 234343400, 334343434000, 400434340, 203434340, 4232, 23545, 15535, 353535, 33434434, 5334345, 3533434345, 3535}
    for idx, el := range arr {
        wg.Add(1)
        go test(el, idx)
    }
    wg.Wait()
}

func test(el int, idx int) {
    fmt.Printf("%d started: %d\n", idx, el)
    for i := 0; i < el; i++ {
        el = el - 1
    }
    fmt.Printf("%d completed: %d\n", idx, el)
    defer wg.Done()
}

The output will be something like this
4 started: 400434340
8 started: 15535
8 completed: 7767
13 started: 3535
13 completed: 1767
6 started: 4232
6 completed: 2116
10 started: 33434434
3 started: 334343434000
7 started: 23545
7 completed: 11772
5 started: 203434340
12 started: 3533434345
11 started: 5334345
2 started: 234343400
1 started: 1343434300
11 completed: 2667172
9 started: 353535
9 completed: 176767
0 started: 1343434
0 completed: 671717
10 completed: 16717217
5 completed: 101717170
4 completed: 200217170
2 completed: 117171700
1 completed: 671717150
12 completed: 1766717172

If you look closely, you will see that there is no 3 completed entry.
I change elements with indices 4 and 5 to the same numbers 334343434000, 334343434000, i.e. we do so that all goroutines work, but that 3 remain, i.e. like this
arr := []int{1343434, 1343434300, 234343400, 334343434000, 334343434000, 334343434000, 4232, 23545, 15535, 353535, 33434434, 5334345, 3533434345, 3535}

We start again and see that now 3 cores are perfectly loaded
%Cpu0  :  0.3 us,  1.0 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  1.7 us,  0.7 sy,  0.0 ni, 97.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  1.6 us,  2.9 sy,  0.0 ni, 95.5 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  :100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  :  5.6 us,  1.0 sy,  0.0 ni, 93.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question