首页 > 解决方案 > Rust:测量 fs I/O 吞吐量给出了高得离谱的数字——如何正确测量真实的 I/O 速度?

问题描述

我有一台 Linux 机器,并在 Rust 中编写了一个小型磁盘速度测试,它从我的主目录(即主存储设备)中的文件读取/写入二进制数据。(在我的例子中是 NVMe-SSD)。我的 Rust 程序的吞吐速度快得离谱,我认为我的代码有问题。所以为了比较,$ dd if=/dev/zero of=$HOME/.disk-throughput-test oflag=direct bs=500M 给了我大约 2.2GB/s 的吞吐量。另一方面,我的实用程序返回

Writing of 1GB took 0.316157895s with 3162.98mb/s
Reading of 1GB took 0.159161669s with 6282.92mb/s

即使它是现代 NVMe SSD,因为卷是加密的(我猜所有数据都会即时加密),我非常怀疑 SSD 的写入吞吐量为 3.1GB/s。我更怀疑读取速度是 6.3GB/s。我猜想什么地方都被缓存了:但是在哪里以及为什么?

如何禁用所有 fs/IO 缓存以使用 Rust测量真实吞吐量?或者这里还有其他问题吗?

我的代码也可以在play.rust-lang.org上找到。我不得不稍微调整一下(与上面显示的输出行相比):它只写入 200MB 而不是 1GB,否则服务器会超时。

use std::fs::{OpenOptions, File};
use std::io::{Read, Seek, SeekFrom, Write};
use std::time::Instant;

fn main() {
    // 100MB with random data
    let mut buf: Vec<u8> = Vec::with_capacity(100_000_000);
    for _ in 0..buf.capacity() {
        buf.push(rand::random())
    }
    let mut buf = buf.into_boxed_slice();

    let mut file = open_file();

    // Measure write throughput
    let now = Instant::now();
    // write 2*100MB to file
    for _ in 0..2 {
        file.write_all(&mut buf).unwrap();
    }
    file.flush().unwrap();
    let write_duration = now.elapsed();

    // Measure read throughput
    file.seek(SeekFrom::Start(0)).unwrap();
    let now = Instant::now();
    // read 2*100MB MB from file
    for _ in 0..2 {
        file.read_exact(&mut buf).unwrap();
    }
    let read_duration = now.elapsed();
    println!(
        "Writing of 200MB took {}s with {:.2}mb/s",
        write_duration.as_secs_f64(),
        // 200MB totally written
        200.0 / write_duration.as_secs_f64(),
    );
    println!(
        "Reading of 200MB took {}s with {:.2}mb/s",
        read_duration.as_secs_f64(),
        200.0 / read_duration.as_secs_f64(),
    );
}

fn open_file() -> File {
    OpenOptions::new()
        .write(true)
        .read(true)
        .create(true)
        .open("./foobar.bin")
        .unwrap()
}

标签: rustio

解决方案


推荐阅读