저는 VHDL에 직렬 ATA 호스트 버스 어댑터(HBA)를 구현하고 이를 FPGA에 프로그래밍했습니다. FPGA는 모든 디지털 회로로 프로그래밍할 수 있는 칩입니다. 또한 SATA 또는 PCIe용 고속 신호를 생성하는 직렬 트랜시버도 장착되어 있습니다.
SATA 컨트롤러는 SATA 6Gb/s 회선 속도를 지원하고 ATA-8 DMA-IN/OUT 명령을 사용하여 장치와 최대 32MiB의 블록으로 데이터를 전송합니다. 이 디자인은 최고 속도(예: Samsung SSD 840 Pro -> 550MiB/s 이상)에서 실행될 수 있는 것으로 나타났습니다.
여러 SSD 및 HDD 장치로 몇 가지 테스트를 마친 후 새로운 Seagate 6TB Archive HDD(ST6000AS0002). 하드 드라이브의 읽기 성능은 최대 190MiB/s입니다.하지만 쓰기 성능은 30~40MiB/s에 불과합니다!
그래서 더 깊이 파고들어 전송된 프레임을 측정했습니다(예, FPGA 설계로 가능합니다). 내가 아는 한, Seagate HDD는 전체 전송의 처음 32MiB를 수신할 준비가 되어 있습니다. 이 전송은 최대 회선 속도 580MiB/s에서 발생합니다. 그 후에는 HDD가 남은 바이트 수를 초과하는 것을 중지합니다.800밀리초!그런 다음 HDD는 다음 32MiB를 수신할 준비가 되고 800밀리초 동안 다시 멈춥니다. 전체적으로 1GiB 전송에는 30초 이상이 소요되며 이는 약 35MiB/s에 해당합니다.
HDD에는 버스트 주기 사이에 플러시되는 32MiB 쓰기 캐시가 있다고 가정합니다. 32MiB보다 작은 데이터 전송에서는 이 동작이 나타나지 않습니다.
내 컨트롤러는 DMA-IN 및 DMA-OUT 명령을 사용하여 데이터를 전송합니다. NCQ를 지원하는 AHCI 컨트롤러에서 사용하는 QUEUED-DMA-IN 및 QUEUED-DMA-OUT 명령을 사용하지 않았습니다. FPGA 플랫폼에서 AHCI 및 NCQ를 구현하는 것은 매우 복잡하며 내 애플리케이션 계층에는 필요하지 않습니다.
내 Linux PC에서 이 시나리오를 재현하고 싶지만 Linux AHCI 드라이버에는 기본적으로 NCQ가 활성화되어 있습니다. NCQ를 비활성화해야 했기 때문에 방법을 설명하는 이 웹사이트를 찾았습니다.NCQ 비활성화, 하지만 작동하지 않습니다.
Linux PC는 여전히 190MiB/s의 쓰기 성능을 달성했습니다.
> dd if=/dev/zero of=/dev/sdb bs=32M count=32
1073741824 bytes (1.1 GB) copied, 5.46148 s, 197 MB/s
위 기사에는 실수가 있는 것 같습니다. NCQ 대기열 깊이를 1로 줄이면 NCQ가 비활성화되지 않습니다. 운영 체제가 하나의 대기열만 사용하도록 허용합니다. QUEUED-DMA-** 명령을 사용하여 계속 전송할 수 있습니다. 드라이버가 장치에 DMA-IN/OUT 명령을 실행할 수 있도록 실제로 NCQ를 비활성화해야 합니다.
내 질문은 다음과 같습니다
- NCQ를 비활성화하는 방법은 무엇입니까?
- NCQ 대기열 깊이 = 1인 경우 Linux용 AHCI 드라이버는 QUEUED-DMA-** 또는 DMA-** 명령을 사용합니까?
/sys/block/sdX/device/queue_depth
에서 변경사항이 보고되지 않아 NCQ가 비활성화되었는지 어떻게 확인할 수 있나요dmesg
?
답변1
@frostschutz 덕분에 NCQ 기능 없이 Linux에서 쓰기 성능을 측정할 수 있습니다. 커널 부팅 매개변수는 libata.force=noncq
NCQ를 완전히 비활성화합니다.
Seagate 6TB의 쓰기 성능 문제와 관련하여 속도에는 변화가 없습니다. Linux는 여전히 180MiB/s에 도달합니다.
하지만 또 다른 생각이 떠올랐습니다.
Linux 드라이버는 32MiB 블록 전송을 사용하지 않는다는 것입니다. 커널 버퍼는 특히 32개 대기열이 있는 NCQ가 활성화된 경우 훨씬 작습니다(32개 대기열 * 32MiB => 1GiB AHCI 버퍼).
그래서 256KiB 전송 속도로 SATA 컨트롤러를 테스트했는데 짜잔, 185MiB/s가 가능했습니다.
그래서 Seagate ST6000AS0002 펌웨어는 대규모 ATA 버스트 전송을 처리할 수 없는 것 같습니다. ATA 표준은 32MiB에 해당하는 최대 65.536개의 논리 블록을 허용합니다.
SMR - 슁글드 자기 녹음
쓰기 성능이 저하될 수 있는 또 다른 가능성은 다음과 같습니다.슁글드 자기 녹음 기술, Seagate는 이러한 보관 장치에 이를 사용합니다. 분명히 내 FPGA 구현은 드문 효과를 촉발했습니다.
답변2
대기열 깊이를 1( /sys/block/sd*/device/queue_depth
)로 설정하면 커널 매개변수 libata.force=noncq
(부팅 시에만 설정할 수 있음)를 사용하지 않고 NCQ가 비활성화됩니다.
범죄360f654e7cda850034f3f6252a7a7cff3fa77356
Date: Sat Sep 30 19:45:00 2006 +0900
[PATCH] libata: turn off NCQ if queue depth is adjusted to 1
Turn off NCQ if queue depth is adjusted to 1.