Функция runtime.NumCPU
Функция runtime.NumCPU возвращает количество логических процессоров,
доступных текущей Go-программе. Обычно это значение соответствует количеству
ядер процессора (включая гиперпоточность), которое операционная система
видит для выполнения потоков. Функция не принимает никаких параметров
и возвращает целое число типа int.
Синтаксис
runtime.NumCPU()
Пример с базовым использованием
Давайте получим количество логических процессоров и выведем его на экран:
package main
import (
"fmt"
"runtime"
)
func main() {
cpuCount := runtime.NumCPU()
fmt.Println(cpuCount)
}
Результат выполнения кода:
8
В зависимости от аппаратной конфигурации вашего компьютера, вывод может отличаться. Например, на машине с 4-ядерным процессором и гиперпоточностью функция вернет 8.
Пример с параллельными вычислениями
Давайте используем количество процессоров для оптимального распределения задач между воркерами:
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
numCPU := runtime.NumCPU()
fmt.Printf("CPU count: %d\n", numCPU)
var wg sync.WaitGroup
chunkSize := 100 / numCPU
for i := 0; i < numCPU; i++ {
wg.Add(1)
go func(workerID int) {
defer wg.Done()
start := workerID * chunkSize
end := start + chunkSize
fmt.Printf("Worker %d processes range [%d, %d)\n",
workerID, start, end)
}(i)
}
wg.Wait()
}
Результат выполнения кода:
"CPU count: 8"
"Worker 0 processes range [0, 12)"
"Worker 1 processes range [12, 24)"
"Worker 2 processes range [24, 36)"
"Worker 3 processes range [36, 48)"
"Worker 4 processes range [48, 60)"
"Worker 5 processes range [60, 72)"
"Worker 6 processes range [72, 84)"
"Worker 7 processes range [84, 96)"
Пример с настройкой GOMAXPROCS
Значение, возвращаемое runtime.NumCPU, часто используется
для установки максимального количества параллельных процессов
через runtime.GOMAXPROCS:
package main
import (
"fmt"
"runtime"
)
func main() {
numCPU := runtime.NumCPU()
runtime.GOMAXPROCS(numCPU)
fmt.Println(runtime.GOMAXPROCS(0))
}
Результат выполнения кода:
8
Вызов runtime.GOMAXPROCS(0) возвращает текущее значение,
не изменяя его. Обычно Go автоматически использует все
доступные процессоры, поэтому явный вызов runtime.GOMAXPROCS
требуется редко.
Пример с пулом воркеров
Создадим пул воркеров с размером, равным количеству процессоров:
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
const tasks = 20
numWorkers := runtime.NumCPU()
taskCh := make(chan int, tasks)
var wg sync.WaitGroup
for w := 0; w < numWorkers; w++ {
wg.Add(1)
go func(workerID int) {
defer wg.Done()
for task := range taskCh {
fmt.Printf("Worker %d processed task %d\n",
workerID, task)
}
}(w)
}
for t := 0; t < tasks; t++ {
taskCh <- t
}
close(taskCh)
wg.Wait()
}
Результат выполнения кода:
"Worker 0 processed task 0"
"Worker 0 processed task 1"
"Worker 0 processed task 2"
"Worker 1 processed task 3"
"Worker 1 processed task 4"
"Worker 2 processed task 5"
"Worker 2 processed task 6"
"Worker 3 processed task 7"
"Worker 3 processed task 8"
"Worker 4 processed task 9"
"Worker 4 processed task 10"
"Worker 5 processed task 11"
"Worker 5 processed task 12"
"Worker 6 processed task 13"
"Worker 6 processed task 14"
"Worker 7 processed task 15"
"Worker 7 processed task 16"
"Worker 0 processed task 17"
"Worker 1 processed task 18"
"Worker 2 processed task 19"
Количество воркеров соответствует количеству доступных процессоров, что позволяет эффективно утилизировать аппаратные ресурсы системы.
Смотрите также
-
функцию
runtime.GOMAXPROCS,
которая управляет количеством одновременно выполняющихся потоков Go -
функцию
runtime.NumGoroutine,
которая возвращает количество активных горутин в текущий момент -
функцию
runtime.GC,
которая запускает сборку мусора -
функцию
runtime.Goexit,
которая завершает выполнение текущей горутины