Eu implementei meu próprio HBA (Serial-ATA Host-Bus-Adapter) em VHDL e o programa 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. É comprovado que o design funciona 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 de 6 TB da Seagate ( ST6000AS0002 ). Este HDD atinge até 190 MiB / s de desempenho de leitura, mas apenas 30 a 40 MiB / s de desempenho de gravação!
Então, eu cavei mais fundo e medi os quadros transmitidos (sim, isso é possível com um design FPGA). Pelo que sei, o Seagate HDD está pronto para receber os primeiros 32 MiB de uma transferência em uma única peça. Essa transferência ocorre na velocidade máxima da linha de 580 MiB / s. Depois disso, o HDD interrompe os bytes restantes por mais de 800 ms! O HDD está pronto para receber os próximos 32 MiB e pára 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. As transferências de dados com menos de 32 MiB não mostram esse comportamento.
Meu controlador usa os comandos DMA-IN e DMA-OUT para transferir dados. Não estou usando os comandos QUEUED-DMA-IN e QUEUED-DMA-OUT, que são usados pelos controladores AHCI compatíveis com NCQ. A implementação do AHCI e do NCQ em uma plataforma FPGA é muito complexa e não é necessária para a minha camada de aplicação.
Gostaria de reproduzir esse cenário no meu PC Linux, mas o driver AHCI do Linux tem o NCQ ativado por padrão. Preciso desabilitar o NCQ, por isso encontrei este site descrevendo como desabilitar o NCQ , mas ele não funciona.
O PC Linux ainda atinge 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
Acho que há uma falha no artigo acima: Reduzir a profundidade da fila NCQ para 1 não desativa o NCQ. Apenas permite que o sistema operacional use apenas uma fila. Ele ainda pode usar os comandos QUEUED-DMA - ** para a transferência. Preciso realmente desabilitar o NCQ para que o driver emita comandos DMA-IN / OUT no dispositivo.
Então, aqui estão as minhas questões:
- Como posso desativar o NCQ?
- Se profundidade da fila NCQ = 1, o driver AHCI do Linux está usando os comandos QUEUED-DMA - ** ou DMA - **?
- Como posso verificar se o NCQ está desativado, porque as alterações
/sys/block/sdX/device/queue_depth
não são relatadasdmesg
?
> dd if=/dev/zero of=/dev/sdb bs=32M count=32
Não sei o que você pretendia fazer com isso; mas será erase
o MBR e bilhões de blocos além. Fazer isso em uma unidade com o sistema principal em execução (e grub
instalado no MBR, como no meu caso) seria bastante perigoso;) Pensei em escrever isso aqui como um comentário, para impedir que pessoas menos experientes experimentem sua linha "legal" ...;)
libata.force=noncq
?