Ich habe meinen eigenen Serial-ATA Host-Bus-Adapter (HBA) in VHDL implementiert und auf ein FPGA programmiert. Ein FPGA ist ein Chip, der mit jeder digitalen Schaltung programmiert werden kann. Es ist auch mit seriellen Transceivern ausgestattet, um Hochgeschwindigkeitssignale für SATA oder PCIe zu erzeugen.
Dieser SATA-Controller unterstützt SATA-Übertragungsraten von 6 Gbit / s und verwendet ATA-8-DMA-IN / OUT-Befehle, um Daten in bis zu 32 MiB-Blöcken zum und vom Gerät zu übertragen. Das Design arbeitet nachweislich mit maximaler Geschwindigkeit (z. B. Samsung SSD 840 Pro -> über 550 MiB / s).
Nach einigen Tests mit mehreren SSD- und HDD-Geräten habe ich eine neue Seagate 6 TB Archive-Festplatte ( ST6000AS0002 ) gekauft. Diese Festplatte erreicht eine Leseleistung von bis zu 190 MiB / s, aber nur eine Schreibleistung von 30 bis 40 MiB / s!
Also habe ich tiefer gegraben und die übertragenen Frames gemessen (ja, das ist mit einem FPGA-Design möglich). Soweit ich das beurteilen kann, ist die Seagate-Festplatte bereit, die ersten 32 MiB einer Übertragung in einem Stück zu empfangen. Diese Übertragung erfolgt mit einer maximalen Liniengeschwindigkeit von 580 MiB / s. Danach blockiert die Festplatte die verbleibenden Bytes für mehr als 800 ms! Dann ist die Festplatte bereit, die nächsten 32 MiB zu empfangen und bleibt 800 ms lang stehen. Alles in allem dauert eine 1-GiB-Übertragung über 30 Sekunden, was ca. 35 MiB / s entspricht.
Ich gehe davon aus, dass diese Festplatte einen 32-MiB-Schreibcache hat, der zwischen den Burst-Zyklen gespült wird. Datenübertragungen mit weniger als 32 MiB zeigen dieses Verhalten nicht.
Mein Controller verwendet die Befehle DMA-IN und DMA-OUT, um Daten zu übertragen. Ich verwende nicht die Befehle QUEUED-DMA-IN und QUEUED-DMA-OUT, die von NCQ-fähigen AHCI-Controllern verwendet werden. Die Implementierung von AHCI und NCQ auf einer FPGA-Plattform ist sehr komplex und wird von meiner Anwendungsebene nicht benötigt.
Ich möchte dieses Szenario auf meinem Linux-PC reproduzieren, aber der Linux-AHCI-Treiber hat standardmäßig NCQ aktiviert. Ich muss NCQ deaktivieren, daher habe ich auf dieser Website erfahren, wie man NCQ deaktiviert , aber es funktioniert nicht.
Der Linux-PC erreicht immer noch eine Schreibgeschwindigkeit von 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
Ich denke, es gibt einen Fehler in dem Artikel von oben: Das Reduzieren der NCQ-Warteschlangentiefe auf 1 deaktiviert NCQ nicht. Es erlaubt dem Betriebssystem nur, nur eine Warteschlange zu verwenden. Es kann weiterhin QUEUED-DMA - ** - Befehle für die Übertragung verwenden. Ich muss NCQ wirklich deaktivieren, damit der Treiber DMA-IN / OUT-Befehle an das Gerät ausgibt.
Also hier sind meine Fragen:
- Wie kann ich NCQ deaktivieren?
- Wenn die Tiefe der NCQ-Warteschlange = 1 ist, verwendet der AHCI-Treiber von Linux die Befehle QUEUED-DMA - ** oder DMA - **?
- Wie kann ich überprüfen, ob NCQ deaktiviert ist, da Änderungen
/sys/block/sdX/device/queue_depth
nicht in gemeldet werdendmesg
?
> dd if=/dev/zero of=/dev/sdb bs=32M count=32
Keine Ahnung, was Sie damit vorhatten; aber es wird erase
sowohl den MBR als auch Millionen von Blöcken jenseits. Dies auf einem Laufwerk zu tun, auf dem das Hauptsystem läuft (und grub
das wie in meinem Fall auf MBR installiert ist), wäre ziemlich gefährlich. Ich dachte, ich schreibe dies hier als Kommentar, um zu verhindern, dass weniger erfahrene Leute damit experimentieren Ihre "coole" Linie ...;)
libata.force=noncq
?