한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Guia do Lag em Jogos › L9 Processo do jogo no servidor

Contenção de lock Lock contention

ID da causa sp-lock · Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento)

Abrir o card interativo, com figuras e simulações →

Quando várias threads esperam o mesmo lock para usar os mesmos dados, só uma roda por vez, por mais threads que se acrescentem.

Por quê Várias threads usam ao mesmo tempo dados compartilhados, como a casa de leilões ou o baú da guilda → Efeito As outras esperam até a thread que pegou o lock terminar → Na tela Só um recurso específico fica lento; nos casos graves, o tick inteiro atrasa

Sintomas
Input lag, Travamento
Fatores
Paralisação
Quem é afetado
Só um recurso específico, Servidor inteiro
Quando
Quando junta muita gente
Responsável
Responsável principal Desenvolvimento do servidor (Equipe de desenvolvimento)
O que fazer (Equipe de desenvolvimento)
Dividir os locks em partes menores, reduzir o trabalho feito dentro do lock, usar uma arquitetura baseada em mensagens (cada dado tem uma thread responsável, e as outras threads só enviam pedidos por mensagem).
Números de referência
Se o trabalho dentro do lock é 20% do total, por mais threads que se acrescentem, a vazão para em no máximo 5 vezes a de uma thread; com 40%, para em 2,5 vezes.
No gráfico
Sobe com a carga · Tempo de processamento dos pedidos, CPU e trocas de contexto por thread
Onde olhar
Trocas de contexto voluntárias por thread (cswch/s, quantas vezes parou esperando um recurso) com pidstat -w -t 1, e onde a thread espera fora da CPU (tempo de espera por pilha de chamadas) com bcc offcputime -p. No .NET, o número de contenções de lock no dotnet-counters (dotnet.monitor.lock_contentions a partir do .NET 9, Monitor Lock Contention Count até o 8)
Confirma se
Mesmo com mais carga, o uso de CPU fica baixo, mas o tempo de processamento sobe, a maior parte do tempo de espera se concentra nas pilhas de chamadas que tentam pegar o lock, e o número de contenções de lock sobe junto
Descarta se
CPU no máximo: problema de volume de cálculo (estouro do tick, sobrecarga de zona em thread única). Espera em chamadas ao BD ou a arquivos: aponta para chamadas síncronas na thread do jogo
Como verificar
Ferramentas de infra (sem precisar do código do jogo)
Saiba mais
Acontece em arquiteturas em que várias threads alteram juntas os dados do jogo. Arquiteturas em que cada área ou recurso fica com uma thread e a comunicação é só por mensagens quase não têm locks, mas é preciso cuidar do acúmulo de trabalho numa thread só (sobrecarga de zona em thread única). Se a thread do jogo espera um lock segurado por uma operação lenta de salvamento, o tick inteiro para.
Casos reais
Roblox 2021: Queda de 73 horas no Roblox: contenção no cluster de service discovery (Consul)

Fontes

  1. Amdahl's Law in the Multicore Era IEEE
    Artigo da IEEE Computer de 2008 (versão publicada pelos autores). Se a fração que não dá para paralelizar é 1−f, o ganho de velocidade não passa de 1/(1−f), por mais núcleos que se acrescentem (lei de Amdahl)
  2. Request scheduling Microsoft
    Os grains (atores) do Orleans seguem um modelo de execução em thread única que processa um pedido de cada vez até o fim, então o estado nunca é alterado ao mesmo tempo; se esperarem as respostas uns dos outros, pode haver deadlock
  3. pidstat(1) — Linux manual page sysstat
    cswch/s do -w é o número de trocas de contexto voluntárias, quando a thread para esperando um recurso; -t mostra por thread
  4. Demonstrations of offcputime, the Linux eBPF/bcc version IO Visor
    Soma, por pilha de chamadas, o tempo em que as threads ficaram paradas fora da CPU (off-CPU); -p especifica o processo
  5. Well-known EventCounters in .NET Microsoft
    Monitor Lock Contention Count (monitor-lock-contention-count): número de vezes em que houve contenção ao tentar pegar um monitor lock
  6. .NET runtime metrics .NET
    A partir do .NET 9, dotnet.monitor.lock_contentions: número de vezes, desde o início do processo, em que houve contenção ao tentar pegar um monitor lock

Veja também

Mesma camada: L9 Processo do jogo no servidor

Mesmo sintoma (Input lag) em outras camadas

Ver o card interativo, com figuras e simulações