メモ: 私の質問は別のU&L Qから来ました。fioのioDeepthは正確に何ですか?
内部はどうか知りたいです。ペオI/O 深さを設定します。つまり、FIOを実行したときにFIOに送信するパラメータの1つが「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
この例のように、「iolength」の値は変更される可能性があります。したがって、fioはこの値をオペレーティングシステムに渡します。それでは、FIOはこれをどのように実行しますか?
実用的な問題を解決したい場合:fioなどのベンチマークプログラムを作成したい場合は、IOキューの深さをどのように制御できますか?
答え1
fioはこの値[深さ]をオペレーティングシステムに渡します。
そして
したがって、fioはこの値をオペレーティングシステムに渡します。それでは、FIOはこれをどのように実行しますか?
これには誤解がある可能性があります。 fioは深さパラメータをオペレーティングシステムに直接渡しません。可能であれば、fioはiodepth
与えられたioengineを使用して指定されたI / Oを送信しようとします。もし深さに達するそれからfioは、追加のI / Oを送信する前に(一部)未解決のI / Oが完了するのを待ちます。
FIOベンチマークの[io]深度を設定するには?
ioengineに依存し、記載されているfioパラメータによって異なります。fioのioDeepthは正確に何ですか?、https://serverfault.com/questions/923487/what-does-iolength-in-fio-tests-really-mean-is-it-the-queue-lengthそして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の1つをエミュレートし、(非同期的に)I / Oを送信して完了を確認できるイベントループが必要です。アイデアがあれば、特定の深さにのみコミットするのは簡単です。いつでも選択した深さに一致する優れたI / Oがある場合(または1つずつ確認しない場合は超過した場合)、待機が必要です。より多くのコンテンツを送信する前に、何かを完了する必要があります。
あなたは見つけることができますLinuxテストプロジェクトのaio-stress.cおもちゃのベンチマークを作成する場合は、fioよりも理解/修正が簡単です。