内核利用率:空闲时间

使用本主题标识未充分利用的 CPU 内核或线程。 如果所有 CPU 内核都没有 100 % 地执行有用的工作,则有改进的空间。 如果可以确定空闲时间的各个部分,使用工作填充,然后确保独立任务并行运行,则可以显著提升游戏的性能。 幸运的是,很容易找到内核上的空闲时间。 识别这些位置有助于确定游戏是否被不必要地阻塞或是否有空闲周期来处理其他工作。

Performance Investigator for Xbox (PIX)

Performance Investigator for Xbox (PIX) 中的时间线视图显示了 CPU 内核的使用方式以及这些内核上各个线程的占用情况。 使用以下步骤来调查线程。

  1. 请按照通用步骤主题中的步骤创建计时捕获。

  2. 从缩小的视图开始,检查 CPU 内核时间线大部分为空的部分(表示没有运行代码)。 如图 1 所示,内核三未执行任何工作。

    图 1. 显示能够显示 CPU 3 空闲 CPU 时间线的 PIX 计时捕获
    显示 CPU 3 空闲 CPU 时间线的 PIX 计时捕获的屏幕截图

  3. 放大直到找到要调查的帧。 Pix 放大到示例的单个帧,该示例以每秒 60 帧(FPS)的速度运行,如图 2 所示。

    图 2. 显示缩放至单帧的 PIX 计时捕获,此帧显示空闲的内核和利用率过低的内核。
    缩放为单帧的 PIX 计时捕获屏幕截图

    注意

    双击 PIX 时间线中的元素会自动将视图缩放到该元素的持续时间,例如图 2 中的帧 302 标记。

  4. 在图 2 中,内核 0 和内核 4 的时间线已填满,表示着它们的运行率接近 100%。 核心 1、2、5和 6 的空间为空,并且以大约 25% 的利用率运行。

  5. 可以在线程时间线中查看各个线程的行为。 可以专注于认为应该运行接近 100% 的线程,如图 3 所示。

    图 3. 显示放大到 4 毫秒的线程时间线以及每个线程上的停顿(992 除外)
    4 毫秒线程时间线以及每个线程上停顿的屏幕截图

  6. 线程执行的每个部分顶部的不同颜色的条形表示运行线程的内核。 前两个线程具有相同的深金条,表示它们都在同一内核上运行。 将鼠标悬停在顶栏上以显示内核编号。 如图 2 所示,线程 1120 和 1124 在内核 4 上交替显示。

  7. 此时,可以使用 线程锁定 主题中描述的步骤来缩小导致线程停止执行的代码行范围。 如果线程只是在等待新工作,而CPU内核处于空闲状态,则调整其他线程的线程亲和性来安排该内核上的时间,或准备要在该内核上进行的其他工作。

Windows Performance Analyzer (WPA)

Windows Performance Analyzer (WPA) 具有两个游戏中线程的主视图,分别称为 按 CPU 利用率列出的 CPU 使用率(精确)按进程利用率列出的 CPU 使用率(精确)

按 CPU 利用率列出的 CPU 使用率(精确)显示与内核相关的数据。 这样可以快速显示出哪里有额外空间来运行线程。 按进程利用率列出的 CPU 使用率(精确)显示哪些线程大部分空闲或占用内核。 使用以下步骤进行检查

  1. 按照通用步骤主题中的步骤来生成事件跟踪日志(ETL)文件。

  2. 通用步骤主题所述,应用 ThreadUtilization.wpaProfile WPA 配置文件。 应用配置文件后,将出现新的分析选项卡,如图 5 所示。

    图 5. 显示 WPA 中线程利用率的默认视图
    WPA 中线程利用率的默认视图屏幕截图

重点关注未正确使用的 CPU 核心的步骤

  1. 按 CPU 利用率列出的 CPU 使用率(精确)视图中,使用CPU 使用率 %列查找使用率低于预期的 CPU 内核,如图 6 所示。 该百分比基于整个 CPU 的100%,而不是每个内核。 因此,对于单个内核,14.28% 表示该内核以 100 %的速度运行,因为有七个可用 CPU 内核(100% / 7个 CPU 内核= 14.28 %)。

    图 6. 显示仅内核 0 以100 %运行时的 CPU 利用率
    仅内核 0 以100 %运行时的 CPU 利用率的屏幕截图

  2. 放大到图形上 CPU 内核空闲或非常繁忙的区域。

  3. 展开数据表中的新线程堆栈(帧标记)条目以显示游戏正获得 CPU 控制的位置,如图 7 所示。 CPU 使用率 %列显示所花费的总时间百分比,相对于整个 CPU 而不是每个内核的100 %。

    图 7. 显示总体 CPU 使用率增加并使 std::mutex 保持 CPU 利用率较低的放大时间段
    屏幕截图放大显示 CPU 使用率上升到完全使用而 std::mutex 保持低 CPU 使用率的时间段

  4. 使用主题线程锁定中描述的步骤来缩小导致线程在这些内核上停止执行的代码行的范围。 如果线程只是在等待新工作,而CPU内核处于空闲状态,则调整其他线程的线程亲和性来安排该内核上的时间,或准备要在该内核上进行的其他工作。

重点关注未如预期运行的线程的步骤

  1. 使用按进程、线程利用率列出的 CPU 使用率(精确)窗口按线程缩小问题。

  2. 查看以低于 CPU 预期百分比运行的线程,该线程在CPU 使用率 % 列中找到,如图 8 所示。 例如,希望大部分时间关联单独内核的线程。 该百分比基于整个 CPU 的100%,而不是每个内核。

    图 8. 显示“按进程排序的利用率”窗口,以查看游戏中线程的 CPU 使用率百分比
    “按进程排序的利用率”窗口,以查看游戏中线程的 CPU 使用率百分比的屏幕截图

  3. 放大直到找到要调查的部分。 这将限制通过数据表排序的数据量。

  4. 展开数据表中的新线程堆栈(帧标记)条目以显示游戏正获得 CPU 控制的位置,如图 9 所示。 CPU 使用率 %列显示所花费的总时间百分比,相对于整个 CPU 而不是每个内核的100 %。

    图 9. 显示使用率增加至 std::mutex 保持线程利用率较低的线程点
    使用率增加而 std::mutex 保持低线程使用率的线程点的屏幕截图

  5. 此时,可以按照线程锁定中描述的步骤,缩小导致线程停止执行的代码行范围。