Emscripten 将 C++ 编译为 JavaScript 和 Asm.js 的结果不佳
Posted
技术标签:
【中文标题】Emscripten 将 C++ 编译为 JavaScript 和 Asm.js 的结果不佳【英文标题】:Bad results with Emscripten compiling C++ to JavaScript & Asm.js 【发布时间】:2014-12-05 12:59:20 【问题描述】:对于大学的一门课程,我必须演示 asm.js。我找到了一个教程 (http://www.sitepoint.com/understanding-asm-js/),这正是我想要的。 所以我创建了给定的 C++ 文件并用 Emscripten 编译它。 结果是一个近 10000 行长的文件。无处可找到“使用 asm”语句。与手写的 javascript 文件相比,它要慢得多。
我正在使用便携式 Emscripten-SDK-package 并在使用前对其进行了更新。
如何让 Emscripten 生成好的 asm 代码?
更新: 我在没有 Emscipten 的情况下为我的演示找到了不同的解决方案: https://gist.github.com/dherman/3d0b4733303eaf4bae5e。 也许有人需要这个。
【问题讨论】:
虽然我没有找到让 Emscripten 设置“use asm”语句的方法(我手动更改了它),但我使用 @scott-stensland 输出的代码必须像确实是这样,但问题很简单,纯 js 只比 10k 行代码快。但我不知道,为什么 Emscripten 不在代码中添加“use asm”。 【参考方案1】:从我的测试来看,Emscripten 似乎只使用 asm.js,并将 "use asm";
放入生成的 Javascript 中,优化级别为 -O1
及以上。所以编译时需要将-O1
(或比1
更高的级别)传递给编译器:
如果不指定优化级别,或通过-O0
:
然后"use asm";
不会被放入生成的 Javascript。
【讨论】:
【参考方案2】:10k 行 javascript 相当适中,因为它必须包含与系统库(libc 等)等效的功能,当您执行 c++ 编译源时,系统库作为单独的文件存在 - 当浏览器执行 javascript 时,它的沙盒化并且无法访问此类目标计算机上的系统库(由于安全性,操作系统中立性......)例如,只需对一些动态链接的 c/c++ 可执行文件执行 ldd 命令,即可了解这 10k 行 javascript 中的大部分内容正在替换:
ldd /bin/ls
linux-vdso.so.1 => (0x00007fff8c865000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f7b82854000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f7b8264b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7b82285000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f7b82018000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7b81e14000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7b82aba000)
libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f7b81c0e000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7b819f0000)
这可能会给你更多关于使用 asm.js 和 emscripten 的提示: https://hacks.mozilla.org/2014/11/porting-to-emscripten/
【讨论】:
以上是关于Emscripten 将 C++ 编译为 JavaScript 和 Asm.js 的结果不佳的主要内容,如果未能解决你的问题,请参考以下文章
2021-09-13 使用Emscripten 将c++编译为WebAssembly给JS调用
使用 Emscripten 将 R 函数编译为 JavaScript