Задать вопрос
@markinaras

Почему Go с горутинами работает на одном ядре?

Написал тест,чтобы проверить работу процессора с горутинами. Ожидал,что все ядра загрузятся. А в этоге увидел,что пока 1 ядро пашет на 100%,то остальные отдыхают. Может кто знает в чем ошибка?

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()
}
  • Вопрос задан
  • 302 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
EvgenyMamonov
@EvgenyMamonov Куратор тега Go
Senior software developer, system architect
Горутины выполняются на разных процессорах как и должны, у вас четвёртое число слишком большое, все горутины завершают выполнение, а одна продолжает работать. По этому и создаётся впечатление, что они все работают на одном ядре.

Чтобы в этом убедиться добавим два fmt.Printf, чтобы получилось вот так
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()
}


Вывод будет примерно таким
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

При внимательном просмотре станет видно, что нет записи 3 completed.

меняю элементы с индексами 4 и 5 на такие же числа 334343434000, 334343434000, т.е. делаем чтобы все горутины отработали, но чтобы 3 осталось, т.е. вот так

arr := []int{1343434, 1343434300, 234343400, 334343434000, 334343434000, 334343434000, 4232, 23545, 15535, 353535, 33434434, 5334345, 3533434345, 3535}


Запускаем заново и видим, что теперь 3 ядра отлично загружены
%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
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы