WebGL/OpenGL:性能比较 [英] WebGL/OpenGL: comparing the performance

查看:211
本文介绍了WebGL/OpenGL:性能比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于教育目的,我需要比较 WebGL 与 OpenGL 的性能.我有两个用 WebGL 和 OpenGL 编写的等效程序,现在我需要获取它们的帧速率并比较它们.

For educational purposes I need to compare the performance of WebGL with OpenGL. I have two equivalent programs written in WebGL and OpenGL, now I need to take the frame rate of them and compare them.

在 Javascript 中,我使用 requestAnimationFrame 来制作动画,我注意到它会导致帧速率始终保持在 60 FPS,并且只有在我切换选项卡或窗口时才会下降.另一方面,如果我总是递归调用渲染函数,窗口会因为明显的原因而冻结.

In Javascript I use requestAnimationFrame to animate, and I noticed that it causes the frame rate to be always at 60 FPS, and it goes down only if I switch tab or window. On the other hand if I always call the render function recursively, the window freezes for obvious reasons.

var stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '450px';
stats.domElement.style.top = '750px';

document.body.appendChild( stats.domElement );

setInterval( function () {

    stats.begin();
    stats.end();
}, 1000 / 60 );

            
var render= function() {
    requestAnimationFrame(render);
    renderer.render(scene,camera);
}

render();

现在如果场景总是以 60 FPS 的速度存在的问题是,我实际上无法将它与 OpenGL 的帧速率进行比较,因为 OpenGL 仅在以某种方式修改场景(例如,如果我旋转对象)和 glutPostRedisplay() 被调用.

Now the problem if having always the scene at 60 FPS is that I cannot actually compare it with the frame rate of OpenGL, since OpenGL redraws the scene only when it is somehow modified (for example if I rotate the object) and glutPostRedisplay() gets called.

所以我想 WebGL 中是否有一种方法可以仅在必要时重绘场景,例如当对象旋转或着色器中的某些属性发生更改时.

So I guess if there is a way in WebGL to redraw the scene only when it is necessary, for example when the object is rotated or if some attributes in the shaders are changed.

推荐答案

在 WebGL 中,您无法通过推送帧直接比较 GPU 之间的帧率.相反,您需要弄清楚在一个框架内可以完成多少工作.

You can't compare framerates directly across GPUs in WebGL by pushing frames. Rather you need to figure out how much work you can get done within a single frame.

所以,基本上选择一些目标帧率,然后继续做越来越多的工作,直到超过目标.当您达到目标时,您可以做多少工作.您可以将其与使用相同技术的其他机器或 GPU 进行比较.

So, basically pick some target framerate and then keep doing more and more work until you go over your target. When you've hit your target that's how much work you can do. You can compare that to some other machine or GPU using the same technique.

有些人会建议使用 glFinish 来检查时间.不幸的是,这实际上不起作用,因为它会停止图形管道,而且这种停止本身并不是在真实应用程序中通常会发生的事情.这就像计算汽车从 A 点到 B 点的速度,但不是在 A 点之前开始很久,在 B 点之后很久结束,而是在到达 B 点之前猛踩刹车并测量到达 B 点的时间.时间包括减速所花费的所有时间,这在每个 GPU 上是不同的,在 WebGL 和 OpenGL 之间是不同的,甚至对于每个浏览器也是不同的.您无法知道有多少时间花在了减速上,又有多少时间花在了您真正想要衡量的事情上.

Some people will suggest using glFinish to check timing. Unfortunately that doesn't actually work because it stalls the graphics pipeline and that stalling itself is not something that normally happens in a real app. It would be like timing how fast a car can go from point A to point B but instead of starting long before A and ending long after B you slam on the brakes before you get to B and measure the time when you get to B. That time includes all the time it took to slow down which is different on every GPU and different between WebGL and OpenGL and even different for each browser. You have no way of knowing how much of the time spent is time spent slowing down and how much of it was spent doing the thing you actually wanted to measure.

因此,您需要全程全速行驶.就像汽车一样,您会在到达 A 点之前加速到最高速度,然后一直保持最高速度直到您通过 B 点.就像他们在排位赛中为赛车计时一样.

So instead, you need to go full speed the entire time. Just like a car you'd accelerate to top speed before you got to point A and keep going top speed until after you pass B. The same way they time cars on qualifying laps.

您通常不会通过猛击休息时间 (glFinish) 来停止 GPU,因此将停止时间添加到您的计时测量中是无关紧要的,并且不会为您提供有用的信息.使用 glFinish 你会计时绘图+停止.如果一个 GPU 在 1 秒内绘制并在 2 内停止,而另一个 GPU 在 2 秒内绘制并在 1 内停止,则两个 GPU 的计时将为 3 秒.但是如果你在不停止的情况下运行它们,一个 GPU 每秒会绘制 3 个东西,而另一个 GPU 每秒只能绘制 1.5 个东西.一个 GPU 显然更快,但使用 glFinish 你永远不会知道这一点.

You don't normally stall a GPU by slamming on the breaks (glFinish) so adding the stopping time to your timing measurements is irrelevant and doesn't give you useful info. Using glFinish you'd be timing drawing + stopping. If one GPU draws in 1 second and stops in 2 and another GPU draws in 2 seconds and stops in 1, your timing will say 3 seconds for both GPUs. But if you ran them without stopping one GPU would draw 3 things a second, the other GPU would only draw 1.5 things a second. One GPU is clearly faster but using glFinish you'd never know that.

相反,您通过尽可能多地绘制来全速运行,然后测量您能够完成多少并保持全速.

Instead you run full speed by drawing as much as possible and then measure how much you were able to get done and maintain full speed.

这是一个例子:http://webglsamples.org/lots-o-objects/lots-o-objects-draw-elements.html

它基本上绘制每一帧.如果帧速率为 60fps,它会在下一帧再绘制 10 个对象.如果帧速率低于 60 fps,则绘制较少.

It basically draws each frame. If the frame rate was 60fps it draws 10 more objects the next frame. If the frame rate was less than 60fps it draws less.

由于浏览器计时并不完美,您可能会选择一个稍低的目标,例如 57fps,以了解它的速度.

Because browser timing is not perfect you might be to choose a slightly lower target like 57fps to find how fast it can go.

最重要的是,WebGL 和 OpenGL 真的只是与 GPU 对话,而 GPU 做真正的工作.无论是 WebGL 要求 GPU 还是 OpenGL,GPU 完成的工作都将花费完全相同的时间.唯一的区别在于设置 GPU 的开销.这意味着你真的不想画任何沉重的东西.理想情况下,你几乎什么都不会画.将您的画布设为 1x1 像素,绘制一个三角形,然后检查时间(例如在 60fps 的 WebGL 和 OpenGL 中一次可以绘制多少个三角形).

On top of that, WebGL and OpenGL really just talk to the GPU and the GPU does the real work. The work done by the GPU will take the exact same amount of time regardless of if WebGL asks the GPU to do it or OpenGL. The only difference is in the overhead of setting up the GPU. That means you really don't want to draw anything heavy. Ideally you'd draw almost nothing. Make your canvas 1x1 pixel, draw a single triangle, and check the timing (as in how many single triangles can you draw one triangle at a time in WebGL vs OpenGL at 60fps).

但情况会变得更糟.一个真正的应用程序会经常切换着色器、切换缓冲区、切换纹理、更新属性和制服.那么,你的时间是什么?您可以在 60fps 下调用多少次 gl.drawBuffers?您可以在 60fps 下调用多少次 gl.enablegl.vertexAttribPointergl.uniform4fv?某种组合?什么是合理的组合?10% 调用 gl.verterAttribPointer + 5% 调用 gl.bindBuffer + 10% 调用 gl.uniform.这些调用的时间是 WebGL 和 OpenGL 之间唯一不同的地方,因为最终它们与同一个 GPU 进行通信,而 GPU 无论如何都会以相同的速度运行.

It gets even worse though. A real app will switch shaders, switch buffers, switch textures, update attributes and uniforms often. So, what are you timing? How many times you can call gl.drawBuffers at 60fps? How many times you can call gl.enable or gl.vertexAttribPointer or gl.uniform4fv at 60fps? Some combination? What's a reasonable combination? 10% calls to gl.verterAttribPointer + 5% calls to gl.bindBuffer + 10% calls to gl.uniform. The timing of those calls are the only things different between WebGL and OpenGL since ultimately they're talking to the same GPU and that GPU will run the same speed regardless.

这篇关于WebGL/OpenGL:性能比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆