Skip to content

Commit

Permalink
Rename RollingAverage to NonNegativeRollingAverage
Browse files Browse the repository at this point in the history
And, make it discard negative values.

The spec says timestamp query can return a beginning timestamp
with a value greater than an ending timestamp and such values
should be discarded.

The easiest place to do this is in the RollingAverage class but
just doing it there without renaming it seemed bad since someone
might use RollingAverage for other purposes and not realize it
was discarding negative values.

Further, it's possible offsite samples are linking directly to
rolling-timing.js (which is the case if you export any sample)
so leave that implementation as is and put NonNegativeRollingAverage
in its own file.
  • Loading branch information
greggman committed Jan 3, 2025
1 parent 8771b2f commit 48050b7
Show file tree
Hide file tree
Showing 21 changed files with 140 additions and 120 deletions.
12 changes: 6 additions & 6 deletions webgpu/lessons/webgpu-optimization.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 12 additions & 7 deletions webgpu/lessons/webgpu-timing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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) {
...
Expand Down
23 changes: 23 additions & 0 deletions webgpu/resources/js/non-negative-rolling-average.js
Original file line number Diff line number Diff line change
@@ -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;
}
}
1 change: 0 additions & 1 deletion webgpu/resources/js/rolling-average.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// See https://webgpufundamentals.org/webgpu/lessons/webgpu-timing.html
export default class RollingAverage {
#total = 0;
#samples = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 = (() => {
Expand Down
10 changes: 5 additions & 5 deletions webgpu/webgl-optimization-none-uniform-buffers.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<script type="module">
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;
Expand Down Expand Up @@ -117,10 +117,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 = (() => {
Expand Down
10 changes: 5 additions & 5 deletions webgpu/webgl-optimization-none.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<script type="module">
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;
Expand Down Expand Up @@ -117,10 +117,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 = (() => {
Expand Down
10 changes: 5 additions & 5 deletions webgpu/webgl-optimization-uniform-buffers-one-large.html
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 = (() => {
Expand Down
27 changes: 5 additions & 22 deletions webgpu/webgpu-compute-shaders-histogram-video-w-timing.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,33 +51,16 @@
</body>
<script type="module">
import TimingHelper from './resources/js/timing-helper.js';
import NonNegativeRollingAverage from './resources/js/non-negative-rolling-average.js';
// see https://webgpufundamentals.org/webgpu/lessons/webgpu-utils.html#wgpu-matrix
import { mat4 } from '../3rdparty/wgpu-matrix.module.js';

const range = (i, fn) => new Array(i).fill(0).map((_, i) => fn(i));

class RollingAverage {
#total = 0;
#samples = [];
#cursor = 0;
#numSamples;
constructor(numSamples = 30) {
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;
}
get() {
return this.#total / this.#samples.length;
}
}

const fpsAverage = new RollingAverage();
const jsAverage = new RollingAverage();
const histogramAverage = new RollingAverage();
const renderAverage = new RollingAverage();
const fpsAverage = new NonNegativeRollingAverage();
const jsAverage = new NonNegativeRollingAverage();
const histogramAverage = new NonNegativeRollingAverage();
const renderAverage = new NonNegativeRollingAverage();

async function main() {
const adapter = await navigator.gpu?.requestAdapter();
Expand Down
10 changes: 5 additions & 5 deletions webgpu/webgpu-optimization-none.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
// 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();

/** Given a css color string, return an array of 4 values from 0 to 255 */
const cssColorToRGBA8 = (() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
// 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();

/** Given a css color string, return an array of 4 values from 0 to 255 */
const cssColorToRGBA8 = (() => {
Expand Down
10 changes: 5 additions & 5 deletions webgpu/webgpu-optimization-step4-material-uniforms.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
// 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();

/** Given a css color string, return an array of 4 values from 0 to 255 */
const cssColorToRGBA8 = (() => {
Expand Down
10 changes: 5 additions & 5 deletions webgpu/webgpu-optimization-step5-use-buffer-offsets.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
// 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();

/** Given a css color string, return an array of 4 values from 0 to 255 */
const cssColorToRGBA8 = (() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
// 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();

/** Given a css color string, return an array of 4 values from 0 to 255 */
const cssColorToRGBA8 = (() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
// 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 vec3 = {
cross(a, b, dst) {
Expand Down Expand Up @@ -610,10 +610,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 = (() => {
Expand Down
10 changes: 5 additions & 5 deletions webgpu/webgpu-optimization-step6-use-mapped-buffers.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
// 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();

/** Given a css color string, return an array of 4 values from 0 to 255 */
const cssColorToRGBA8 = (() => {
Expand Down
10 changes: 5 additions & 5 deletions webgpu/webgpu-optimization-step7-double-buffer-2-submit.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
// 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();

/** Given a css color string, return an array of 4 values from 0 to 255 */
const cssColorToRGBA8 = (() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
// 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();

/** Given a css color string, return an array of 4 values from 0 to 255 */
const cssColorToRGBA8 = (() => {
Expand Down
Loading

0 comments on commit 48050b7

Please sign in to comment.