浮动线程

使用本主题来学习如何查找内核之间浮动的线程。 内核之间浮动的线程可能会停止关键进程。

线程的相关性定义操作系统可以在其上调度线程的 CPU 内核。 默认情况下,可以安排线程在任何 CPU 内核上执行。 线程关闭后,可以重新切回时可安排在不同的 CPU 内核上运行(即浮动至其他内核)。 在某些情况下,此行为是可取的,因为它可以帮助负载均衡任务,并在其他内核可用时避免线程等待。 但是,这可能会对游戏的性能产生负面影响。 请考虑以下示例。

  • 线程可以浮动到对游戏至关重要的内核。 例如,如果游戏将渲染线程锁定到内核 1,则工作线程可以浮动到内核 1,然后停止渲染线程。
  • 缓存中几乎总是有错误的数据。 这进而导致大量缓存未命中

PIX

可以轻松确定线程是否在 PIX 的内核之间浮动。 线程时间线显示了每个事件执行线程的内核。

使用PIX确定线程是否在内核之间浮动

  1. 创建计时捕获。 有关更多信息,请参阅 通用步骤

  2. 在线程时间线上,放大到怀疑可能引起问题的部分。 举例说明,见图 1。

  3. 请注意,每个线程在时间线上有两条水平线。 下面一条表示活动的 PIX 事件。 上面一条表示线程在哪个 CPU 内核上运行。

    图 1. 显示线程 836 在内核之间浮动的 PIX 线程时间线放大视图

    显示线程 836 在内核之间浮动的 PIX 线程时间线放大视图的屏幕截图

  4. 考虑图 1 中的线程 836。 请注意,它同时在绿色内核(内核 1)和浅蓝色内核(内核 2)上运行。 将鼠标移到任何上面的事件行上以突出显示该部分,它会显示一个弹出窗口,告诉你它代表哪个内核。

  5. 请注意,线程 836 在内核 1 和 2 之间浮动 — 线程 972 和 976 已在其中执行(参见图 2)。 使用箭头查看所选的上下文开关。 注意,任务结束时,线程 976 由线程 972 准备。 但是,线程 976 将其相关性设置为仅在内核 2 上运行。 因此,必须稍后在836(当时占用内核 2)的 58μs 内切换。 尽管这是一个简单的示例,但演示了浮动线程如何影响其他线程的性能。

    图 2. 图 1 中所选上下文开关的元素详细信息

    图 1 中所选上下文开关的元素详细信息的屏幕截图

Windows Performance Analyzer (WPA)

在 WPA 中,按进程、线程列出的 CPU 使用率(精确)时间线窗口(ThreadFloating.wpaProfile 配置文件的一部分)提供了游戏内核是否在内核之间浮动所需的全部信息。

用于使用 WPA 查找浮动线程

  1. 生成事件跟踪日志 (ETL) 文件。 有关详细信息,请参阅 通用步骤

  2. 按照通用步骤中的说明应用ThreadFloating.wpaProfile WPA 配置文件。 图 3 显示新的分析选项卡的外观。

    图 3. ThreadFloating WPA 配置文件默认视图

    显示 ThreadFloating WPA 配置文件默认视图的屏幕截图

  3. 使用此 WPA 配置文件,已将 CPU 列设置为显示每一行的唯一计数(请参见图 4)。 它显示 ETL 事件为此进程和线程报告的唯一 CPU 值数量。 大于 1 的任何值表示线程在可见时间段内至少在 CPU 内核之间浮动一次。

    图 4. 关注线程的唯一 CPU 值,线程 800 和 836 在六个不同的内核上运行

    显示线程 800 和 836 在六个内核上运行的屏幕截图

  4. 查找浮动到关键内核的线程。 为此,右键单击 CPU 列,然后选择查找列... 。此操作将搜索浮动到该特定内核的所有线程。

    图 5. 使用“搜索”功能来定位捕获期间在内核 1 上运行的所有线程

    显示如何使用“搜索”功能来定位捕获期间在内核 1 上运行的所有线程的屏幕截图