简体   繁体   English

使用 javascript 检测设备 CPU/GPU 性能?

[英]Using javascript to detect device CPU/GPU performance?

(The question is not specific to three.js but I will use it as an example) (这个问题不是针对 three.js 的,但我会以它为例)

I have been using three.js to develop a web app interface lately and written some nice fallback between WebGL and Canvas renderer (for desktop browsers).我最近一直在使用 three.js 开发 web 应用程序界面,并在 WebGL 和 Canvas 渲染器(用于桌面浏览器)之间编写了一些不错的后备。

But now the problem becomes how to properly detect device capability, there are 2 aspects to the problem:但是现在问题变成了如何正确检测设备能力,问题有两个方面:

  1. browser features (static features like webgl/canvas): this is largely solved within web community using simple feature detect.浏览器功能(静态功能,如 webgl/canvas):这在 web 社区中使用简单的功能检测在很大程度上得到了解决。
  2. device capability : this is the hard part, without direct access to device's hardware information, we need some ways of telling whether we should fallback to less hardware-demanding code.设备能力:这是困难的部分,如果不能直接访问设备的硬件信息,我们需要一些方法来判断我们是否应该回退到对硬件要求较低的代码。

A notable example : Firefox mobile/Opera mobile claims support of WebGL but are buggy or limited by device hardware.一个值得注意的例子:Firefox 移动/Opera 移动声称支持 WebGL,但存在错误或受设备硬件限制。

A few workarounds I come up with so far:到目前为止,我提出了一些解决方法:

  1. Use a common feature as performance indicator - touch device, for example, has less powerful hardware in general.使用通用功能作为性能指标- 例如,触摸设备通常具有不太强大的硬件。 The con: it's not future-proof.缺点:它不是面向未来的。
  2. Blacklist known buggy browser/device - UA sniffing will be unavoidable, and it can be hard to maintain.黑名单已知有问题的浏览器/设备- UA 嗅探将是不可避免的,并且可能难以维护。
  3. Performance test - hence the question, besides running the code and measure framerate, are there better options?性能测试——因此问题是,除了运行代码和测量帧率之外,还有更好的选择吗?

Or maybe it doesn't have to be this hard, are there other suggestions?或者也许它不必这么难,还有其他建议吗?

I've ended up using a performance measurement approach on a project where we wanted to utilise canvas features that are available on high spec CPU/GPU desktops, as well as lower speed devices such as tables and phones. 我最终在一个项目中使用了性能测量方法,我们希望利用高规格CPU / GPU桌面上的画布功能,以及桌面和手机等低速设备。

Basically we start at a minimum scene complexity, and if the renderloop takes less than 33ms we add complexity (we also reduce complexity if the renderloop starts taking too long at a later time). 基本上我们从最小的场景复杂度开始,如果renderloop花费不到33ms,我们就增加了复杂性(如果renderloop以后开始花费太长时间,我们也会降低复杂性)。

I suppose in your case you might have to run a quick canvas and webgl performance test and then choose one. 我想在您的情况下,您可能需要运行快速画布和webgl性能测试,然后选择一个。 Having spent some time researching this I've not come across some tricky non-obvious technique that solves this better. 花了一些时间研究这个我没有遇到一些棘手的非显而易见的技术,可以更好地解决这个问题。

您可以使用http://webglstats.com/进行WebGL硬件支持和功能检测。

If your using three.js you can just use the detector.js to find out if webgl is enabled. 如果您使用three.js,您可以使用detector.js来查明是否启用了webgl。 also staying away from the canvasrenderer will help. 也远离canvasrenderer将有所帮助。 use the webglrenderer or the softwarerender. 使用webglrenderer或softwarerender。 as they allow for more vertices. 因为它们允许更多顶点。 the softwarerender is fairly new and needs some work but can be used. softwarerender相当新,需要一些工作但可以使用。

This is the snippet I wrote to benchmark webgl, using three.js:这是我使用 three.js 写给基准 webgl 的代码片段:

import {
  Mesh,
  MeshStandardMaterial,
  PerspectiveCamera,
  Scene,
  SphereGeometry,
  WebGLRenderer,
} from "three";

function sleep(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

export enum GPUPerformanceLevel {
  HIGH = "HIGH",
  LOW = "LOW",
}

/**
 * Three.js based webgl benchmark
 *
 * In summary, the `run` method adds `meshPerStep` new spheres every step (frame)
 * and measures the fps. If we're able to perform >=`thresholds.steps` of these
 * steps, without the fps dropping below `thresholds.fps`, then we label the device
 * `GPUPerformanceLevel.HIGH`.
 */
export class GPUBenchmark {
  scene = new Scene();
  material = new MeshStandardMaterial();
  geometry = new SphereGeometry();

  static thresholds = { fps: 10, steps: 40 };
  static meshPerStep = 1000;

  async run(debug = false): Promise<GPUPerformanceLevel> {
    const camera = new PerspectiveCamera(75);
    const renderer = new WebGLRenderer();

    let tPrev = performance.now() / 1000;
    let steps = 0;

    let passedThreshold = false;

    const animate = async () => {
      const time = performance.now() / 1000;
      const fps = 1 / (time - tPrev);
      tPrev = time;

      if (debug) {
        console.log(`fps: ${fps} steps: ${steps}`);
      }

      if (
        fps > GPUBenchmark.thresholds.fps &&
        steps < GPUBenchmark.thresholds.steps
      ) {
        requestAnimationFrame(animate);

        this.step();
        steps++;
        renderer.render(this.scene, camera);
      } else {
        passedThreshold = true;
      }
    };

    animate();

    while (!passedThreshold) {
      await sleep(1);
    }

    this.cleanup();
    const level = GPUBenchmark.stepsToPerfLevel(steps);

    if (debug) {
      console.log("device benchmarked at level:", level);
    }

    return level;
  }

  private step() {
    for (let i = 0; i < GPUBenchmark.meshPerStep; i++) {
      const sphere = new Mesh(this.geometry, this.material);
      sphere.frustumCulled = false;

      this.scene.add(sphere);
    }
  }

  private cleanup() {
    for (const obj of this.scene.children) {
      this.scene.remove(obj);
    }

    //@ts-ignore
    this.scene = null;

    this.material.dispose();
    this.geometry.dispose();

    //@ts-ignore
    this.material = null;
    //@ts-ignore
    this.geometry = null;
  }

  private static stepsToPerfLevel(numSteps: number): GPUPerformanceLevel {
    if (numSteps >= GPUBenchmark.thresholds.steps) {
      return GPUPerformanceLevel.HIGH;
    } else {
      return GPUPerformanceLevel.LOW;
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用CPU速度从Javascript检测iPhone 5 DEVICE - Detect iPhone 5 DEVICE from Javascript using CPU speed 是否可以通过使用 onload 事件来测量 gpu/cpu 的性能? - Is it possible to measure gpu/cpu performance with timing by using an onload event? 使用javascript检测iPad设备方向 - Detect iPad device orientation using javascript 使用Javascript或HTML检测iOS设备的型号? - Detect model of iOS device using Javascript or HTML? 如何使用javascript,css检测浏览器/设备? - How to detect the browser/device using javascript,css? Nodejs GPU.js 使用 GPU 比使用 CPU 慢 - Nodejs GPU.js slower using GPU than using CPU Javascript 检测是否在移动设备上 - Javascript detect if on mobile device 如何使用AngularJS中的JavaScript检测设备平台并更改链接URL - How to detect device platform and change link url using JavaScript in AngularJS 使用javascript或jquery检测Android应用程序是否已安装在设备中 - detect Android app is installed or not in device using javascript or jquery 如何使用 javascript 为 PWA 应用程序检测设备级通知打开或关闭? - How to Detect the device level Notification ON or OFF using javascript for PWA Application?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM