我正在运行几乎所有的数据处理应用程序:
var f = function(a,b){ /* any function of type int -> int -> int */ };
var g = function(a){ /* any function of type int -> int */ };
function my_computation(state){
var data = state[2];
for (var i=0,l=data.length,res=0; i<l; ++i)
res = f(res,g(data[i]));
state[3] = res;
return res;
}
这种模式几乎是foldl
的模式。这个计算在CPU上不够快。是否有可能在浏览器上以某种方式在GPU上运行该计算?
答案 0 :(得分:3)
来自你的评论:
我对顶点着色器了解不多,但据我所知,它在孤立的像素中工作,而对于折叠,你需要一个累积模式。否?
如果要使用WebGL对数组进行计算,则很可能希望在片段着色器中进行,而不是使用顶点着色器。如果使用覆盖整个视口的输入几何体,则片段着色器就是一个逐个像素地计算图像的程序。它可以用作输入数字参数和任意纹理。此外,您可以将输出渲染为纹理。
这是您输入的方式:将输入数据存储在纹理中,并让片段着色器在纹理中进行查找。在纹理中进行多次偏移查找是完全正常的。例如,这就是模糊效果的工作原理。
你很关心积累。没有本地方法可以对所有像素进行折叠。但是,如果您可以以“map-reduce”方式表达算法,其中reduce操作组合了两个输出,而不关心它们是否是先前reduce步骤的输入,那么您可以这样做:< / p>
g
,非累积计算)着色器程序,生成中间输出纹理。f
),生成另一个纹理的一半宽。 / LI>
这将只在O(log n)JavaScript操作中为您提供单一答案。
答案 1 :(得分:1)
我会说是的。我自己经常这样做。您的数据将作为顶点属性缓冲区附加,自定义着色器将执行折叠代码,将结果“渲染”到屏幕外缓冲区。然后,您将结果缓冲区读回CPU内存。
答案 2 :(得分:1)
鉴于您希望在浏览器上运行它,您受到WebGL /扩展支持的限制,特别是对CPU数据的CPU访问。
您可以在下面的代码库中查看用于过滤器/边缘检测的着色器代码,以了解如何在fragment shader
中执行此操作。
https://github.com/prabindh/sgxperf/blob/master/sgxperf_strings.cpp
在此之后,您可以使用readPixels
访问数据。注 - 片段着色器只能输出定点数据。