Implementé mi propio Serial-ATA Host-Bus-Adapter (HBA) en VHDL y lo programé en un FPGA. Un FPGA es un chip que se puede programar con cualquier circuito digital. También está equipado con transceptores en serie para generar señales de alta velocidad para SATA o PCIe.
Este controlador SATA admite velocidades de línea SATA de 6 Gb / sy utiliza comandos ATA-8 DMA-IN / OUT para transferir datos en hasta 32 fragmentos MiB desde y hacia el dispositivo. Se ha demostrado que el diseño funciona a la velocidad máxima (por ejemplo, Samsung SSD 840 Pro -> más de 550 MiB / s).
Después de algunas pruebas con varios dispositivos SSD y HDD, compré un nuevo Seagate 6 TB Archive HDD ( ST6000AS0002 ). Este HDD alcanza un rendimiento de lectura de hasta 190 MiB / s, ¡ pero solo un rendimiento de escritura de 30 a 40 MiB / s!
Entonces cavé más profundo y medí los cuadros transmitidos (sí, eso es posible con un diseño FPGA). Hasta donde puedo decir, el Seagate HDD está listo para recibir los primeros 32 MiB de una transferencia en una sola pieza. Esta transferencia ocurre a una velocidad máxima de línea de 580 MiB / s. ¡Después de eso, el HDD detiene los bytes restantes por más de 800 ms! Luego, el HDD está listo para recibir los siguientes 32 MiB y se detiene nuevamente durante 800 ms. En general, una transferencia de 1 GiB necesita más de 30 segundos, lo que equivale a alrededor de 35 MiB / s.
Supongo que este HDD tiene una memoria caché de escritura de 32 MiB, que se vacía entre los ciclos de ráfaga. Las transferencias de datos con menos de 32 MiB no muestran este comportamiento.
Mi controlador utiliza el comando DMA-IN y DMA-OUT para transferir datos. No estoy usando los comandos QUEUED-DMA-IN y QUEUED-DMA-OUT, que son utilizados por los controladores AHCI con capacidad NCQ. La implementación de AHCI y NCQ en una plataforma FPGA es muy compleja y mi capa de aplicación no la necesita.
Me gustaría reproducir este escenario en mi PC con Linux, pero el controlador Linux AHCI tiene NCQ habilitado de forma predeterminada. Necesito deshabilitar NCQ, así que encontré este sitio web que describe cómo deshabilitar NCQ , pero no funciona.
La PC con Linux aún alcanza 190 miB / s de rendimiento de escritura.
> dd if=/dev/zero of=/dev/sdb bs=32M count=32
1073741824 bytes (1.1 GB) copied, 5.46148 s, 197 MB/s
Creo que hay un error en el artículo anterior: reducir la profundidad de la cola NCQ a 1 no deshabilita NCQ. Simplemente le permite al sistema operativo usar una sola cola. Todavía puede usar los comandos QUEUED-DMA - ** para la transferencia. Necesito deshabilitar realmente NCQ para que el controlador emita comandos DMA-IN / OUT al dispositivo.
Asi que aqui están mis preguntas:
- ¿Cómo puedo desactivar NCQ?
- Si la profundidad de la cola de NCQ = 1, ¿el controlador AHCI de Linux usa los comandos QUEUED-DMA - ** o DMA - **?
- ¿Cómo puedo verificar si NCQ está desactivado porque
/sys/block/sdX/device/queue_depth
no se informan los cambiosdmesg
?
> dd if=/dev/zero of=/dev/sdb bs=32M count=32
No sé qué pretendías hacer con eso; pero será erase
tanto el MBR como millones de bloques más allá. Hacer esto en una unidad con el sistema principal en ejecución (e grub
instalado en MBR, como en mi caso) sería bastante peligroso;) Pensé en escribir esto aquí como un comentario, para evitar que algunas personas menos experimentadas experimenten con your "cool" line ...;)
libata.force=noncq
?