Io

nvme 隊列深度與 fio iodepth arg 關係/解釋

  • November 17, 2019

這個問題與fiolibaio (靈活的 i/o 測試器)實用程序在使用引擎時管理 NVME 儲存(特別是 SSD)的 I/O 隊列有關。

對於測試,我使用的是Ubuntu 14.04 和商業 nvme SSD

我使用以下參數強制執行 fio 實驗:

direct=1
numjobs=256
iodepth=1
ioengine=libaio
group_reporting

對於此範例,假設 nvme 設備通告/支持10 個 IO 隊列創建,最大隊列深度為 64。您可以假設 10 個隊列創建成功作為初始化的一部分。

基於上述參數和約束, "How would fio use the queues, for I/O commands?"或者縮小範圍,"Does the iodepth argument in fio directly equate to nvme_queue_depth for the test"這就是問題所在。

我希望下面的內容會在幕後進行,但沒有正確的資訊。

範例場景 1:

fio 是否生成 256 個作業/執行緒,它們嘗試將 i/o 送出給 nvme_queues,並嘗試在任何時候在 10 個 nvme_queues 中保持至少 1 個 i/o cmd。如果作業看到隊列已滿(即,如果(一個)i/o cmd 存在於 nvme_queue 中,則嘗試在其他 9 個 nvme_queue 或循環中送出,直到它可以找到一個空隊列)

範例場景 2:

fio 是否有 256 個執行緒/作業,並沒有真正尊重用於此測試的 iodepth==nvme_quedepth 並送出多個 i/o。因此,例如,每個執行緒只向 nvme_queues 送出 1 個 i/o cmd,而不對 10 個 nvme_queues 中的命令深度進行任何檢查。換句話說,256 個執行緒嘗試在 10 個 nvme_queues 中維護大約 25 或 26 個 i/o 掛起/進行中。

連結到來自 fio 文件的iodepth定義。

兩種情況都是真的嗎?有沒有辦法通過實驗來確定這一點。

通過 nvme 和 fio 的規範並沒有真正清楚地說明這種情況是如何處理的或者是模糊的。

更新:以下是圖像格式 https://imgur.com/OCZtwgM(無法嵌入)的兩個場景,頂部是場景 1,底部是 scn。2

更新2:對不起,如果問題含糊不清,但我會嘗試通過進一步擴展來改進它。

我對設備和fio之間的理解。因此,這個問題跨越了許多層的程式碼和/或協議,它們在這裡起作用。列出它們

  1. Fio(應用程序)和 libaio

  2. Linux Kernel/OS

  3. Nvme 驅動程序

  4. 儲存設備 SSD 控制器和程式碼。

上面解釋的兩種情況是模糊的試圖在非常高的層次上解釋來回答我自己的問題,因為到目前為止我不是上述各層的專家。

根據下面的答案,這似乎scenario 1是鬆散的相關。並且想通過所有層了解更多關於一般政策和可預測性的資訊。部分解釋可以,希望結合成一個完整的解釋。

所以這個問題的第三個天真的改寫是 "how does fio issue traffic and how they really end up the storage nvme_queues?"

TLDR;Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems論文中描述了當 I/O 離開核心時送出使用者空間 I/O 的設計。

"How would fio use the queues, for I/O commands?"或縮小範圍"Does the iodepth argument in fio directly equate to nvme_queue_depth for the test"

這種想法有點過於草率,我會警告不要這樣做。“fio 如何將隊列用於 I/O 命令?” - 不只是fio。“fio 中的 iodepth 參數是否直接等同於測試的 nvme_queue_depth” - 也許但可能不是?在您的範例中,fio 將 I/O 送出給核心,但核心反過來可能會選擇在將 I/O 送出到磁碟之前對其進行轉換(請參閱“fio 測試中的 iodepth 到底是什麼意思?它是隊列深度嗎? ?”)。

場景 1:fio 是否生成 256 個作業/執行緒,這些作業/執行緒嘗試將 i/o 送出到 nvme_queues 並嘗試保持至少

$$ sic $$10 個 nvme_queues 中的 1 個 i/o cmd 在任何時候

排序(但 s/jobs/processes/)。每個作業(如果您的範例完整,可能會映射到一個程序)最多向核心送出一個 I/O。但是請記住,fio 對您的磁碟可以做什麼的了解為零,並且在調度其 I/O 和每個單獨的 fio 程序方面,您的核心選擇做的任何事情都受其支配。

範例場景 2

恐怕我不明白,因為你沒有舉一個單獨的例子。在這種情況下, “ iodepth”是指fio的iodepth參數嗎?

兩種情況都是真的嗎?

我不明白你的場景 2 和場景 1 會有很多成本,我們不知道核心會對 I/O 做什麼,所以我認為這不能明確回答(例如,我是有點懷疑您的 NVMe 磁碟與 SCSI 設備節點一起出現…)。

我建議查看iostatfio 作業執行時所說的內容以了解一些想法,但是每個作業執行一個 I/O 是送出 I/O 的一種非常低效的方式,並且會產生大量成本(這可能會阻止你從達到最佳速度)。通常,您安排一個作業送出盡可能多的 I/O,然後才引入其他作業。

更新

根據您在更新中包含的圖表,我們或多或少處於您認為的場景 2 中(256 個程序每個送出一個 I/O,NVMe 磁碟有多個隊列,每個隊列具有單獨的深度而不是一個巨大的隊列)但想像一下從使用者空間到核心的漏斗和從核心到“磁碟”隊列的另一個(不同)漏斗(讓我們忽略硬體 RAID 等),而不是從使用者空間程序到磁碟隊列的某種一對一映射. 除非您為磁碟使用使用者空間驅動程序,否則您將無法控制給定 I/O 最終將進入哪個隊列,因為核心會為您抽象該決定。例如,您的程序可能想跨 CPU(在核心中)

並且想通過所有層了解更多關於一般政策和可預測性的資訊

您可能必須通過核心塊層跟踪您的方式以確定同時了解您正在使用的核心版本。此外,一些 Ubuntu 14.04 核心對 NVMe 磁碟(我認為對 NVMe 設備的 blk-mq 支持在 3.19 核心中出現)不支持多隊列(請參閱 thi LWN 文章以獲得 blk-mq 的簡要摘要),這又回來了對我的“我有點懷疑您的 NVMe 磁碟出現在 SCSI 設備節點”的評論)。有一篇名為“ Linux Block IO: Introducing Multi-queue SSD Access on Multi-core Systems ”的論文更詳細地討論了 blk-mq 的變化和好處,並涵蓋了領域 1-3。給出一個入門總結。

fio 是如何發出流量的,以及它們是如何真正結束儲存 nvme_queues 的?

取決於 I/O 引擎和您選擇的配置 :-) 但是,對於範例配置,您提供的“在多核系統上引入多隊列 SSD 訪問”論文的圖 2 和圖 5 涵蓋了 fio 和“ fio 測試中的 iodepth 到底是什麼意思?是隊列深度嗎?答案涵蓋在 fio 本身內。

引用自:https://serverfault.com/questions/990563