笔记: 我的问题源于另一个 U&L Q -fio中的iodepth到底是什么?
我想知道内部如何菲奥设置 I/O 深度。即,当我们运行FIO时,我们提交给FIO的参数之一是“IO深度”( --iodepth=
)。 FIO内部是如何通过底层操作系统来控制这个参数的呢?
以下是我们用来运行 FIO 基准测试的命令示例:
$ sudo fio --filename=/dev/nvme0n1 --direct=1 --rw=randwrite --refill_buffers \ --norandommap --randrepeat=0 --ioengine=libaio --bs=8K--io深度=72--numjobs=256 \ --time_based --runtime=600 --allow_mounted_write=1 --group_reporting --name=benchtest 基准测试:(g=0):rw=randwrite,bs=8K-8K/8K-8K/8K-8K,ioengine=libaio,io深度=72
如本例所示,“iodepth”的值可以更改。因此,fio 将此值传递给操作系统。那么FIO是如何做到这一点的呢?
如果你想解决一个实际问题:如果我想写一个像fio这样的基准程序,我该如何控制IO队列深度?
答案1
fio 正在将此值 [深度] 传递给操作系统
和
因此,fio 将此值传递给操作系统。那么FIO是如何做到这一点的呢?
这里可能存在误解:fio 并不直接将深度参数传递给操作系统。如果可能,fio 尝试iodepth
使用给定的 ioengine 提交指定的 I/O。如果达到深度然后fio 将等待(某些)未完成的 I/O 完成,然后再尝试提交更多 I/O...
FIO 基准测试如何设置 [io]深度?
取决于ioengine,取决于中提到的fio参数fio中的iodepth到底是什么?,https://serverfault.com/questions/923487/what-does-iodepth-in-fio-tests-really-mean-is-it-the-queue-depth和https://www.spinics.net/lists/fio/msg07191.html。如果没有小的固定例子,就有太多的东西需要解释。
到了某个时候,除了阅读和理解 fio 本身的代码之外,没有其他事可做... Fio 有用于提交 I/O 的主循环(请参阅https://github.com/axboe/fio/blob/fio-3.8/backend.c#L1055):
static void do_io(struct thread_data *td, uint64_t *bytes_done)
{
[...]
while ((td->o.read_iolog_file && !flist_empty(&td->io_log_list)) ||
(!flist_empty(&td->trim_list)) || !io_issue_bytes_exceeded(td) ||
td->o.time_based) {
[...]
} else {
ret = io_u_submit(td, io_u);
if (should_check_rate(td))
td->rate_next_io_time[ddir] = usec_for_io(td, ddir);
if (io_queue_event(td, io_u, &ret, ddir, &bytes_issued, 0, &comp_time))
break;
/*
* See if we need to complete some commands. Note that
* we can get BUSY even without IO queued, if the
* system is resource starved.
*/
reap:
full = queue_full(td) ||
(ret == FIO_Q_BUSY && td->cur_depth);
if (full || io_in_polling(td))
ret = wait_for_completions(td, &comp_time);
}
[...]
}
[...]
}
ioengine 的排队例程由来自 的调用链调用io_u_submit()
。假设 ioengine 是异步的,它可能会选择只在 fio 中“排队”I/O,然后在稍后一次性提交整个 I/O(通常是getevents()
从调用链调用其函数的结果wait_for_completions()
)。不过,我们将通过 fio 的代码进行跟踪作为读者的练习。
如果我想写一个像fio这样的基准程序,我该如何控制IO队列深度?
您需要模仿 fio 的(异步)ioengine 之一,并拥有一个能够(异步)提交 I/O 并检查其完成情况的事件循环。一旦你有了这样的想法,你只提交特定深度的想法就会很容易 - 如果在任何时候你都有未完成的 I/O 匹配(或者超过,如果你不逐一检查)所选深度那么您需要等待某些内容完成才能提交更多内容。
你可能会发现Linux 测试项目中的 aio-stress.c如果您正在制作玩具基准测试,则比 fio 更容易理解/修改。