Eu implementei meu próprio HBA (Host-Bus-Adapter) Serial-ATA em VHDL e o programou em um FPGA. Um FPGA é um chip que pode ser programado com qualquer circuito digital. Também é equipado com transceptores seriais para gerar sinais de alta velocidade para SATA ou PCIe.
Este controlador SATA suporta taxas de linha SATA de 6 Gb / s e usa comandos ATA-8 DMA-IN / OUT para transferir dados em até 32 blocos MiB de e para o dispositivo. O design está comprovado para funcionar na velocidade máxima (por exemplo, Samsung SSD 840 Pro - > acima de 550 MiB / s).
Após alguns testes com vários dispositivos SSD e HDD, comprei um novo HDD de arquivo do Seagate 6 TB ( ST6000AS0002 ). Este HDD atinge desempenho de leitura de até 190 MiB / s, , mas somente desempenho de gravação de 30 a 40 MiB / s!
Então eu cavei mais fundo e medi os quadros transmitidos (sim, isso é possível com um design FPGA). Tanto quanto eu posso dizer, o Seagate HDD está pronto para receber os primeiros 32 MiB de uma transferência em uma única peça. Essa transferência acontece na velocidade máxima da linha de 580 MiB / s. Depois disso, o HDD bloqueia os bytes restantes por mais de 800 ms! Em seguida, o HDD está pronto para receber os próximos 32 MiB e parará novamente por 800 ms. Ao todo, uma transferência de 1 GiB precisa de mais de 30 segundos, o que equivale a cerca de 35 MiB / s.
Suponho que este HDD tenha um cache de gravação de 32 MiB, que é liberado entre os ciclos de burst. Transferências de dados com menos de 32 MiB não mostram esse comportamento.
Meu controlador usa o comando DMA-IN e DMA-OUT para transferir dados. Eu não estou usando o comando QUEUED-DMA-IN e QUEUED-DMA-OUT, que são usados por controladores AHCI com capacidade NCQ. A implementação de AHCI e NCQ em uma plataforma FPGA é muito complexa e não é necessária para minha camada de aplicativo.
Eu gostaria de reproduzir este cenário no meu PC Linux, mas o driver Linux AHCI tem o NCQ habilitado por padrão. Eu preciso desativar NCQ, então eu encontrei este site descrevendo como desativar NCQ , mas não funciona.
O PC Linux ainda alcança o desempenho de gravação 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
Eu acho que há uma falha no artigo acima: Reduzir a profundidade da fila do NCQ para 1 não desabilita o NCQ. Apenas permite que o sistema operacional use apenas uma fila. Ele ainda pode usar os comandos QUEUED-DMA - ** para a transferência. Eu preciso realmente desabilitar o NCQ para que o driver emita comandos DMA-IN / OUT para o dispositivo.
Então, aqui estão minhas perguntas:
- Como posso desativar o NCQ?
- Se a profundidade da fila NCQ = 1, o driver AHCI do Linux estiver usando os comandos QUEUED-DMA - ** ou DMA - **?
- Como posso verificar se o NCQ está desabilitado, porque alterar
/sys/block/sdX/device/queue_depth
não é reportado em dmesg
?