turbo.js 是一个很小的 JavaScript 库,用来简化并行的复杂计算。其设计的计算(内核执行)是基于 GPU 进行的,这使得其可以在同一时间对一组数据进行同时操作。
turbo.js 兼容所有的浏览器(甚至是不使用 ES6 模板字符串的 IE)以及几乎所有桌面和移动的 GPU。
在线演示和简单的介绍请看 turbo.github.io.
示例1
在上述网站我们可以看到对一个非常大的数组值进行简单计算的例子。
第 1 段(可获 1.33 积分)
0
CY23天前
不管是 turbo.js 还是 JavaScript,分配内存的类型是严格的,并通过 32 位 IEEE 浮点数值的一维数组呈现。所以 .data 子数组是一个标准的 JavaScript Float32Array
对象。内存分配完毕后,你可以对该数组进行任意操作,但不能更改其大小。如果你试图修改数组大小,将会遇到未知错误。
if (turbojs) { var foo = turbojs.alloc(1e6);
}
我们现在有了一个包含 100 万个元素的数组,下面给数组填充一些值。
if (turbojs) { var foo = turbojs.alloc(1e6); for (var i = 0; i < 1e6;="" i++)="" foo.data[i]="i;" print="" first="" five="">
console.log(foo.data.subarray(0, 5));
}
第 3 段(可获 0.89 积分)
0
CY23天前
示例2: 向量
有些时候你希望在一个操作中返回多个值,尽管看起来不太好,但我们一直都这样做。commit 和 read 实际上都支持 4 维的向量:
vec4 read()
返回 GLSL 的数据类型 vec4
.
void commit(vec4)
要求 vec4 参数并写到内存
vec4
类型其实就是一个数组,你可以认为是相当于 JavaScript 这样的形式:foobar = {r:0, g:0, b:0, a:0}
,与 JavaScript SIMD 的
Float32x4 非常相似。
GLSL 很棒的一点是所有操作都是可重载的,因此它可以处理向量而不是单独处理每个元素,因此
第 5 段(可获 1.4 积分)
0
CY23天前
每一次运行,每个 vec4 内存分配的前两个值使用随机坐标进行填充,并作为分形函数的输入:
for (var i = 0; i < samplesize;="" i="" +="4)">
testData.data[i] = Math.random();
testData.data[i + 1] = Math.random();
}
每一个操作结果将会产生一个灰度色值,这个数值将被写到每一个向量的第三个元素:
function testJS() { for (var i = 0; i < samplesize;="" i="" +="4)" {="" var="" x0="-2.5" +="" (3.5="" *="" testdata.data[i]);="" var="" y0="testData.data[i" +="" 1],="" x="0," y="0," xt="0," c="0;" for="" (var="" n="0;" n="">< sampleiterations;="" n++)="" {="" if="" (x="" *="" x="" +="" y="" *="" y="">= 2 * 2) break;
xt = x * x - y * y + x0;
y = 2 * x * y + y0;
x = xt;
c++;
} var col = c / sampleIterations;
testData.data[i + 2] = col;
}
}
第 7 段(可获 0.61 积分)
0
CY23天前
看看 JavaScript 代码转为 GLSL 是有多简单,没有特别的方式。当然了,这个例子并不是在 JavaScript 和 GLSL 中最优化的算法,我们只不过是为了比较而已。
示例3: 调试
GLSL 代码是通过 GPU 向量编译器进行编译的。通常这些编译器都会提供非常详尽的错误信息。你可以通过捕获 turbo.js 抛出的异常来获取编译时的错误。例如下面代码所示:
if (turbojs) { var foo = turbojs.alloc(1e6); var nFactor = 4;
turbojs.run(foo, `void main(void) {
commit(${nFactor}. + bar);
}`);
}
第 9 段(可获 0.99 积分)
CY23天前
上面代码会产生两个错误,第一个是 bar 未被初始化;第二个是类型不匹配:commit 函数的参数要求是向量,但却传递了浮点类型。打开你的浏览器控制台就会看到项目错误信息:
注意事项
你最好提供一个 JavaScript 回退方法,用于浏览器不支持 turbo.js 的情况
使用 web workers 来处理大数据集,避免页面操作堵塞
使用假数据来对 GPU 进行热身,否则将无法得到 GPU 的充分性能表现
关于错误检查,使用小的数据集进行检查,如果检查不通过则回退到 JavaScript 方法
我没有试过,但我猜你会用 glsl-transpiler 来自动创建 JS 回退代码
认真考虑你是否真的需要用 turbo.js ,你应该优先考虑算法的优化,考虑使用 JS SIMD。turbo.js 并不适用于非并行计算场景。
联系客服