락을 잘게 나누기, 락 안에서 하는 일 줄이기, 메시지 기반 구조(데이터마다 담당 스레드를 정하고 다른 스레드는 메시지로 요청만 보내기).
수치 감각
락 안의 일이 작업의 20%면 스레드를 아무리 늘려도 처리량은 1개일 때의 최대 5배, 40%면 2.5배에서 멈춥니다.
그래프에서는
인원·부하를 따라 오름 · 요청 처리 시간, 스레드별 CPU·컨텍스트 스위칭
확인할 곳
pidstat -w -t 1로 스레드별 자발적 컨텍스트 스위칭(cswch/s, 자원을 기다리며 멈춘 횟수), bcc offcputime -p로 스레드가 CPU를 떠나 어디서 기다리는지(호출 스택별 대기 시간). .NET은 dotnet-counters의 락 경합 수(.NET 9 이후 dotnet.monitor.lock_contentions, 8 이하 Monitor Lock Contention Count)
이러면 맞음
부하가 늘어도 CPU 사용률은 낮게 머무는데 처리 시간이 늘고 대기 시간의 대부분이 락을 잡으려는 호출 스택에 몰려 있으며 락 경합 수가 함께 오름
이러면 아님
CPU가 꽉 차 있으면 계산량 문제(틱 예산 초과, 단일 스레드 지역 과부하). 기다리는 곳이 DB·파일 호출이면 게임 스레드의 동기 호출 쪽
확인 수단
인프라 도구로 확인(게임 코드 불필요)
더 알아보기
여러 스레드가 게임 데이터를 함께 고치는 구조에서 생깁니다. 지역·기능마다 스레드 하나가 맡고 메시지로만 주고받는 구조는 락이 거의 없는 대신, 한 스레드에 일이 몰리는 문제(단일 스레드 지역 과부하)를 조심해야 합니다. 게임 스레드가 느린 저장 작업이 잡은 락을 기다리면 그 틱 전체가 멈춥니다.