Paw*_*wel 5 javascript c++ emscripten asm.js
我正在尝试运行4x4矩阵乘法的C++函数.2天后,它终于有效了,但不如预期的那样.
通常将参数反馈给函数,然后是这一行:
dataHeap2.set( new Uint8Array(data2.buffer) );
Run Code Online (Sandbox Code Playgroud)
产生错误"Uncaught RangeError:Source is too large"
一眼就看起来它只是一个普通的Float32Array,有16个元素,但在查看它的缓冲区大小后,它似乎有所不同
console.log(data2.buffer.bufferLength);
Run Code Online (Sandbox Code Playgroud)
结果不是预期的64字节,而是像3342345这样的巨大数字.这是问题吗?我通过手动复制值(如下所示)找到了一种解决方法,返回该值然后问题就消失了.不幸的是,它使我的代码比直接在缓冲区上运行慢得多.
// bad solution - which works
for(var i = 0; i < 16; i++) {
dataTarget[i] = result[i];
}
Run Code Online (Sandbox Code Playgroud)
希望今晚我会找到一个更好的解决方案,我想继续使用这个功能,因为它使用编译的C++代码使用ASM.JS + SIMD来解决多个字符.在纯JavaScript中,它仍然太慢.这是整个功能.我很确定data2正在使用Emscripten的HEAP,我想避免它.
matrix4multiply = function(data, data2) {
// Import function from Emscripten generated file
var mmul_vec4 = Module.cwrap(
'mmul_vec4', 'number', ['number', 'number', 'number']
);
var dataTarget = new Float32Array(16);
// Get data byte size, allocate memory on Emscripten heap, and get pointer
var nDataBytes = dataTarget.length * dataTarget.BYTES_PER_ELEMENT;
// First matrix copy data to Emscripten heap
var dataPtr = Module._malloc(nDataBytes);
var dataPtr2 = Module._malloc(nDataBytes);
var dataPtr3 = Module._malloc(nDataBytes);
var dataHeap = new Uint8Array(Module.HEAPU8.buffer, dataPtr, nDataBytes);
dataHeap.set( new Uint8Array(data.buffer) );
// second matrix allocate and copy to emscripten's heap
var dataHeap2 = new Uint8Array(Module.HEAPU8.buffer, dataPtr2, nDataBytes);
dataHeap2.set( new Uint8Array(data2.buffer) );
// target heap
var targetHeap = new Uint8Array(Module.HEAPU8.buffer, dataPtr3, nDataBytes);
targetHeap.set( new Uint8Array(dataTarget.buffer) );
// Call the function by passing a number pointing to the byte location of
// the array of pointers on the Emscripten heap. Emscripten knows what to do!
mmul_vec4(dataHeap.byteOffset, dataHeap2.byteOffset, targetHeap.byteOffset);
// get result
var result = new Float32Array(targetHeap.buffer, targetHeap.byteOffset, 16);
// bad solution - which works
//for(var i = 0; i < 16; i++) {
// dataTarget[i] = result[i];
//}
// Free memory
Module._free(dataHeap.byteOffset);
Module._free(dataHeap2.byteOffset);
Module._free(targetHeap.byteOffset);
return result;
}
Run Code Online (Sandbox Code Playgroud)
编辑:简化版不要担心malloc等
new Uint8Array(Module.HEAPU8.buffer, this.dataPtr, 64).set( new Uint8Array(data.buffer, data.byteOffset, 64) );
// second matrix allocate and copy to emscripten's heap
new Uint8Array(Module.HEAPU8.buffer, this.dataPtr + 72, 64).set( new Uint8Array(data2.buffer, data2.byteOffset, 64) );
// multiply first two parameters and return in the last one
this.mmul_vec4(this.dataPtr, this.dataPtr + 72, this.dataPtr + 144);
// like that it works, unfotunately copying is being made here
return new Float32Array(Module.HEAPU8.buffer.slice(this.dataPtr + 144, this.dataPtr + 208));
// with this version (if uncommented) there's just white screen(but it looks like the game is working.
//return new Float32Array(Module.HEAPU8.buffer, this.dataPtr + 144, 16);
Run Code Online (Sandbox Code Playgroud)
要使用 的头 64 字节data2
,请指定偏移量和长度。
dataHeap2.set( new Uint8Array(data2.buffer, data2.byteOffset, nDataBytes) );
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4657 次 |
最近记录: |