Zaimplementowałem własny adapter Serial-ATA Host-Bus-Adapter (HBA) w VHDL i zaprogramowałem go na FPGA. FPGA to układ, który można zaprogramować za pomocą dowolnego obwodu cyfrowego. Jest również wyposażony w szeregowe urządzenia nadawczo-odbiorcze do generowania sygnałów wysokiej prędkości dla SATA lub PCIe.
Ten kontroler SATA obsługuje prędkości linii SATA 6 Gb / s i wykorzystuje polecenia ATA-8 DMA-IN / OUT do przesyłania danych do 32 porcji MiB do i z urządzenia. Udowodniono, że konstrukcja działa z maksymalną prędkością (np. Samsung SSD 840 Pro -> ponad 550 MiB / s).
Po kilku testach z kilkoma urządzeniami SSD i HDD kupiłem nowy dysk twardy Seagate 6 TB Archive HDD ( ST6000AS0002 ). Ten dysk twardy osiąga prędkość odczytu do 190 MiB / s, ale tylko 30 do 40 MiB / s!
Więc kopałem głębiej i mierzyłem przesyłane klatki (tak, jest to możliwe przy konstrukcji FPGA). O ile mi wiadomo, dysk twardy Seagate jest gotowy do odbioru pierwszych 32 MB transferu w jednym kawałku. Transfer ten odbywa się przy maksymalnej prędkości linii wynoszącej 580 MiB / s. Następnie dysk twardy wstrzymuje pozostałe bajty na ponad 800 ms! Następnie dysk twardy jest gotowy na przyjęcie kolejnych 32 MiB i zatrzymuje się ponownie na 800 ms. W sumie transfer 1 GiB wymaga ponad 30 sekund, co odpowiada około 35 MiB / s.
Zakładam, że ten dysk twardy ma pamięć podręczną zapisu 32 MiB, która jest wprowadzana pomiędzy cyklami zdjęć seryjnych. Przesyłanie danych z mniej niż 32 MiB nie wykazuje tego zachowania.
Mój kontroler używa DMA-IN i DMA-OUT do przesyłania danych. Nie używam poleceń QUEUED-DMA-IN i QUEUED-DMA-OUT, które są używane przez kontrolery AHCI obsługujące NCQ. Wdrożenie AHCI i NCQ na platformie FPGA jest bardzo złożone i nie jest potrzebne mojej warstwie aplikacji.
Chciałbym odtworzyć ten scenariusz na moim komputerze z systemem Linux, ale sterownik Linux AHCI ma domyślnie włączone NCQ. Muszę wyłączyć NCQ, więc znalazłem tę stronę z opisem, jak wyłączyć NCQ , ale to nie działa.
Komputer z systemem Linux nadal osiąga wydajność zapisu 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
Myślę, że w powyższym artykule jest błąd: zmniejszenie głębokości kolejki NCQ do 1 nie wyłącza NCQ. Pozwala to systemowi operacyjnemu na użycie tylko jednej kolejki. Nadal może używać do przesyłania poleceń QUEUED-DMA - **. Naprawdę muszę wyłączyć NCQ, więc sterownik wydaje polecenia DMA-IN / OUT do urządzenia.
Oto moje pytania:
- Jak mogę wyłączyć NCQ?
- Jeśli głębokość kolejki NCQ = 1, czy sterownik AHCI systemu Linux używa poleceń QUEUED-DMA - ** lub DMA - **?
- Jak mogę sprawdzić, czy NCQ jest wyłączone, ponieważ zmiana
/sys/block/sdX/device/queue_depth
nie jest zgłaszana wdmesg
?
> dd if=/dev/zero of=/dev/sdb bs=32M count=32
Nie wiem, co zamierzałeś z tym zrobić; ale będzie to erase
zarówno MBR, jak i gazilliony bloków dalej. Robienie tego na dysku z uruchomionym na nim głównym systemem (i grub
zainstalowanym na MBR, jak w moim przypadku) byłoby dość niebezpieczne;) Myślałem, że napiszę to tutaj jako komentarz, aby uniemożliwić niektórym mniej doświadczonym ludziom eksperymentowanie z twoja „fajna” linia ...;)
libata.force=noncq
?