Excesso de threads e troca de contexto Thread oversubscription, context switching
ID da causa so-context · Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de servidores (Equipe de infraestrutura)
Com muito mais threads do que núcleos, o SO gasta CPU só para revezar as threads na execução.
Por quê Centenas a milhares de threads, por exemplo, uma thread por conexão → Efeito Sobem o custo da troca de contexto (troca da thread em execução) e os cache misses → Na tela CPU ocupada, mas com pouca vazão e ticks irregulares: engasgos e câmera lenta
Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento) · Também envolvidos Infraestrutura de servidores (Equipe de infraestrutura)
O que fazer (Equipe de desenvolvimento)
Ajustar o número de threads ao número de núcleos, usar I/O assíncrono (epoll ou IOCP).
O que fazer (Equipe de infraestrutura)
Monitorar o número de trocas de contexto e de threads esperando para rodar (cs e r no vmstat).
Números de referência
Cada troca de contexto custa alguns µs, e mais ainda somando os cache misses que vêm depois.
No gráfico
Sobe com a carga · Trocas de contexto por segundo, threads esperando para rodar
Onde olhar
Comparar o cs (trocas de contexto por segundo) e o r (processos rodando ou esperando CPU) do vmstat 1 com o número de núcleos, e ver com pidstat -w -t as trocas de contexto voluntárias (cswch/s) e involuntárias (nvcswch/s) por thread do servidor do jogo
Confirma se
Quando o número de jogadores simultâneos sobe, r fica muito acima do número de núcleos, cs dispara junto e há centenas de threads com muitas trocas de contexto involuntárias
Descarta se
r fica no máximo no número de núcleos: não é esta causa. Só as trocas voluntárias estão altas: as threads estão esperando lock ou I/O (“Contenção de lock”, “Arquitetura de I/O bloqueante”)
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Fontes
Quantifying The Cost of Context Switch (ExpCS 2007)ACM Custo direto da troca de contexto de cerca de 3,8 µs; o custo indireto, somando o efeito no cache, vai de alguns µs a mais de 1.000 µs (no ambiente medido)
vmstat(8) — Linux manual pageprocps-ng Campos cs (trocas de contexto por segundo) e r (processos rodando ou esperando para rodar)
I/O Completion PortsMicrosoft Processa muito I/O assíncrono com um pool de threads criado de antemão e IOCP, e ajusta o número de threads rodando ao mesmo tempo à concorrência da CPU
pidstat(1) — Linux manual pagesysstat No -w, cswch/s são as trocas de contexto voluntárias (a thread parou sozinha esperando um recurso) e nvcswch/s, as involuntárias (trocada à força por esgotar a fatia de tempo); -t mostra por thread