我希望在移动设备/架构的WebGL中测量着色器性能。
我知道在着色器中使用'discard()‘效率不是很高,但我想进行一些实验,并获得一些关于着色器在绘制调用方面的性能的数字--其中一个主要标准是在使用'discard()’或只是将对象/顶点放置在平台体的远平面之外时,测量不同移动设备和架构(iPhone、iPad以及瓦片渲染和延迟渲染)的性能。
我是Javascript/WebGL的新手,因此我想请教一些指针,或者可能有人已经有了一些类似的测试,我可以在这些测试的基础上获得一些数字。我还没有在互联网上遇到过这样的片段。任何使用THREE.js或typescript或纯js示例的东西都可以作为入门模板。
谢谢,任何指针都将不胜感激。
谢谢
发布于 2019-05-02 22:59:08
您可以像这样调用gl.readPixels来衡量哪个更快
const startTime = performance.now();
drawLotsOfStuff();
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
const endTime = performance.now();
const elaspedTimeInMilliseconds = endTime - startTime();这不会告诉你渲染的速度,但它可能会告诉你哪种方法更快。
WebGL是多进程的,特别是在Chrome中。默认情况下,当你只是在一个60fps的应用程序中不断渲染时,一切都有可能并行运行。JavaScript正在调用gl.drawXXX,之前的绘制命令是并行运行的。但是,当您调用gl.readPixels时,必须停止整个并行部分,以便在读取数据之前执行前面的所有绘制命令。
这意味着使用gl.readPixels并不能告诉你某个东西的运行速度有多快。它会告诉你花了多少时间
start 2 or 3 processes
2 or 3 commands
如果你想知道什么东西画得有多快,你只想对上面的步骤4进行计时,但基于事物是并行的事实,你可以在计时中包括步骤1.、2.、3.、5.、6.和7.。
尽管如此,假设所有这些都是常量,你至少可以知道步骤3比其他步骤3更快还是更慢。
我说可能是因为浏览器中发生了很多事情。可能会出现垃圾收集问题,或者添加更多步骤的其他事情,这会导致时间不佳。
另一个问题是浏览器会,或者至少是故意返回低分辨率的结果来计时。这是为了减轻Spectre issues。我认为Chrome已经重新打开了高分辨率的结果,因为他们增加了进程隔离,尽管不确定。
让我们测试一下,看看是否得到了一致的结果
function main() {
const gl = document.createElement('canvas').getContext('webgl');
const vs = `
attribute vec4 position;
void main() {
gl_PointSize = 128.0;
gl_Position = position;
}
`;
const fastFS = `
precision highp float;
void main() {
gl_FragColor = vec4(1);
}
`;
const slowFS = `
precision highp float;
// these are here to try to make sure the loop
// is not optimized. (though it could still easily
// be as it's really just color = junk * moreJunk * 100
uniform vec4 junk;
uniform vec4 moreJunk;
void main() {
vec4 color = vec4(0);
for (int i = 0; i < 100; ++i) {
color += junk * moreJunk;
}
gl_FragColor = color;
}
`;
const locations = ['position']; // make position location 0
const fastPrg = twgl.createProgram(gl, [vs, fastFS], locations);
const slowPrg = twgl.createProgram(gl, [vs, slowFS], locations);
const fastTime = time(gl, 'fast', fastPrg);
const slowTime = time(gl, 'slow', slowPrg);
// Because Safari is the new IE we can't not have attirbutes
// as Safari fails the WebGL conformance tests for no attribute
// situations.
{
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, 1000000, gl.STATIC_DRAW);
const posLoc = 0; // assigned in createProgramInfo
gl.enableVertexAttribArray(posLoc);
// only taking X from buffer
gl.vertexAttribPointer(posLoc, 1, gl.FLOAT, false, 0, 0);
}
const fastX = slowTime / fastTime;
console.log(`fast is maybe ${fastX.toFixed(4)}x faster than slow`);
console.log(gl.getError());
function time(gl, label, prg) {
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE);
gl.useProgram(prg);
// use program once so any initialization behind the scenes
// happens (voodoo)
gl.drawArrays(gl.POINTS, 0, 1);
sync(gl);
const startTime = performance.now();
for (let i = 0; i < 100; ++i) {
gl.drawArrays(gl.POINTS, 0, 1000);
}
sync(gl);
const endTime = performance.now();
const elapsedTime = endTime - startTime;
console.log(label, 'elapsedTime:', elapsedTime.toFixed(4));
return elapsedTime;
}
function sync(gl) {
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
}
}
main();<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
当我运行上面的时候,我得到了从3.5x到4.5x的快速着色器比慢速着色器的结果,所以你可以看到结果不一致,但至少我们知道快速着色器实际上比慢速着色器更快,这足以让我们选择一种方法而不是另一种方法。
当然,在不同的GPU上结果可能会有所不同。在iOS上尤其如此,因为iOS设备使用。即使我们要求系统在每次绘制调用和100个绘制调用中绘制100个四边形,换句话说,10000个四边形,平铺渲染器也可能意识到它只需要绘制最后一个四边形。一种解决方法可能是打开与
gl.enable(gl.BLEND);这样,我相信平铺渲染器不能只渲染最后一个四边形。
不幸的是,当我在iOS上运行上面的例子时,我得到的结果是快比慢,这表明(1)浏览器中的计时分辨率是多么糟糕,或者(2)不同的平铺架构是如何工作的,或者(3) iOS驱动程序实际上确实优化了循环。
让我们通过在内部循环中使用纹理来使慢速着色器变得更慢,这样我们实际上必须在每次循环迭代时查找不同的结果。
function main() {
const gl = document.createElement('canvas').getContext('webgl');
const vs = `
attribute vec4 position;
void main() {
gl_PointSize = 128.0;
gl_Position = position;
}
`;
const fastFS = `
precision highp float;
void main() {
gl_FragColor = vec4(1);
}
`;
const slowFS = `
precision highp float;
uniform vec4 junk;
uniform vec4 moreJunk;
uniform sampler2D tex;
void main() {
vec4 color = vec4(0);
for (int i = 0; i < 100; ++i) {
// AFAIK this can not be optimized too much as the inputs
// change over the loop looking up different parts of the texture.
color += texture2D(tex, fract(junk * moreJunk * float(i)).xy * gl_PointCoord.xy);
}
gl_FragColor = color;
}
`;
const fastPrg = twgl.createProgram(gl, [vs, fastFS]);
const slowPrg = twgl.createProgram(gl, [vs, slowFS]);
// Because Safari is the new IE we can't not have attirbutes
// as Safari fails the WebGL conformance tests for no attribute
// situations.
{
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, 1000000, gl.STATIC_DRAW);
const posLoc = 0; // assigned in createProgramInfo
gl.enableVertexAttribArray(posLoc);
// only taking X from buffer
gl.vertexAttribPointer(posLoc, 1, gl.FLOAT, false, 0, 0);
}
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
const data = new Uint8Array(1024 * 1024 * 4);
for (let i = 0; i < data.length; ++i) {
data[i] = Math.random() * 256;
}
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1024, 1024, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
gl.generateMipmap(gl.TEXTURE_2D);
const fastTime = time(gl, 'fast', fastPrg);
const slowTime = time(gl, 'slow', slowPrg);
const fastX = slowTime / fastTime;
console.log(`fast is maybe ${fastX.toFixed(4)}x faster than slow`);
function time(gl, label, prg) {
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE);
gl.useProgram(prg);
// use program once so any initialization behind the scenes
// happens (voodoo)
gl.drawArrays(gl.POINTS, 0, 1);
sync(gl);
const startTime = performance.now();
for (let i = 0; i < 100; ++i) {
gl.drawArrays(gl.POINTS, 0, 1000);
}
sync(gl);
const endTime = performance.now();
const elapsedTime = endTime - startTime;
console.log(label, 'elapsedTime:', elapsedTime.toFixed(4));
return elapsedTime;
}
function sync(gl) {
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
}
}
main();<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>
现在在我的iPhoneX上,我发现快比慢快得多。
那么,我们学到了什么呢?我们可能了解到,如果您的着色器具有类似的性能级别,则很难可靠地区分哪个更快。
https://stackoverflow.com/questions/55948019
复制相似问题