我正在调查WebAssembly项目中的速度慢,我想知道SIMD指令是否以某种方式被模拟。这里有一个玩具Rust库来练习一些SIMD操作:
use core::arch::wasm32::*;
#[no_mangle]
pub fn do_something(f: f32) -> f32 {
let f4 = f32x4_splat(f);
let mut a = f4;
for _ in 0..100000 {
a = f32x4_add(a, f4);
}
f32x4_extract_lane::<0>(a)
+ f32x4_extract_lane::<1>(a)
+ f32x4_extract_lane::<2>(a)
+ f32x4_extract_lane::<3>(a)
}
字符串
然后我用cargo build --release --target wasm32-unknown-unknown
构建它。
最后,我运行它:
const response = await fetch(WASM_FILE);
const wasmBuffer = await response.arrayBuffer();
const wasmObj = await WebAssembly.instantiate(wasmBuffer, {env:{}});
function do_something() {
wasmObj.instance.exports.do_something(0.00001);
requestAnimationFrame(do_something);
}
requestAnimationFrame(do_something);
型
我怀疑SIMD操作正在被模拟,因为我看到这是Chrome性能调用树:
的数据
如果SIMD操作被降低到一条指令(正如我所期望的那样),我就不会期望在概要跟踪中看到任何带有f32x4_add
的内容。
1条答案
按热度按时间2izufjch1#
这是一个众所周知的陷阱,如果你没有为SIMD函数启用适当的
target_feature
,它们就不会内联,从而导致很大的开销。解决方案是打开
simd128
目标功能。您可以通过设置RUSTFLAGS
(例如,在.cargo/config.toml
中)来实现,并将参数-C target-feature=+simd128
传递给rustc。