gpt4 book ai didi

javascript - WebGL,优化Web Worker的几何计算

转载 作者:行者123 更新时间:2023-11-30 05:40:08 27 4
gpt4 key购买 nike

嗨,我正在开发一个webgl应用程序,该应用程序需要动态生成许多2d几何形状,例如折线和复杂多边形。当前,已使用的顶点/颜色/索引/ texcoords已预先分配,然后根据主更新循环中的用户输入进行计算。

我尽量回收,例如。当绘制150000个圆时,我尝试确保仅一次计算几何图形/颜色/ texcoords /索引,除非基本参数(圆细节,...)不变,然后平移,缩放(x&y),旋转顶点,(移动索引并设置顶点颜色)此“圆形蓝图”的x倍于用户指定的数量。
之后,通过一次drawArrays / drawElements调用发送数据。绘制折线和其他图元的处理方式相似。

尽管这已经相当快了,但显然将大量时间用于将原始顶点转换为新的位置和尺寸,有时只剩下少量的资源,用户可以使用这些资源来实际构建要显示的内容。
因此,我问自己如何将那些“简单”的计算外包。在考虑以gpgpu方式进行操作之前,我曾考虑过将这些计算移至网络工作者。

所以这就是我的想法:


主线程:用户发送请求以绘制150000个圆,提供尺寸,变换和颜色
主线程:请求被推送到绘制请求队列
主线程:将请求数据发送到Web工作者(如果该工作者尚未启动或已完成先前的队列项目)
网络工作者:正在使用足够大的预分配数据集来构建几何并对其进行转换
Web Worker:通过以下方式传输转换后的Float32Array顶点,颜色数据和Uint16Array索引数据
可转移对象到主线程
主线程:onWorkeRequestProcessed:获取由工作人员发送的数据,发送给glDrawArrays / glDrawElements调用,
将数据发送回工作人员
网络工作者:接收数据,将“确定,一切恢复原状,我准备好另一个请求了”味精到主线程
主线程:转移队列,从前面发送下一个请求


...
因此,最后希望主线程可以使用更多资源来执行一些用户启动的计算。

这样做意味着主循环始终必须等待,直到工作人员完全线性线性地处理了队列,才能以正确的顺序绘制所有内容,最后可能使使用工作人员的优势过时。

这是我到目前为止的内容:https://gist.github.com/automat/8566773(没有webgl部分,只有消息队列,没有主循环,因为同步帧步长和等待工作程序也是一个问题)

顺便说一句:不能通过纹理四边形实例化几何实体。

您可以在这里查看项目:https://github.com/automat/canvasGL.js(src / gl / cglContext.js应该特别有趣)

这样好吗任何提示表示赞赏...

最佳答案

过去的时候,我从事图形流水线工作,当时您的平均poly muncher是一套VME机架,价格约为$ 1.000.000,几乎每秒只能吐出10K polys 50次。接下来的内容是一个粗略而粗糙的轮廓,但是我已经编写了使之正常工作的软件,并且我很确定这种方式确实可以以一种有效的方式完成工作。

基本上,您需要在这里进行良好的数据依赖分析。

如果要获得一些计算能力,则必须在尽可能多的CPU内核上生成工作线程。您的问题是轻松并行化的完美案例,因为您要计算的每个几何图元之间没有依赖关系。

在这里看来,您的主线程似乎无所事事,只需要拧动它的虚拟拇指来等待您的工人完成自己的圈子咀嚼业务。您将避免阻塞浏览器用户界面,但在CPU功能方面一无所获。

但是,您可以执行以下操作:


将您的圈子分成大包(假设每个100圈,总共150包,共100圈)。
将所有这些数据包放入公共输入队列
每个CPU上都运行着一个相同工作线程的实例
每个工作线程将从公共输入队列中选择下一个可用数据包,对其进行处理,然后将结果放回公共输出队列中。
让主线程从输出队列中抓取数据包,并将其提供给饥饿的GPU。


有了这种架构,您将使所有CPU全速运行,并在循环上进行真正的并行计算。

公共队列将充当简单的自动负载平衡器。
想象一下,由于某些原因,某些圆的计算成本比其他圆高。不幸的是,虽然有一个需要处理数据包的CPU,但它只会花费更多的时间来处理它,而其兄弟姐妹会将更多更快的数据包从队列中弹出。
就像在普通邮局的办公桌上进行工作负载平衡一样,当多个办公桌为一个客户队列提供服务时。

一旦处理了第一批100个圆圈,从高级软件到GPU的管道就会开始填充。运行主应用程序的CPU可能花费很少的时间来给GPU供电,而工作线程将有近100%的CPU时间可用来执行与运行在专用CPU上的同级兄弟相同的计算。

总的计算时间将几乎除以系统上可用CPU的数量(在同步和其他背景噪声中损失5%或损失5%)。

整个管道的全局同步将需要一些思考,但是基本上您知道给定帧生成了多少数据包,因此您可以轻松地计算通过输入和输出队列传输的数据包的数量,从而确定何时给定的图像生成周期已经结束。

不过要当心:这假设您的圆包确实可以独立计算,也就是说,它们仅依赖于当前帧的全局信息(通常是相机位置和一些照明参数)。
如果必须执行全局遮挡剔除之类的操作,则可以亲吻并行处理再见(当然,除非为此设计专门的并行化算法)。

编辑:

我进行了一些基本测试,以查看这些工人是否在充分利用其他CPU。请参阅this fiddle,其中9个或10个工作人员一直在紧密运行。

这已在FireFox上进行了测试,但由于使用blob创建工作程序代码的安全限制而未能在IE11上运行。我仅使用此技巧是为了使演示适合JSFiddle。我想如果您使用常规的.js文件,该代码应该在IE11上可以正常运行。

<script id='worker' type='worker'>
onmessage = function (e)
{
// eat 100% CPU for the requested number of seconds
var done = Date.now()+e.data*1000;
while (Date.now() < done) { /* wasting CPU here */ }

// signal done
postMessage('');
};
</script>


由于某些原因,CPUS似乎没有被完全占用。这可能与我的虚拟等待循环有关,或者可能是工作人员分配没有充分利用多核。
根据我从Mozilla文档中了解到的那样,应该在多个内核上生成工作线程,但是据我所知,您无法控制它。

无论如何,如果您使用真实的计算而不是虚拟的,这可能是一些性能测试的基础。当然,您应该使用直接数据访问,否则消息副本将破坏工作人员之间共享数据的大部分好处。

关于javascript - WebGL,优化Web Worker的几何计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21294082/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com