diff --git a/webgpu/lessons/webgpu-optimization.md b/webgpu/lessons/webgpu-optimization.md index 36784602..69bf005a 100644 --- a/webgpu/lessons/webgpu-optimization.md +++ b/webgpu/lessons/webgpu-optimization.md @@ -669,19 +669,19 @@ A few more things left to do. Let's add in resizing +observer.observe(canvas); ``` -Let's also add in some timing. We'll use the `RollingAverage` and `TimingHelper` classes +Let's also add in some timing. We'll use the `NonNegativeRollingAverage` and `TimingHelper` classes we made in [the article on timing](webgpu-timing.html). ```js // see https://webgpufundamentals.org/webgpu/lessons/webgpu-timing.html import TimingHelper from './resources/js/timing-helper.js'; // see https://webgpufundamentals.org/webgpu/lessons/webgpu-timing.html -import RollingAverage from './resources/js/rolling-average.js'; +import NonNegativeRollingAverage from './resources/js/non-negative-rolling-average.js'; -const fpsAverage = new RollingAverage(); -const jsAverage = new RollingAverage(); -const gpuAverage = new RollingAverage(); -const mathAverage = new RollingAverage(); +const fpsAverage = new NonNegativeRollingAverage(); +const jsAverage = new NonNegativeRollingAverage(); +const gpuAverage = new NonNegativeRollingAverage(); +const mathAverage = new NonNegativeRollingAverage(); ``` Then we'll time our JavaScript from the beginning to the end of our rendering code diff --git a/webgpu/lessons/webgpu-timing.md b/webgpu/lessons/webgpu-timing.md index f3bcaf24..ce60228c 100644 --- a/webgpu/lessons/webgpu-timing.md +++ b/webgpu/lessons/webgpu-timing.md @@ -567,7 +567,10 @@ average. Here's a class to help compute a rolling average. ```js -class RollingAverage { +// Note: We disallow negative values as this is used for timestamp queries +// where it's possible for a query to return a beginning time greater than the +// end time. See: https://gpuweb.github.io/gpuweb/#timestamp +class NonNegativeRollingAverage { #total = 0; #samples = []; #cursor = 0; @@ -576,9 +579,11 @@ class RollingAverage { this.#numSamples = numSamples; } addSample(v) { - this.#total += v - (this.#samples[this.#cursor] || 0); - this.#samples[this.#cursor] = v; - this.#cursor = (this.#cursor + 1) % this.#numSamples; + if (!Number.isNaN(v) && Number.isFinite(v) && v >= 0) { + this.#total += v - (this.#samples[this.#cursor] || 0); + this.#samples[this.#cursor] = v; + this.#cursor = (this.#cursor + 1) % this.#numSamples; + } } get() { return this.#total / this.#samples.length; @@ -592,9 +597,9 @@ oldest value is subtracted from the total as the new value is added. We can use it like this. ```js -+const fpsAverage = new RollingAverage(); -+const jsAverage = new RollingAverage(); -+const gpuAverage = new RollingAverage(); ++const fpsAverage = new NonNegativeRollingAverage(); ++const jsAverage = new NonNegativeRollingAverage(); ++const gpuAverage = new NonNegativeRollingAverage(); function render(now) { ... diff --git a/webgpu/resources/js/non-negative-rolling-average.js b/webgpu/resources/js/non-negative-rolling-average.js new file mode 100644 index 00000000..efee0f09 --- /dev/null +++ b/webgpu/resources/js/non-negative-rolling-average.js @@ -0,0 +1,23 @@ +// See https://webgpufundamentals.org/webgpu/lessons/webgpu-timing.html +// Note: We disallow negative values as this is used for timestamp queries +// where it's possible for a query to return a beginning time greater than the +// end time. See: https://gpuweb.github.io/gpuweb/#timestamp +export default class NonNegativeRollingAverage { + #total = 0; + #samples = []; + #cursor = 0; + #numSamples; + constructor(numSamples = 30) { + this.#numSamples = numSamples; + } + addSample(v) { + if (!Number.isNaN(v) && Number.isFinite(v) && v >= 0) { + this.#total += v - (this.#samples[this.#cursor] || 0); + this.#samples[this.#cursor] = v; + this.#cursor = (this.#cursor + 1) % this.#numSamples; + } + } + get() { + return this.#total / this.#samples.length; + } +} diff --git a/webgpu/resources/js/rolling-average.js b/webgpu/resources/js/rolling-average.js index a2f36c97..d4bf7df5 100644 --- a/webgpu/resources/js/rolling-average.js +++ b/webgpu/resources/js/rolling-average.js @@ -1,4 +1,3 @@ -// See https://webgpufundamentals.org/webgpu/lessons/webgpu-timing.html export default class RollingAverage { #total = 0; #samples = []; diff --git a/webgpu/webgl-optimization-global-material-per-object-uniform-buffers.html b/webgpu/webgl-optimization-global-material-per-object-uniform-buffers.html index 3ea39eb2..62fc67e7 100644 --- a/webgpu/webgl-optimization-global-material-per-object-uniform-buffers.html +++ b/webgpu/webgl-optimization-global-material-per-object-uniform-buffers.html @@ -46,7 +46,7 @@ //import 'https://greggman.github.io/webgl-lint/webgl-lint.js'; import GUI from '../3rdparty/muigui-0.x.module.js'; import * as twgl from '../3rdparty/twgl-full.module.js'; -import RollingAverage from './resources/js/rolling-average.js'; +import NonNegativeRollingAverage from './resources/js/non-negative-rolling-average.js'; class TimingHelper { #ext; @@ -118,10 +118,10 @@ }, }; -const fpsAverage = new RollingAverage(); -const jsAverage = new RollingAverage(); -const gpuAverage = new RollingAverage(); -const mathAverage = new RollingAverage(); +const fpsAverage = new NonNegativeRollingAverage(); +const jsAverage = new NonNegativeRollingAverage(); +const gpuAverage = new NonNegativeRollingAverage(); +const mathAverage = new NonNegativeRollingAverage(); /** Given a css color string, return an array of 4 values from 0 to 255 */ const cssColorToRGBA8 = (() => { diff --git a/webgpu/webgl-optimization-none-uniform-buffers.html b/webgpu/webgl-optimization-none-uniform-buffers.html index 450c8f2a..68476dd3 100644 --- a/webgpu/webgl-optimization-none-uniform-buffers.html +++ b/webgpu/webgl-optimization-none-uniform-buffers.html @@ -45,7 +45,7 @@