我正在尝试将一些基本的MATLAB移植到Javascript,并且对JS的性能有点失望,无论是Chrome还是Firefox。通过转置其中一个矩阵,展开内部循环并使用Float64Arrays,我进行了略微优化:
function vvdot_body(rollsize)
{
var body = '';
body += ' var acc, ni, nj, nr, rs, lo, i;\n';
body += ' acc = 0.0;\n';
body += ' rs = ' + rollsize + ';\n';
body += ' nr = Math.floor(n / rs);\n';
body += ' lo = n - (nr * rs);\n';
body += ' for (i=0; i<nr; i++) {\n';
body += ' ni = aos + i * rs;\n';
body += ' nj = bos + i * rs;\n';
/* begin unroll */
body += ' acc += a[ni] * b[nj] ';
for (var i=1; i<rollsize; i++)
body += ' + a[ni + ' + i + '] * b[nj + ' + i + ']';
body += ';\n }\n'
/* done unroll */
/* handle leftover */
body += ' ni = aos + nr * rs;\n';
body += ' nj = bos + nr * rs;\n';
body += ' for (i=0; i<lo; i++)\n';
body += ' acc += a[ni + i] * b[nj + i];\n\n';
body += ' return acc;';
return body;
}
function mkvvdot(rollsize)
{
var args = 'a,b,n,aos,bos'
, body = vvdot_body(rollsize);
return new Function(args, body);
}
/* transpose */
function T(b, n, bT) {
for (var i = 0; i < n; i++) {
for (var j = 0; j < n; j++) {
bT[i * n + j] = b[j * n + i];
}
}
}
function mkmmm(unroll) {
var vvdot = mkvvdot(unroll);
return function(a, b, c, n) {
var bT = new Float64Array(n*n);
T(b, n, bT);
for (var i = 0; i < n; i++) {
for (var j = 0; j < n; j++) {
c[i * n + j] = vvdot(a, bT, n, i * n, j * n);
}
}
}
}
以下JS Fiddle运行基准
http://jsfiddle.net/42nmw4yx/2/
在我的机器上(E5-1650),在矢量点内循环中展开的变化显示在Chrome 40中的峰值性能为~2.6 Gflops,在Firefox 35中为~1.0,而MATLAB,单核心,运行15-20 Gflops。
将JS中的天真算法与供应商的线性代数库(MKL)进行比较似乎是不公平的,我可以接受50%的性能损失,但2015年的数量级似乎是不合理的。
除了(ab)使用WebGL进行计算外,我还能做什么?可能的答案属于1)Javascript的类别,即不使用匿名函数(实际上并不慢)2)线性代数技巧,即转置其中一个矩阵(我已经完成了,具有很好的加速) 3)其他?
编辑修正了flops / s以简单地触发。此外,我在引用NumPy安装(Debian软件包)上运行了bencmark,它显示了与Javascript相同的错误性能,因此由于MKL的全能性而出现了性能上的巨大差异。 MKL&amp;供应商调整库..
答案 0 :(得分:0)
您可以尝试使用SIMD.JS.它目前在Firefox中受支持,但尚未在Chrome中支持。在这手牌上有Crosswalk(https://crosswalk-project.org/),它是使用Chromium源码基础构建的,可以在许多平台上使用。
SIMD指令可通过英特尔®酷睿™和英特尔®凌动™处理器以及ARM *处理器访问。
答案 1 :(得分:0)
在Firefox中尝试此操作(每晚) https://jsperf.com/simdmat4
您也可以在Chrome中使用标记--js-flags =“ - harmony-simd”
在Firefox中,SIMD的速度要快3倍,Chrome的速度要慢20倍(Chrome还在使用polyfill?)