[英]cargo test --release causes a stack overflow. Why doesn't cargo bench?
在尝试编写优化的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 test
cargo bench
没有崩溃,因为“测试” 在新线程中调用了函数it_works()
,而“长凳” 在主线程中调用了该函数。
主线程的默认堆栈大小通常为8 MiB,因此该阵列将占据可用堆栈的一半。 足够多了,但仍有可用空间,因此基准测试正常运行。
但是, 新线程的堆栈大小通常要小得多。 在Linux上是2 MiB, 其他平台可能更小 。 因此,您的4 MiB阵列很容易溢出线程的堆栈,并导致堆栈溢出/ segfault。
您可以通过设置RUST_MIN_STACK
环境变量来增加新线程的默认堆栈大小。
$ RUST_MIN_STACK=8388608 cargo test
cargo test
测试在并行线程中运行测试以缩短总测试时间,而基准测试则在同一线程中依次运行以减少噪音。
由于堆栈大小有限,在堆栈上分配此数组是一个坏主意。 您必须将其存储在堆上( box
)或作为全局static mut
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.