FIOベンチマークはIO深度をどのように設定しますか?

FIOベンチマークはIO深度をどのように設定しますか?

メモ: 私の質問は別の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よりも理解/修正が簡単です。

関連情報