FIO 벤치마크는 IO 깊이를 어떻게 설정합니까?

FIO 벤치마크는 IO 깊이를 어떻게 설정합니까?

노트: 내 질문은 또 다른 U&L Q에서 비롯되었습니다.fio에서 ioDeepth는 정확히 무엇입니까?


내부는 어떤지 알고 싶어요페오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

이 예에서와 같이 "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 중 하나를 에뮬레이트하고 (비동기적으로) I/O를 제출하고 완료를 확인할 수 있는 이벤트 루프가 있어야 합니다. 아이디어가 있으면 특정 깊이에만 커밋하기가 쉽습니다. 언제든지 선택한 깊이와 일치하는 뛰어난 I/O가 있는 경우(또는 하나씩 확인하지 않으면 초과하는 경우) 대기가 필요합니다. 더 많은 콘텐츠를 제출하기 전에 무언가를 완료해야 합니다.

당신은 찾을 수 있습니다Linux 테스트 프로젝트의 aio-stress.c장난감 벤치마크를 만드는 경우 fio보다 이해/수정하기가 더 쉽습니다.

관련 정보