Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何度量函数堆栈在Rust中的使用情况?_Rust_Stack Memory - Fatal编程技术网

如何度量函数堆栈在Rust中的使用情况?

如何度量函数堆栈在Rust中的使用情况?,rust,stack-memory,Rust,Stack Memory,有没有一种方法可以测量函数使用了多少堆栈内存 这个问题不是递归函数特有的;然而,我很想知道递归调用函数需要多少堆栈内存 我对优化堆栈内存使用的函数感兴趣;然而,在不知道编译器已经进行了哪些优化的情况下,这只是猜测是否有真正的改进 要清楚,这不是一个关于如何优化以更好地使用堆栈的问题。 那么,有没有可靠的方法来确定函数在Rust中使用了多少堆栈内存呢 请注意,其他编译器也支持这一点,例如GCC有-fstack用法。作为最后手段,您可以观察堆栈指针(使用内联汇编)并从中推断结果。这种方法绝对不是你

有没有一种方法可以测量函数使用了多少堆栈内存

这个问题不是递归函数特有的;然而,我很想知道递归调用函数需要多少堆栈内存

我对优化堆栈内存使用的函数感兴趣;然而,在不知道编译器已经进行了哪些优化的情况下,这只是猜测是否有真正的改进

要清楚,这不是一个关于如何优化以更好地使用堆栈的问题。

那么,有没有可靠的方法来确定函数在Rust中使用了多少堆栈内存呢



请注意,其他编译器也支持这一点,例如GCC有
-fstack用法。

作为最后手段,您可以观察堆栈指针(使用内联汇编)并从中推断结果。这种方法绝对不是你在生产中使用的。。。但它是有效的

#![feature(asm)]

use std::cell::Cell;
use std::cmp;
use std::usize;

// This global variable tracks the highest point of the stack
thread_local!(static STACK_END: Cell<usize> = Cell::new(usize::MAX));

macro_rules! stack_ptr {
    () => ({
        // Grab a copy of the stack pointer
        let x: usize;
        unsafe {
            asm!("mov %rsp, $0" : "=r"(x) ::: "volatile");
        }
        x
    })
}

/// Saves the current position of the stack. Any function
/// being profiled must call this macro.
macro_rules! tick {
    () => ({
        // Save the current stack pointer in STACK_END
        let stack_end = stack_ptr!();
        STACK_END.with(|c| {
            // Since the stack grows down, the "tallest"
            // stack must have the least pointer value
            let best = cmp::min(c.get(), stack_end);
            c.set(best);
        });
    })
}

/// Runs the given callback, and returns its maximum stack usage
/// as reported by the `tick!()` macro.
fn measure<T, F: FnOnce() -> T>(callback: F) -> (T, usize) {
    STACK_END.with(|c| c.set(usize::MAX));
    let stack_start = stack_ptr!();
    let r = callback();
    let stack_end = STACK_END.with(|c| c.get());
    if stack_start < stack_end {
        panic!("tick!() was never called");
    }
    (r, stack_start - stack_end)
}

/// Example recursive function
fn fibonacci(n: i64) -> i64 {
    tick!();
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci(n-1) + fibonacci(n-2)
    }
}

fn main() {
    // Stack usage should grow linearly with `i`
    for i in 0 .. 10 {
        let (result, stack) = measure(|| fibonacci(i));
        println!("fibonacci({}) = {}: used {} bytes of stack", i, result, stack);
    }
}
#![功能(asm)]
使用std::cell::cell;
使用std::cmp;
使用std::usize;
//此全局变量跟踪堆栈的最高点
本地线程!(静态堆栈_END:Cell=Cell::new(usize::MAX));
宏规则!堆栈ptr{
() => ({
//获取堆栈指针的副本
让x:usize;
不安全{
asm!(“mov%rsp,$0:”=r(x):“volatile”);
}
x
})
}
///保存堆栈的当前位置。任何功能
///正在分析的必须调用此宏。
宏规则!滴答声{
() => ({
//将当前堆栈指针保存在stack_END中
让stack_end=stack_ptr!();
带(| c|)的堆栈|U端{
//由于烟囱向下生长,“最高的”
//堆栈必须具有最小的指针值
让best=cmp::min(c.get(),stack_end);
c、 设置(最佳);
});
})
}
///运行给定的回调,并返回其最大堆栈使用率
///正如《滴答声》报道的那样!()”宏。
fn度量值T>(回调:F)->(T,usize){
使用(| c | c.set(usize::MAX));
让stack_start=stack_ptr!();
设r=callback();
让stack_end=stack_end.with(| c | c.get());
如果堆栈开始<堆栈结束{
惊慌失措!(“滴答声!()从未被叫来”);
}
(r,堆栈开始-堆栈结束)
}
///递归函数示例
fn斐波那契(n:i64)->i64{
滴答!();
匹配{
0 => 0,
1 => 1,
_=>斐波那契(n-1)+斐波那契(n-2)
}
}
fn main(){
//堆栈使用率应随'i'线性增长`
因为我在0..10{
let(result,stack)=度量(| | fibonacci(i));
println!(“fibonacci({})={}:使用了堆栈的{}字节”,i,result,stack);
}
}
相关: