货物测试-释放会导致堆栈溢出.为什么没有货台? [英] cargo test --release causes a stack overflow. Why doesn't cargo bench?

查看:56
本文介绍了货物测试-释放会导致堆栈溢出.为什么没有货台?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试编写优化的DSP算法时,我想知道堆栈分配和堆分配之间的相对速度以及堆栈分配的数组的大小限制.我意识到存在堆栈帧大小限制,但是我不明白为什么要运行以下内容,并使用cargo bench生成看似真实的基准测试结果,但是使用cargo test --release运行时会出现堆栈溢出的情况.

In trying to write an optimized DSP algorithm, I was wondering about relative speed between stack allocation and heap allocation, and size limits of stack-allocated arrays. I realize there is a stack frame size limit, but I don't understand why the following runs, generating seemingly realistic benchmark results with cargo bench, but fails with a stack overflow when run with 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.

To get things into perspective, note that the size of your array is 8 × 2 × 512 × 512 = 4 MiB in size.

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

cargo test crashes but cargo bench doesn't because a "test" calls the function it_works() in a new thread, while "bench" calls it in the main thread.

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

The default stack size of the main thread is typically 8 MiB, so that array is going to occupy half of the available stack. That's a lot, but there's still room available, so the benchmark runs normally.

新线程的堆栈大小通常很大较小.在Linux上,它是2 MiB,,其他平台则可能更小.因此,您的4 MiB阵列很容易溢出线程的堆栈,并导致堆栈溢出/segfault.

The stack size of a new thread, however, is typically much smaller. On Linux it is 2 MiB, and other platforms could be even smaller. So, your 4 MiB array easily overflows the thread's stack and causes a stack overflow / segfault.

您可以将新线程的默认堆栈大小增加

You can increase the default stack size of new threads by setting the RUST_MIN_STACK environment variable.

$ RUST_MIN_STACK=8388608 cargo test 

cargo test在并行线程中运行测试以缩短总测试时间,而基准测试则在同一线程中依次运行以减少噪音.

cargo test runs the tests in parallel threads to improve total test time while benchmarks are run sequentially in the same thread to reduce noise.

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

Due to the limited stack size, it is a bad idea to allocate this array on stack. You have to either store it on the heap (box it) or as a global static mut.

这篇关于货物测试-释放会导致堆栈溢出.为什么没有货台?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆