货物测试 --释放导致堆栈溢出。为什么货物板凳不?



在尝试编写优化的 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]; });
}
}

为了正确看待问题,请注意数组的大小为 8 × 2 × 512 × 512 = 4 MiB。

cargo test崩溃,但cargo bench不会,因为"测试"在新线程中it_works()调用函数,而"bench">在主线程中调用它。

主线程的默认堆栈大小通常为 8 MiB,因此该数组将占用可用堆栈的一半。这很多,但仍有可用空间,因此基准测试正常运行。

但是,新线程的堆栈大小通常要小得多。在Linux上,它是2 MiB,其他平台可能更小。因此,您的 4 MiB 阵列很容易溢出线程的堆栈并导致堆栈溢出/段错误。

您可以通过设置RUST_MIN_STACK环境变量来增加新线程的默认堆栈大小。

$ RUST_MIN_STACK=8388608 cargo test 

cargo test在并行线程中运行测试以缩短总测试时间,而基准测试在同一线程中按顺序运行以减少噪音。

由于堆栈大小有限,因此在堆栈上分配此数组是一个坏主意。您必须将其存储在堆上(box它)或作为全局static mut

相关内容

  • 没有找到相关文章

最新更新