javascript - 有没有一种从 asm.js 模块处理多个数组的好方法?

标签 javascript asm.js

特别是,我正在尝试实现一个向量数学模块来处理向量和矩阵。

我最初的计划如下:对所有同类对象(比如 4x4 矩阵)使用一个大堆,为相互计算保留一些空间,并通过偏移量访问其余矩阵。这是我的代码示例:

'use strict';

function Mat4(stdlib, foreign, heap) {
    'use asm';

    var H = new stdlib.Float32Array(heap);

    function identity(n) {
        n = n|0;

        var offset = 0;
        offset = ((n|0) << 6)|0;

        H[((offset|0)) >> 2] = 1.0;
        H[((offset|0) + 4) >> 2] = 0.0;
        H[((offset|0) + 8) >> 2] = 0.0;
        H[((offset|0) + 12) >> 2] = 0.0;
        H[((offset|0) + 16) >> 2] = 0.0;
        H[((offset|0) + 20) >> 2] = 1.0;
        H[((offset|0) + 24) >> 2] = 0.0;
        H[((offset|0) + 28) >> 2] = 0.0;
        H[((offset|0) + 32) >> 2] = 0.0;
        H[((offset|0) + 36) >> 2] = 0.0;
        H[((offset|0) + 40) >> 2] = 1.0;
        H[((offset|0) + 44) >> 2] = 0.0;
        H[((offset|0) + 48) >> 2] = 0.0;
        H[((offset|0) + 52) >> 2] = 0.0;
        H[((offset|0) + 56) >> 2] = 0.0;
        H[((offset|0) + 60) >> 2] = 1.0;

        return ((offset|0) >> 2)|0;
    }

    return {
        identity: identity
    };
};

var buffer = new ArrayBuffer(4096);
var fArray = new Float32Array(buffer);
var mod = Mat4(window, {}, buffer);

var dmat4 = {
    counter: 0
};

dmat4.identity = function() {
    var offset = mod.identity(dmat4.counter++);
    return fArray.subarray(offset, offset + 16);
};

这似乎可行,但似乎比仅就地创建 Float32Array 并用值填充它要慢得多。我的猜测是所有偏移量计算都占用了大部分时间,并且在编译此 asm.js 代码时并未对其进行优化。

但也许我遗漏了什么,这段代码可以改进吗?

最佳答案

按以下方式重新编写代码:

'use strict';

function Mat4(stdlib, foreign, heap) {
    'use asm';

    var H = new stdlib.Float32Array(heap);
    var I = new stdlib.Uint8Array(heap);

    function identity() {
        var offset = 0;
        offset = ((I[0]|0 + 16) << 6)|0;
        I[0] = I[0]|0 + 1;

        H[offset >> 2] = 1.0;
        H[(offset + 4) >> 2] = 0.0;
        H[(offset + 8) >> 2] = 0.0;
        H[(offset + 12) >> 2] = 0.0;
        H[(offset + 16) >> 2] = 0.0;
        H[(offset + 20) >> 2] = 1.0;
        H[(offset + 24) >> 2] = 0.0;
        H[(offset + 28) >> 2] = 0.0;
        H[(offset + 32) >> 2] = 0.0;
        H[(offset + 36) >> 2] = 0.0;
        H[(offset + 40) >> 2] = 1.0;
        H[(offset + 44) >> 2] = 0.0;
        H[(offset + 48) >> 2] = 0.0;
        H[(offset + 52) >> 2] = 0.0;
        H[(offset + 56) >> 2] = 0.0;
        H[(offset + 60) >> 2] = 1.0;

        return (offset >> 2)|0;
    }

    return {
        identity: identity
    };
};

var buffer = new ArrayBuffer(65536);
var array = new Float32Array(buffer);
var mod = Mat4(window, {}, buffer);

var dmat4 = {};

dmat4.identity = function() {
    var offset = mod.identity();
    return array.subarray(offset, offset + 16);
};

dmat4.create = dmat4.identity;

dmat4.identity();

现在只比 glMarix 方法慢 2 倍(我猜这是预料之中的);

关于javascript - 有没有一种从 asm.js 模块处理多个数组的好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16704445/

相关文章:

webgl - 如何通过 Emscripten 激活抗锯齿

javascript - 满足的状态

javascript - 从类型化数组更新 svg 路径

javascript - 对于JavaScript事件,冒泡比捕获好吗?

javascript - 在多表列中具有多个术语的简单 PHP 过滤器

javascript - 为什么 asm.js 会降低性能?

javascript - emscripten:如何删除 C++ 代码中分配的 std::vector 内存

javascript - 手写 asm.js

javascript - 从字符串 JavaScript 中提取数字

javascript - 双向链表可以在每个节点项上调用一个函数吗?