emscripten - 使用 Emscripten 编译的 WebAssembly 可以生成更小的文件大小吗

标签 emscripten webassembly

我对 WebAssembly 非常感兴趣,但我感到沮丧的是,即使是用 C++ 编码并使用 Emscripten 编译的“Hello World”示例,也会在浏览器中加载总共 396KB。是什么赋予了?如何使这更具有尺寸效率?

最佳答案

概括

  • 对于像游戏引擎这样的大型项目,与小型 Hello World 示例相比,Emscripten 生成的代码按比例减少了大小开销。
  • Emscripten 最近在缩小代码大小方面做了很大改进。确保您使用最新的 Emscripten 版本。
  • 添加 -Os –closure 1可以将生成的代码的大小减少 10 倍。

  • 以下是回答问题how can this be made more size-efficient的说明

    为什么会生成这么多代码?

    生成的 Webassembly 数量与编写的 C++ 代码数量成正比 以及该代码的依赖项 .依赖于标准库的 C++ 程序所依赖的代码比您预期的要多。一个简单的add()像这样的功能...
    int add(int x, int y) {
        return x + y;
    }
    

    .. 将生成一个简短的 Webassembly 函数,如下所示:
    (func $add (param $x i32 $y i32) (return i32)
      (get_local 0
       get_local 1
       i32.add))
    

    但是要调用 printf需要定义函数,如 strlen , flockfile , funlockfile , memcpy , fwrite , fputs , __stdio_write ,即制作 printf 所需的标准库中的所有函数称呼。在 native 环境中运行的 C++ 程序将仅与平台的适当 libc 链接,但 Webassembly 需要携带这些 库依赖项 沿着。

    除了用户空间库依赖,生成Webassembly的工具还需要提供运行环境处理系统调用。因此,Hello World 程序需要定义覆盖分配内存和写入字节的系统调用。

    编译器如何缩小代码大小?

    emscripten 的创建者和维护者 Alon Zakai 撰写了 Mozilla Hacks 文章 Shrinking Webassembly and Javascript code sizes in Emscripten .我将在这里总结那篇文章的要点:

    Emscripten 最初专注于通过为系统调用实现 libc 和运行时来提供 Posix 环境,从而轻松移植现有的 C 和 C++ 程序。为了方便起见,通常包含的代码比需要的要多。

    许多运行时是作为 Javascript 代码实现的。 Emscripten 生成在应用程序/库 Webassembly 代码和 Javascript 运行时之间来回调用的代码。

    从未被调用的代码应该被删除。在由称为 Dead Code Elimination 的优化处理的编译器中. Emscripten 构建所有函数的图形并删除那些从未从 main 调用的部分。好吧,这不是严格正确的,但足以解释这一点。

    但是编译器以前无法为跨越 Webassembly 和 Javascript 边界的调用生成那种图表。随着 wasm-dce tool 的加入,情况发生了变化.现在,Emscripten 可以创建 Webassembly 和 Javascript 代码的图形。

    Hello World 程序的“收缩”极限是多少
    printf是一个对文件描述符进行操作的通用函数,它是线程安全的。为 printf 调用生成的代码几乎都必须存在。

    如果您想对正在生成的代码进行更多实验,我推荐 Webassembly Studio在线IDE。它提供了一个示例 Hello World 项目,其中包含一个自述文件,其中介绍了生成的库代码和运行时 Javascript 代码。

    关于emscripten - 使用 Emscripten 编译的 WebAssembly 可以生成更小的文件大小吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49035417/

    相关文章:

    c++14 - 如何在 WebAssembly 中使用向量(C++ STL)

    c++ - 网页组装 |错误 : invalid argument '-std=c++11' not allowed with 'C/ObjC'

    emscripten - 错误 : unknown argument: '-nostdsysteminc' in Emscripten

    c++ - 使用模板模板参数时的默认模板参数

    c++ - 如何使用 Emscripten API 将 C++ 源代码转换为 js?

    javascript - Web Worker 使用 Web Assembly 时出错

    node.js - 在 node.js 中运行 .wasm 文件

    rust - 在浏览器中调试 WebAssembly 时如何查看 Rust 源代码?

    javascript - 将结构从 C 导出到 wasm?

    c++ - 使用 Emscripten (Emcmake) 时指定选项的问题