Вопрос раскрывает механизм планирования горутин и влияние GOMAXPROCS на производительность.
Планировщик Go распределяет горутины по потокам ОС. GOMAXPROCS задаёт максимальное число потоков для CPU-bound задач (по умолчанию = числу ядер). Для I/O-bound задач горутины могут работать на меньшем числе потоков.
Планировщик Go использует M:N модель, где M горутин работают на N потоках ОС.
Основные компоненты:
G (Goroutine) — выполняемая задача.
M (Machine) — поток ОС.
P (Processor) — контекст выполнения (до GOMAXPROCS штук).
Роль GOMAXPROCS:
Определяет, сколько потоков ОС (M) могут одновременно выполнять CPU-bound код.
По умолчанию равно runtime.NumCPU().
Пример:
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("Текущий GOMAXPROCS:", runtime.GOMAXPROCS(0)) // По умолчанию = ядрам CPU
runtime.GOMAXPROCS(1) // Ограничиваем одним потоком
// Далее горутины будут выполняться на одном ядре
}Когда менять GOMAXPROCS:
Увеличить: если CPU-bound задачи не используют все ядра.
Уменьшить: для снижения накладных расходов на переключение.
Вывод:GOMAXPROCS балансирует между использованием CPU и накладными расходами.