【发布时间】:2018-03-02 02:12:21
【问题描述】:
对于这个广泛的问题,我们深表歉意!我正在学习 WASM,并在 C 语言中创建了 Mandelbrot 算法:
int iterateEquation(float x0, float y0, int maxiterations) {
float a = 0, b = 0, rx = 0, ry = 0;
int iterations = 0;
while (iterations < maxiterations && (rx * rx + ry * ry <= 4.0)) {
rx = a * a - b * b + x0;
ry = 2.0 * a * b + y0;
a = rx;
b = ry;
iterations++;
}
return iterations;
}
void mandelbrot(int *buf, float width, float height) {
for(float x = 0.0; x < width; x++) {
for(float y = 0.0; y < height; y++) {
// map to mandelbrot coordinates
float cx = (x - 150.0) / 100.0;
float cy = (y - 75.0) / 100.0;
int iterations = iterateEquation(cx, cy, 1000);
int loc = ((x + y * width) * 4);
// set the red and alpha components
*(buf + loc) = iterations > 100 ? 255 : 0;
*(buf + (loc+3)) = 255;
}
}
}
我正在编译为 WASM,如下所示(为清楚起见,省略了文件名输入/输出)
clang -emit-llvm -O3 --target=wasm32 ...
llc -march=wasm32 -filetype=asm ...
s2wasm --initial-memory 6553600 ...
wat2wasm ...
我正在加载JavaScript,编译,然后调用如下:
instance.exports.mandelbrot(0, 300, 150)
输出被复制到画布,这使我能够验证它是否正确执行。在我的电脑上执行上述函数大约需要 120 毫秒。
但是,这里有一个 JavaScript 等价物:
const iterateEquation = (x0, y0, maxiterations) => {
let a = 0, b = 0, rx = 0, ry = 0;
let iterations = 0;
while (iterations < maxiterations && (rx * rx + ry * ry <= 4)) {
rx = a * a - b * b + x0;
ry = 2 * a * b + y0;
a = rx;
b = ry;
iterations++;
}
return iterations;
}
const mandelbrot = (data) => {
for (var x = 0; x < 300; x++) {
for (var y = 0; y < 150; y++) {
const cx = (x - 150) / 100;
const cy = (y - 75) / 100;
const res = iterateEquation(cx, cy, 1000);
const idx = (x + y * 300) * 4;
data[idx] = res > 100 ? 255 : 0;
data[idx+3] = 255;
}
}
}
只需要大约 62 毫秒即可执行。
现在我知道 WebAssembly 是非常新的,并且没有经过非常优化。但是我还是忍不住觉得应该比这个快!
谁能发现我可能遗漏的明显东西?
另外,我的 C 代码从“0”开始直接写入内存 - 我想知道这是否安全?堆栈在分页线性内存中存储在哪里?我会冒险覆盖它吗?
这里有一个小提琴来说明:
https://wasdk.github.io/WasmFiddle/?jvoh5
运行时,它会记录两个等效实现(WASM 然后是 JavaScript)的时间
【问题讨论】:
-
你能提供类似 jsfiddle 的链接来试用吗?你测试的是什么浏览器?您的堆栈问题已回答 here,在 WebAssembly 中使用 0 是安全的,但 C++ 在编译到 WebAssembly 时可能会不满意。
-
我只是想让这个在 WasmFiddle 中工作,我会尽快更新问题。浏览器是 Chrome 61。感谢堆栈答案的链接。
-
@JFBastien - 我添加了一个小提琴 :-)
-
我浏览了 C 版本,并且在任何地方都初始化了一个浮点数,我确保它具有“.0f”并且性能显着提高。通过这一更改,WebAssembly 版本比我笔记本电脑上的 JS 版本更快。但是,在我的桌面上,JS 版本仍然比 WebAssembly 版本快。修改后的小提琴:wasdk.github.io/WasmFiddle/?xbo35
标签: webassembly