llo*_*giq 18 memory benchmarking rust
我注意到Rust的测试有一个测量执行时间的基准模式ns/iter,但我找不到测量内存使用情况的方法.
我该如何实施这样的基准?让我们假设目前我只关心堆内存(虽然堆栈使用也肯定会很有趣).
编辑:我发现这个问题要求完全相同的事情.
Art*_*mGr 11
使用Rust 1.0和1.1,您可以使用libc crate来打印jemalloc统计信息:
#![feature(libc)]
extern crate libc;
use libc::*;
extern {fn je_malloc_stats_print (write_cb: extern fn (*const c_void, *const c_char), cbopaque: *const c_void, opts: *const c_char);}
extern fn write_cb (_: *const c_void, message: *const c_char) {
print! ("{}", String::from_utf8_lossy (unsafe {std::ffi::CStr::from_ptr (message as *const i8) .to_bytes()}));
}
fn main() {
unsafe {je_malloc_stats_print (write_cb, std::ptr::null(), std::ptr::null())};
}
Run Code Online (Sandbox Code Playgroud)
在后来的Rust版本(1.8 - 1.14)中,我们将其je_malloc_stats_print重命名为je_stats_print:
#![feature(libc)]
extern crate libc;
extern {fn je_stats_print (write_cb: extern fn (*const libc::c_void, *const libc::c_char), cbopaque: *const libc::c_void, opts: *const libc::c_char);}
extern fn write_cb (_: *const libc::c_void, message: *const libc::c_char) {
print! ("{}", String::from_utf8_lossy (unsafe {std::ffi::CStr::from_ptr (message as *const i8) .to_bytes()}));}
fn main() {unsafe {je_stats_print (write_cb, std::ptr::null(), std::ptr::null())};}
Run Code Online (Sandbox Code Playgroud)
(游乐场)
在单线程程序中,应该可以让您很好地测量结构占用的内存量.只需在创建结构之前打印统计数据,然后计算差异.
您还可以使用Valgrind(Massif)来获取堆配置文件.它的工作方式与任何其他C程序一样.确保在可执行文件中启用了调试符号(例如,使用调试版本或自定义Cargo配置).例如,您可以使用http://massiftool.sourceforge.net/来分析生成的堆配置文件.
(我在Debian Jessie上验证了这一点,在不同的设置中你的里程可能会有所不同).
为了在Valgrind中使用Rust,您可能必须切换到系统分配器:
#![feature(alloc_system)]
extern crate alloc_system;
Run Code Online (Sandbox Code Playgroud)
可以告诉 jemalloc 转储内存配置文件.您可以使用Rust FFI执行此操作,但我没有调查此路线.
就测量数据结构大小而言,这可以通过使用特征和小编译器插件相当容易地完成.Nicholas Nethercote在他的文章中测量数据结构大小:Firefox(C++)与Servo(Rust)演示了它在Servo中的工作原理; 它归结为#[derive(HeapSizeOf)]为你关心的每种类型添加(或偶尔手动实现).这是一种允许精确检查内存去向的好方法; 然而,它是相对侵入性的,因为它首先需要做出改变,而像jemalloc这样的东西print_stats()却没有.尽管如此,对于良好和精确的测量,这是一种合理的方法.
目前,获取分配信息的唯一方法是 调用jemalloc的alloc::heap::stats_print();方法(后面#![feature(alloc)])print_stats().
一旦我了解了输出的含义,我将用更多信息更新这个答案.
(请注意,我不会接受这个答案,所以如果有人想出更好的解决方案......)
现在有jemalloc_ctlcrate 提供方便、安全的类型化 API。将其添加到您的Cargo.toml:
[dependencies]
jemalloc-ctl = "0.3"
jemallocator = "0.3"
Run Code Online (Sandbox Code Playgroud)
然后配置jemalloc为全局分配器并使用jemalloc_ctl::stats模块中的方法:
这是官方示例:
use std::thread;
use std::time::Duration;
use jemalloc_ctl::{stats, epoch};
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
fn main() {
loop {
// many statistics are cached and only updated when the epoch is advanced.
epoch::advance().unwrap();
let allocated = stats::allocated::read().unwrap();
let resident = stats::resident::read().unwrap();
println!("{} bytes allocated/{} bytes resident", allocated, resident);
thread::sleep(Duration::from_secs(10));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4031 次 |
| 最近记录: |