我制作了一个简单的基准程序,以测试WebAssembly代码和javascript之间的性能。问题是,当调用导出的函数时,我得到一个0
值,而如果我要使用gcc
编译C程序,则将得到适当的输出。例如,4.843003
。
我只是刚开始进行WebAssembly编程,所以我不确定自己做错了什么。当我返回一个硬编码的数字时,它似乎可以在我的Chrome JS控制台中正常工作。
我用来编译的标志:
emcc -Os main.c -o main.wasm -s WASM=1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <emscripten.h>
int MAX_SIZE = 1000000;
int MAX_RUNS = 1000;
EMSCRIPTEN_KEEPALIVE
float benchmark() {
int i, j;
float seconds;
clock_t t;
int arr[MAX_SIZE];
srand(time(0));
t = clock();
for(i = 0; i < MAX_RUNS; i++) {
for(j = 0; j < MAX_SIZE; j++) {
arr[j] = rand();
}
}
t = clock() - t;
seconds = ((float)t) / CLOCKS_PER_SEC;
return seconds;
}
我想我不太确定importObject
是什么在JS代码中。我刚刚按照一些教程来获取某种输出,并通过查看wasm2wat
输出来提出:
const importObject ={
env: {
STACKTOP: 0,
STACK_MAX:65536,
abortStackOverflow: function(val) { throw new Error("stackoverfow"); },
memory: new WebAssembly.Memory( { initial: 256, maximum:256 } ),
table: new WebAssembly.Table( { initial:14, maximum:14, element: "anyfunc" } ),
__memory_base:0,
__table_base:0,
_clock: () => {},
abort: () => {},
___syscall146: () => {},
_emscripten_memcpy_big: () => {},
___syscall6: () => {},
___syscall54: () => {},
_time: () => {},
___syscall140: () => {},
_printf: () => {},
_rand: () => {},
_srand: () => {},
abortOnCannotGrowMemory: () => {},
nullFunc_ii: () => {},
nullFunc_iiii: () => {},
nullFunc_jiji: () => {},
___lock: () => {},
___setErrNo: () => {},
___unlock: () => {},
_emscripten_get_heap_size: () => {},
_emscripten_memcpy_big: () => {},
_emscripten_resize_heap: () => {},
setTempRet0: () => {},
tempDoublePtr: 0,
DYNAMICTOP_PTR: 0
}
};
WebAssembly.instantiateStreaming(fetch("main.wasm"), importObject).then((m) => {
const { instance } = m;
const n = instance.exports._benchmark();
console.log(n);
});
所以我不确定这是否真的合适...关于如何进行的任何想法?
答案 0 :(得分:1)
如@zakki所说,除非您知道它的含义,否则不应该直接运行.wasm
文件。
WebAssembly是真正的最小VM,仅能够运行基本操作。它没有任何系统库。它不知道clock()
是什么意思,它没有任何文件系统,并且不能运行TCP / IP网络...它确实不能执行任何系统操作。
相反,Wasm可以导入外部代码。在浏览器上下文中,Wasm可以导入JS代码以模拟系统库。这就是Emscripten存在的原因。 Emscripten不仅是C / C ++-> Wasm编译器,而且是一个完整的工具链,其中包括必要的JS运行时以模仿C标准库(libc)。
以您的情况为例,您可以看到time()
在JS方面是如何形成Emscripten source code的:
clock: function() {
if (_clock.start === undefined) _clock.start = Date.now();
return ((Date.now() - _clock.start) * ({{{ cDefine('CLOCKS_PER_SEC') }}} / 1000))|0;
}
因此,它基本上是借用JS Date.now()
函数来模拟它。 因此,您不能直接运行.wasm
文件,应在Emscripten JS运行时中运行它。
emcc -Os main.c -o main.js -s WASM=1
或者您可以用HTML制作它并运行它。
emcc -Os main.c -o main.html -s WASM=1
答案 1 :(得分:0)
clock()
始终返回0
,因为未实现_clock
。
使用emscripten运行时。
emcc -Os main.c -o main.js -s WASM=1
或者像这样自己定义它们
_clock: () => { return Date.now() * 1000; },