计算压力 API

了解系统计算压力。

Kenneth Christiansen
Kenneth Christiansen
Arnaud (Arno) Mandy

Compute Pressure API 提供表示系统压力的高级状态。它允许实现使用正确的基础硬件指标,以确保用户可以充分利用可用的所有处理能力,前提是系统未处于不可管理的压力之下。

当前状态

步骤 状态
1. 创建铺垫消息 完成
2. 创建规范的初始草稿 完成
3. 收集反馈并迭代设计 进行中
4. 来源试用 完成
5. 发布 已完成(Chrome 125)

试用 Compute Pressure API

如需在本地试用 Compute Pressure API,请参阅此页面

注册参与源代码试用

从 Chrome 115 开始,Compute Pressure API 可作为源试用版提供。该计划预计将在 Chrome 123 中结束(2024 年 5 月 29 日)。注册源代码试用版

应用场景

当前 Compute Pressure API 增强的主要用例是视频会议和视频游戏。

这些热门实时应用被归类为。也就是说,如果系统超出特定状态,服务质量会下降,但不会导致系统完全崩溃。这些软实时应用能够根据 CPU 消耗或压力调整工作负载,这对它们来说非常有益。

具体而言,此 API 的第一个版本旨在支持以下自适应决策。

视频会议

  • 调整在有多个参与者的通话期间同时显示的视频画面数量。
  • 降低视频处理画质(视频分辨率、每秒帧数)。
  • 跳过不必要的视频处理,例如某些相机滤镜。
  • 停用非必需的音频处理,例如 WebRTC 降噪。
  • 在视频和音频编码(在 WebRTC、WebCodecs 或软件编码中)中,将质量与速度和大小与速度旋钮转向“速度”。

视频游戏

  • 使用质量较低的资源来构成游戏的视频(3D 模型、纹理、着色器)和音频(语音、音效)。
  • 停用会导致非必需细节(水、布料、火焰动画、皮肤亮度、眩光效果或对游戏玩法没有影响的物理模拟)看起来不太逼真的效果。
  • 调整游戏渲染引擎中的质量与速度旋钮(阴影质量、纹理过滤、视野距离)。

从技术层面来说,可以通过了解网站正在使用的主线程和工作器的热状态(例如,系统是否采用被动冷却)和 CPU 压力状态来实现这些目标。系统热状态是一种全局状态,可能会受到观察位置以外的应用和网站的影响。

接口

Compute Pressure API 可以在以下上下文中运行:

  • 窗口或主线程
  • 专用工作器
  • 共享工作器

Compute Pressure API 定义了两个新接口。

PressureObserver:用于在预定义的采样间隔时间内观察任意数量来源的计算压力的对象。Chromium 中的第一个迭代会将 "cpu" 公开为 source。如需了解详情,请参阅参数部分。每个观察器都可以异步观察系统中的压力变化趋势。

PressureRecord:描述转换的特定时刻的压力趋势。您只能通过以下两种方式获取此类对象:作为 PressureObserver 回调的输入,或通过对 PressureObserver 实例调用 takeRecords() 方法。

PressureObserver

创建 PressureObserver 对象后,系统会将其配置为在给定采样间隔内监控受支持来源的压力。在 PressureObserver 对象的生命周期内,可以随时单独观察或取消观察受支持的来源。对象创建后,采样间隔无法更改。

构造函数

PressureObserver(callback):创建一个新的 PressureObserver 对象,该对象会在检测到所观察来源的值发生变化时调用指定的回调函数。

构造函数接受一个必需的回调函数。

回拨电话

callback():使用一组未读 PressureRecord 对象调用回调。

方法

PressureObserver.observe(source, options):将要监控的来源和可选的 options 作为参数告知“PressureObserver”。

选项

PressureObserverOptions:包含用户请求更新的采样间隔 sampleInterval(以毫秒为单位)。

PressureObserver.unobserve(source):告知“PressureObserver”停止观察来源。

PressureObserver.disconnect():告知“PressureObserver”停止观察所有来源。

PressureObserver.takeRecords():返回自上次调用回调以来的一组记录

static PressureObserver.knownSources()(只读):按字母顺序返回用户代理的已知来源类型。

参数

source:要观察的来源,例如 "cpu"。此项必须是受支持的来源类型之一。

在计算压力的当前版本中,仅支持 "cpu"

PressureRecord

Compute Pressure API 的 PressureRecord 接口用于描述来源在特定转换时刻的压力趋势。

实例属性

PressureRecord.source(只读):返回表示记录来源的原始来源的字符串。

PressureRecord.state(只读):返回表示记录的压力状态的字符串。

PressureRecord.time(只读):返回一个表示高分辨率时间戳的数字。

示例

以下部分列出了示例用法。

确定 API 支持情况

if ('PressureObserver' in globalThis) {
  // The Compute Pressure API is supported.
}

创建压力观察器

通过调用其构造函数并提供一个回调函数(在每次有压力更新时运行)来创建压力观察器:

const observer = new PressureObserver((records) => {
  /* ... */
});

压力观察器的使用

启动压力观察器只有一种方法。针对每个来源调用 observer.observe(source)

observer.observe("cpu" { sampleInterval: 2_000 });

在此示例中,"cpu" 是我们关注的压力源。目前,这是唯一可用的来源。将来,可能还会有其他来源,例如 "gpu""power""thermals"

采样间隔 sampleInterval 为 2000 毫秒,表示最多每两秒更新一次。

如果系统无法提供所请求的采样间隔,则会以最合适的间隔提供采样数据。例如,如果请求的间隔时间为 2000 毫秒,但系统只能提供最长 1000 毫秒的样本,则系统会选择 1000 毫秒。

如需停止观察某个来源,请使用 unobserve() 方法,如以下示例所示:

observer.unobserve('cpu');

如需一次取消观察所有来源,请使用 disconnect() 方法,如以下示例所示:

observer.disconnect();

检索压力记录

您可以使用回调函数检索压力记录,系统会在压力状态发生变化时调用该函数。

function callback(records) {
  const lastRecord = records[records.length - 1];
  console.log(`Current pressure ${lastRecord.state}`);
  if (lastRecord.state === 'critical') {
    // Reduce workers load by 4.
  } else if (lastRecord.state === 'serious') {
    // Reduce workers load by 2.
  } else {
    // Do not reduce.
  }
}

const observer = new PressureObserver(callback);
await observer.observe('cpu', { sampleInterval: 1_000 });

用户还可以通过调用 takeRecords() 方法强制读取 PressureRecord

PressureObserver 接口的 takeRecords() 方法会返回存储在压力观察器中的 PressureRecords 对象数组,并清空该数组。

最常见的用例是,在断开观察器连接之前,立即提取尚未由观察器的回调函数处理的所有待处理压力记录,以便在关闭观察器时处理所有待处理记录。

调用此方法会清除待处理记录列表,因此系统不会运行回调。

const observer = new PressureObserver((records) => {
  /* Do something with records. */
});

await observer.observe('cpu', { sampleInterval: 1_000 });

setTimeout(() => {
  // Forced records reading.
  const records = observer.takeRecords();
  observer.disconnect();
  // Do something with last records if any.
}, 2000);

分享反馈

API 是否有任何方面未按预期运行?您在使用 API 时是否发现缺少任何方法或属性?在相应的 GitHub 代码库中提交规范问题或对现有问题发表评论。

报告实现方面的问题

您是否发现了 Chromium 实现中的 bug?还是实现与规范不同?请访问 new.crbug.com 提交 bug。务必尽可能详细说明问题,并在组件框中输入 Blink> PerformanceAPIs> ComputePressure

资源