ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

用 WAMR 运行带 SIMD 支持的 meshoptimizer codecbench:从 WASI-SDK/EMSDK 编译到 AOT 全流程实战

用 WAMR 运行带 SIMD 支持的 meshoptimizer codecbench:从 WASI-SDK/EMSDK 编译到 AOT 全流程实战 用 WAMR 运行带 SIMD 支持的 meshoptimizer codecbench从 WASI-SDK/EMSDK 编译到 AOT 全流程实战【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit本指南以 WAMRWebAssembly Micro Runtime仓库内的samples/workload/meshoptimizer示例为线索完整讲解如何把 meshoptimizer 的 codecbench 基准程序编译成启用 WebAssembly SIMD 指令的 wasm 模块再通过wamrc转成 AOT 文件并用iwasm运行。读完本文你将掌握 WASI-SDK 与 EMSDK 两条编译路径、SIMD 编译选项的作用、AOT 转换与运行命令以及仓库内codecbench.patch与 CMake 脚本背后的实现细节。示例背景meshoptimizer 与 codecbench 在 WAMR 中的定位meshoptimizer 是一个面向网格mesh优化的 C/C 库其顶点编解码、索引编解码等算法高度依赖字节级 shuffle 与打包解包操作非常适合用来检验 WebAssembly SIMD 扩展simd128在解释器 / AOT 执行引擎上的实际收益。WAMR 在lib/wasm-micro-runtime-WAMR-2.4.1/samples/workload/meshoptimizer/目录下提供了一个名为codecbench of meshoptimizer的示例其目标非常明确将 meshoptimizer 的 codecbench 基准程序构建为带 SIMD 支持的 WebAssembly 模块并在 iwasm 中运行。codecbench 是 meshoptimizer 自带的编解码基准工具主要衡量顶点数据vertexcodec与索引数据indexcodec的压缩 / 解压吞吐。把它作为 WAMR 的 workload可以同时验证上游代码能否顺利通过 WASI-SDK 或 EMSDK 交叉编译成 wasmwasm 模块中的simd128指令能否被 WAMR 正确解析与执行AOTAhead-Of-Time模式下 SIMD 指令的本地代码生成质量。环境准备安装构建依赖官方说明要求先完成通用依赖安装详细步骤见 workload 顶层安装说明。该文档指出所有 workload 都依赖emsdk与binaryen并以 Ubuntu 20.04 为示例环境。有两种方式准备环境方式一一键脚本preparation.sh仓库提供了 preparation.sh它会依次安装软件版本脚本内锁定用途wabt1.0.31WebAssembly 二进制工具集wat2wasm 等cmake3.25.1构建系统emsdk3.1.28Emscripten 工具链用于 EMSDK 编译路径binaryenversion_111提供wasm-opt用于 wasm 二次优化bazel6.0.0部分 workload如 tensorflow需要直接执行$ cd lib/wasm-micro-runtime-WAMR-2.4.1/samples/workload $ ./preparation.sh方式二手动安装 emsdk 与 binaryen按照 workload 顶层安装说明 手动安装 emsdk并激活后确认环境变量EMSDK已生效$ cd /opt $ git clone https://github.com/emscripten-core/emsdk.git $ cd emsdk $ git pull $ ./emsdk install 3.0.0 $ ./emsdk activate 3.0.0 $ echo source /opt/emsdk/emsdk_env.sh ${HOME}/.bashrc再安装 binaryen 到/opt/binaryen$ wget https://github.com/WebAssembly/binaryen/releases/download/${BINARYEN_VER}/${BINARYEN_FILE} $ tar zxf ${BINARYEN_FILE} -C /opt $ ln -sf /opt/binaryen-${BINARYEN_VER} /opt/binaryen说明preparation.sh与顶层安装文档锁定的 emsdk 版本略有差异3.1.28 vs 3.0.0以你实际选用的路径为准两种版本均可完成本示例的构建。路径一使用 WASI-SDK 构建 codecbench.wasm关联文档给出的 WASI-SDK 构建命令如下$ mkdir build cd build $ cmake .. $ make # 验证产物 $ ls codecbench.wasm其中cmake ..会解析本示例目录下的 CMakeLists.txt其内部机制值得展开说明CMake 脚本做了什么定位 WASI-SDKfind_package(WASISDK 16.0 REQUIRED)通过 FindWASISDK.cmake 在/opt/wasi-sdk-*目录下查找share/wasi-sysroot进而导出WASISDK_HOME安装位置WASISDK_SYSROOTshare/wasi-sysrootWASISDK_TOOLCHAINshare/cmake/wasi-sdk.cmake因此使用该路径前请确保 WASI-SDK 16.0 已安装到/opt/wasi-sdk-16.0之类的标准位置。拉取 meshoptimizer 源码并打补丁ExternalProject_Add(codecbench ...)会从 meshoptimizer 上游仓库克隆代码固定到 commitf734fd572aed5bf76e84d9ed62ca6f4f6c47d84e执行git clean -fd git checkout -- *保证源码干净应用本目录下的 codecbench.patch。交叉编译CONFIGURE_COMMAND显式传入WASI_SDK_PREFIX、CMAKE_TOOLCHAIN_FILE即 wasi-sdk 的 toolchain 文件与CMAKE_SYSROOT随后BUILD_COMMAND make codecbench -j 4并行构建最终把生成的codecbench.wasm拷贝到当前构建目录。codecbench.patch 做了什么补丁是让 meshoptimizer 能顺利产出 wasm 的关键主要包含三部分新增codecbench可执行目标在 meshoptimizer 的 CMakeLists 末尾追加add_executable(codecbench tools/codecbench.cpp ${SOURCES})并把输出名设为codecbench.wasm。注入编译与链接选项target_compile_options(codecbench PUBLIC -O3 -msimd128 -stdc11 ...) target_link_options(codecbench PUBLIC LINKER:-allow-undefined,--demangle,--exportmalloc,--exportfree)-msimd128正是开启 WebAssembly SIMD 指令生成的开关-O3保证充分优化链接阶段导出malloc/free便于运行时内存管理。追加wasm-opt二次优化目标通过find_program(WASM_OPT ...)在/opt/binaryen-version_97/bin与/opt/binaryen/bin查找wasm-opt存在则生成codecbench.opt.wasm${WASM_OPT} -Oz --enable-simd -o codecbench.opt.wasm codecbench.wasm若找不到wasm-opt只会告警不影响主产物codecbench.wasm的生成。补丁中的 SIMD intrinsic 修正codecbench.patch的另一半内容是把 meshoptimizer 源码中的旧版 SIMD intrinsic 名迁移到新的命名规范例如-#define wasmx_unpacklo_v8x16(a, b) wasm_v8x16_shuffle(a, b, 0, 16, ...) #define wasmx_unpacklo_v8x16(a, b) wasm_i8x16_shuffle(a, b, 0, 16, ...)涉及src/vertexcodec.cpp与src/vertexfilter.cpp把wasm_v8x16_shuffle、wasm_v16x8_shuffle、wasm_v32x4_shuffle、wasm_v64x2_shuffle、wasm_v8x16_swizzle等替换为对应的wasm_i8x16_*、wasm_i16x8_*、wasm_i32x4_*、wasm_i64x2_*系列。这说明示例在移植到较新工具链 / 较新 WAMR 时同步适配了 WebAssembly SIMD 提案中 intrinsic 命名规范的变化。路径二使用 EMSDK 构建性能更优的备选关联文档指出 EMSDK 是另一条编译 C/C 到 wasm 的工具链且其产出的 wasm 文件可能比 wasi-sdk 生成的文件具有更高性能。手动编译命令如下$ git clone https://github.com/zeux/meshoptimizer.git $ cd messoptimizer $ em tools/codecbench.cpp src/vertexcodec.cpp src/vertexfilter.cpp \ src/overdrawanalyzer.cpp src/indexgenerator.cpp src/vcacheoptimizer.cpp \ src/clusterizer.cpp src/indexcodec.cpp src/vfetchanalyzer.cpp \ src/spatialorder.cpp src/allocator.cpp src/vcacheanalyzer.cpp \ src/vfetchoptimizer.cpp src/overdrawoptimizer.cpp src/simplifier.cpp \ src/stripifier.cpp -O3 -msimd128 \ -s TOTAL_MEMORY268435456 \ -o codecbench.wasm $ ls -l codecbench.wasm对这条命令的要点说明源文件清单tools/codecbench.cpp是基准主程序其余src/*.cpp是 meshoptimizer 的核心实现顶点编解码vertexcodec.cpp、索引编解码indexcodec.cpp、顶点/索引优化器、简化器simplifier.cpp、条带化器stripifier.cpp等与 WASI-SDK 路径下add_executable(codecbench tools/codecbench.cpp ${SOURCES})的编译范围一致。-O3 -msimd128-msimd128开启 WebAssembly SIMD 指令生成是本次运行 SIMD 负载的前提-O3提供激进优化。-s TOTAL_MEMORY268435456把 Emscripten 生成的 wasm 线性内存上限设为 256 MiB268435456字节。codecbench 需要申请较大缓冲用于网格数据编解码默认内存可能不足这个参数务必保留。-o codecbench.wasm输出裸 wasm 文件不带 JS glue正好匹配 iwasm / wamrc 的输入需求。手动编译后同样可用wasm-opt -Oz --enable-simd做体积与性能优化对应补丁中的codecbench.opt目标。运行工作负载构建 iwasm 并用 AOT 方式执行第一步构建支持 SIMD 的 iwasm按关联文档进入 product-mini 的 Linux 平台目录构建$ cd wamr dir/product-mini/platforms/linux/ $ mkdir build cd build $ cmake .. $ make需要说明的是iwasm 的 SIMD 支持默认就是开启的。查看 product-mini/platforms/linux/CMakeLists.txtif (NOT DEFINED WAMR_BUILD_SIMD) # Enable SIMD by default set (WAMR_BUILD_SIMD 1) endif ()并且在 64 位 X86_64 / AARCH64 平台上只要未显式覆盖WAMR_BUILD_SIMD也会被置为 1见该文件 第 25-46 行。同理WAMR_BUILD_AOT默认也为 1第 57-60 行这正是 AOT 运行路径可用的前提。提示若需要在解释器 / AOT 之外显式控制特性可在cmake ..时通过-DWAMR_BUILD_SIMD1 -DWAMR_BUILD_AOT1指定若平台不支持 SIMD则应显式设为 0 以免运行出错。第二步用 wamrc 把 wasm 编译为 AOT 文件$ wamr dir/wamr-compiler/build/wamrc -o codecbench.aot codecbench.wasmwamrc是 WAMR 的 AOT 编译器它读取 wasm 字节码并生成面向本机平台的 AOT 二进制。若尚未构建wamrc可参考 workload 顶层 CMakeLists 中的ExternalProject_Add(wamrc ...)它会在wamr-compiler目录下执行cmakemake产出wamrc。第三步运行$ wamr dir/product-mini/platforms/linux/build/iwasm codecbench.aot运行后会输出 codecbench 各子基准顶点编解码、索引编解码等的性能结果。自动化路径workload 顶层 CMake 的一键构建与冒烟测试除了手动分步执行workload 顶层 CMakeLists.txt 把整个流程串了起来通过ExternalProject自动构建iwasm-DWAMR_BUILD_LIBC_EMCC1与wamrc定义codecbench_to_aot目标在codecbench与wamrc构建完成后自动执行./wamrc -o codecbench.aot ./meshoptimizer/codecbench.wasm注册冒烟测试run_codecbench对应ctestadd_test(NAME run_codecbench COMMAND ./iwasm codecbench.aot ...)这意味着在samples/workload目录下执行一次cmake .. make即可自动完成「拉取 meshoptimizer → 打补丁 → 交叉编译 wasm → wamrc 转 AOT → iwasm 冒烟运行」的完整流水线适合作为 CI 或回归测试的基准。常见问题与注意事项WASI-SDK 路径FindWASISDK.cmake只在/opt/wasi-sdk-*下查找请把 WASI-SDK 16.0 安装到该前缀下或自行调整查找路径。SIMD 默认开启X86_64 / AARCH64 64 位平台下 iwasm 默认启用 SIMD无需额外配置若更换为不支持 SIMD 的目标平台请显式关闭WAMR_BUILD_SIMD。EMSDK 与 WASI-SDK 产物差异关联文档明确指出 EMSDK 产出的 wasm「可能具有更高性能」这是工具链实现差异所致可把两条路径的产物分别跑一遍 codecbench 对比。内存上限EMSDK 路径必须设置-s TOTAL_MEMORY268435456256 MiB否则 codecbench 可能因线性内存不足而运行失败。wasm-opt 可选找不到wasm-opt只影响codecbench.opt.wasm二次优化产物不影响codecbench.wasm主产物。补丁随上游演进codecbench.patch固定的上游 commit 为f734fd572aed5bf76e84d9ed62ca6f4f6c47d84e若自行更换 meshoptimizer 版本需重新评估 SIMD intrinsic 命名是否仍匹配。通过本示例你可以把任意依赖simd128指令的 C/C 负载移植到 WAMR先选定 WASI-SDK 或 EMSDK 工具链编译出 wasm再用wamrc生成 AOT 文件最后交给iwasm运行——整个过程均可复用本文涉及的脚本、CMake 与冒烟测试模式。【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表