Jos*_*osh 9 testing benchmarking stack rust rust-cargo
在尝试编写优化的DSP算法时,我想知道堆栈分配和堆分配之间的相对速度,以及堆栈分配的数组的大小限制.我意识到堆栈帧大小限制,但我不明白为什么以下运行,生成看似真实的基准测试结果cargo bench,但运行时出现堆栈溢出失败cargo test --release.
#![feature(test)]
extern crate test;
#[cfg(test)]
mod tests {
use test::Bencher;
#[bench]
fn it_works(b: &mut Bencher) {
b.iter(|| { let stack = [[[0.0; 2]; 512]; 512]; });
}
}
Run Code Online (Sandbox Code Playgroud)
ken*_*ytm 16
为了更好地理解,请注意阵列的大小为8×2×512×512 = 4 MiB.
cargo test崩溃,但cargo bench不是因为"test" it_works() 在新线程中调用该函数,而"bench" 在主线程中调用它.
主线程的默认堆栈大小通常为8 MiB,因此该阵列将占用可用堆栈的一半.这是很多,但仍然有空间,所以基准测试正常运行.
但是,新线程的堆栈大小通常要小得多.在Linux上它是2 MiB,其他平台可能更小.因此,您的4 MiB阵列很容易溢出线程的堆栈并导致堆栈溢出/段错误.
您可以通过设置RUST_MIN_STACK环境变量来增加新线程的默认堆栈大小.
$ RUST_MIN_STACK=8388608 cargo test
Run Code Online (Sandbox Code Playgroud)
cargo test 以并行线程运行测试以改善总测试时间,同时在同一线程中按顺序运行基准测试以降低噪声.
由于堆栈大小有限,在堆栈上分配此数组是个坏主意.您必须将其存储在堆(boxit)上或作为全局存储static mut.