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

游戏卡顿白皮书 › L7 服务器操作系统(内核)

线程过多与上下文切换 Thread oversubscription, context switching

原因 ID so-context · 主责 研发团队·服务器开发 · 配合 运维团队·系统运维

在含图示和实验的完整版中打开此卡片 →

线程数远多于核心数时,操作系统光是让它们轮流运行就要耗掉大量 CPU。

起因 比如每个连接创建一个线程,线程数达到几百到几千个 → 结果 上下文切换(更换正在执行的线程)的开销和缓存未命中增加 → 画面表现 CPU 很忙但吞吐量低,tick 忽快忽慢,表现为一卡一卡、慢动作

症状
一卡一卡, 慢动作
因素
停顿, 抖动
谁会遇到
全服
何时出现
人多的时候
负责方
主责 研发团队·服务器开发 · 配合 运维团队·系统运维
研发团队要做的事
线程数与核心数匹配;使用异步 I/O(epoll、IOCP)。
运维团队要做的事
监控上下文切换次数和等待运行的线程数(vmstat 的 cs、r)。
数值参考
一次上下文切换需要几 µs,再加上之后的缓存未命中开销,代价更大。
监控图上
随人数/负载上升 · 每秒上下文切换次数、等待运行的线程数
查看位置
把 vmstat 1 的 cs(每秒上下文切换次数)、r(正在运行或等待 CPU 的数量)与核心数对比,用 pidstat -w -t 看游戏服务器各线程的自愿(cswch/s)、非自愿(nvcswch/s)上下文切换
确认依据
同时在线人数上升时 r 远超核心数,cs 也跟着飙升,非自愿上下文切换多的线程有几百个
排除依据
r 保持在核心数以下则不是这个原因。只有自愿切换多,说明线程在等锁或 I/O(“锁竞争”“阻塞 I/O 模型”)
确认手段
运维工具即可确认(无需游戏代码)

出处

  1. Quantifying The Cost of Context Switch (ExpCS 2007) ACM
    上下文切换的直接开销约 3.8 µs,加上缓存影响的间接开销为几 µs 到 1,000 µs 以上(以测量环境为准)
  2. vmstat(8) — Linux manual page procps-ng
    cs(每秒上下文切换次数)和 r(正在运行或等待运行的进程数)字段
  3. I/O Completion Ports Microsoft
    用预先创建的线程池和 IOCP 处理大量异步 I/O,并让同时运行的线程数与 CPU 并发能力相匹配
  4. pidstat(1) — Linux manual page sysstat
    -w 的 cswch/s 是等待资源时主动让出 CPU 的自愿上下文切换,nvcswch/s 是时间片用完后被强制切换的非自愿上下文切换;-t 按线程显示

相关原因

同一层:L7 服务器操作系统(内核)

其他层中同样导致“一卡一卡”的原因

查看含图示和实验的原卡片