J'ai implémenté mon propre adaptateur de bus hôte Serial-ATA (HBA) en VHDL et l'ai programmé sur un FPGA. Un FPGA est une puce qui peut être programmée avec n'importe quel circuit numérique. Il est également équipé d'émetteurs-récepteurs série pour générer des signaux à haute vitesse pour SATA ou PCIe.
Ce contrôleur SATA prend en charge les débits de ligne SATA 6 Gb / s et utilise les commandes ATA-8 DMA-IN / OUT pour transférer des données jusqu'à 32 Mo de blocs vers et depuis l'appareil. Il a été prouvé que la conception fonctionne à vitesse maximale (par exemple, Samsung SSD 840 Pro -> plus de 550 Mio / s).
Après quelques tests avec plusieurs périphériques SSD et HDD, j'ai acheté un nouveau disque dur Seagate 6 TB Archive ( ST6000AS0002 ). Ce disque dur atteint des performances de lecture allant jusqu'à 190 Mio / s, mais seulement des performances d'écriture de 30 à 40 Mio / s!
J'ai donc creusé plus profondément et mesuré les trames transmises (oui c'est possible avec une conception FPGA). Pour autant que je sache, le Seagate HDD est prêt à recevoir les 32 premiers Mo d'un transfert en une seule pièce. Ce transfert se produit à une vitesse de ligne maximale de 580 MiB / s. Après cela, le disque dur bloque les octets restants pendant plus de 800 ms! Ensuite, le disque dur est prêt à recevoir les 32 Mio suivants et se bloque à nouveau pendant 800 ms. Dans l'ensemble, un transfert de 1 Gio nécessite plus de 30 secondes, ce qui équivaut à environ 35 Mio / s.
Je suppose que ce disque dur a un cache d'écriture de 32 Mio, qui est vidé entre les cycles de rafale. Les transferts de données avec moins de 32 Mio ne montrent pas ce comportement.
Mon contrôleur utilise la commande DMA-IN et DMA-OUT pour transférer des données. Je n'utilise pas les commandes QUEUED-DMA-IN et QUEUED-DMA-OUT, qui sont utilisées par les contrôleurs AHCI compatibles NCQ. L'intégration d'AHCI et de NCQ sur une plate-forme FPGA est très complexe et n'est pas nécessaire à ma couche application.
Je voudrais reproduire ce scénario sur mon PC Linux, mais le pilote Linux AHCI a NCQ activé par défaut. Je dois désactiver NCQ, j'ai donc trouvé ce site Web décrivant comment désactiver NCQ , mais cela ne fonctionne pas.
Le PC Linux atteint toujours des performances d'écriture de 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
Je pense qu'il y a un défaut dans l'article ci-dessus: Réduire la profondeur de la file d'attente NCQ à 1 ne désactive pas NCQ. Il permet simplement au système d'exploitation d'utiliser une seule file d'attente. Il peut toujours utiliser les commandes QUEUED-DMA - ** pour le transfert. Je dois vraiment désactiver NCQ pour que le pilote émette des commandes DMA-IN / OUT vers l'appareil.
Donc, voici mes questions:
- Comment puis-je désactiver NCQ?
- Si la profondeur de file d'attente NCQ = 1, le pilote AHCI de Linux utilise-t-il les commandes QUEUED-DMA - ** ou DMA - **?
- Comment puis-je vérifier si NCQ est désactivé, car la modification
/sys/block/sdX/device/queue_depth
n'est pas signalée dansdmesg
?
> dd if=/dev/zero of=/dev/sdb bs=32M count=32
Je ne sais pas ce que vous aviez l'intention de faire avec ça; mais ce sera erase
à la fois le MBR et les gazillions de blocs au-delà. Faire cela sur un lecteur avec le système principal en cours d'exécution (et grub
installé sur MBR, comme dans mon cas) serait assez dangereux;) J'ai pensé écrire ceci ici en tant que commentaire, pour empêcher certaines personnes moins expérimentées d'expérimenter avec votre ligne "cool" ...;)
libata.force=noncq
?