如何(真正)在 Linux 中禁用 NCQ
我用 VHDL 實現了我自己的串列 ATA 主機匯流排適配器 (HBA),並將其程式到 FPGA 上。FPGA是可以用任何數字電路程式的晶片。它還配備了串列收發器,可為 SATA 或 PCIe 生成高速信號。
此 SATA 控制器支持 SATA 6 Gb/s 線路速率,並使用 ATA-8 DMA-IN/OUT 命令以高達 32 MiB 的數據塊在設備之間傳輸數據。該設計已被證明可以以最高速度執行(例如,三星 SSD 840 Pro -> 超過 550 MiB/s)。
在對幾個 SSD 和 HDD 設備進行了一些測試後,我購買了一個新的 Seagate 6 TB Archive HDD ( ST6000AS0002 )。這款 HDD 的讀取性能高達 190 MiB/s,但寫入性能只有 30 到 40 MiB/s!
所以我深入探勘並測量了傳輸的幀(是的,這可以通過 FPGA 設計實現)。據我所知,希捷硬碟已準備好接收前 32 MiB 的一次傳輸。此傳輸以 580 MiB/s 的最大線速度進行。之後,HDD 將剩餘字節停頓超過**800 毫秒!**然後 HDD 準備好接收下一個 32 MiB 並再次停止 800 毫秒。總而言之,1 GiB 傳輸需要超過 30 秒,這相當於大約 35 MiB/s。
我假設這個 HDD 有一個 32 MiB 的寫記憶體,它在突發週期之間被刷新。小於 32 MiB 的數據傳輸不會顯示此行為。
我的控制器使用 DMA-IN 和 DMA-OUT 命令來傳輸數據。我沒有使用支持 NCQ 的 AHCI 控制器使用的 QUEUED-DMA-IN 和 QUEUED-DMA-OUT 命令。在 FPGA 平台上實現 AHCI 和 NCQ 非常複雜,我的應用層不需要。
我想在我的 Linux PC 上重現這種情況,但 Linux AHCI 驅動程序預設啟用了 NCQ。我需要禁用 NCQ,所以我發現這個網站描述瞭如何禁用 NCQ,但它不起作用。
Linux PC 仍然達到 190 MiB/s 的寫入性能。
> dd if=/dev/zero of=/dev/sdb bs=32M count=32 1073741824 bytes (1.1 GB) copied, 5.46148 s, 197 MB/s
我認為上面的文章有一個錯誤:將 NCQ 隊列深度減少到 1 不會禁用 NCQ。它只允許作業系統使用一個隊列。它仍然可以使用 QUEUED-DMA-** 命令進行傳輸。我需要真正禁用 NCQ,以便驅動程序向設備發出 DMA-IN/OUT 命令。
所以這是我的問題:
- 如何禁用 NCQ?
- 如果 NCQ 隊列深度 = 1,Linux 的 AHCI 驅動程序是否使用 QUEUED-DMA-** 或 DMA-** 命令?
- 我如何檢查 NCQ 是否被禁用,因為
/sys/block/sdX/device/queue_depth
沒有報告更改dmesg
?
感謝@frostschutz,我可以在沒有 NCQ 功能的情況下測量 Linux 中的寫入性能。核心引導參數
libata.force=noncq
完全禁用了 NCQ。關於我的希捷 6TB 寫入性能問題,速度沒有變化。Linux 仍然達到 180 MiB/s。
但後來我有了另一個想法:
Linux 驅動程序不使用 32 MiB 塊的傳輸。核心緩衝區要小得多,特別是如果啟用了具有 32 個隊列的 NCQ(32 個隊列 * 32 MiB => 1 GiB AHCI 緩衝區)。
所以我用 256 KiB 傳輸測試了我的 SATA 控制器,瞧,它有可能達到 185 MiB/s。
所以我猜希捷 ST6000AS0002 韌體無法處理大的 ATA 突發傳輸。ATA 標準最多允許 65.536 個邏輯塊,即 32 MiB。
SMR - 疊瓦式磁記錄
寫入性能不佳的另一種可能是希捷在這些存檔設備中使用的疊瓦式磁記錄技術。顯然,我的 FPGA 實現觸發了一種罕見的效果。