スキャン速度 10GB/s への挑戦~その①~

PCIe直結のNVMe-SSDは、コントローラの性能にもよるものの、PCIe x4接続のコンシューマ製品であれば一枚あたり1.8GB/s~3.5GB/s、PCIe x8接続のエンタープライズ製品であれば一枚あたり5.0GB/s~6.0GB/sものスループットを出すことができる。

ただ、実際にはサーバのPCIeスロットに空きがあっても、PCIe x8スロットなので、コンシューマ製品を使うと帯域を余らせてしまったり、エンタープライズ製品では少々お高くなるといった問題がある。

例えば、私が持っているSuperMicro 5018GR-Tというサーバは、TESLAなどパッシブファン型のGPUを搭載できるモデルで、PCIe x16スロットが2つ(GPU用)と、x8スロットが1つ(HHHL)用意されている。
Supermicro | Products | SuperServers | 1U | 5018GR-T
この場合、x16スロットにGPUを搭載すると、物理的に残りスロットは2つ。
エンタープライズ向け製品はそこそこ値段が張るので、なかなか気軽に買うわけにはいかないので、ソフトウェアの開発・デバッグをコンシューマ向けNVMe-SSD製品で行うことになる。そうすると、2枚合わせても帯域は3.6GB/s~7.0GB/s程度となり、GPU側のPCIe x16スロットの帯域を埋め尽くすところまでは到達できない。

そんな折、面白いガジェットを見つけた。
カナダのAmfeltecという会社が開発、販売しているデバイスで、PCIe x16スロットに接続のキャリアボードの上にPCIeスイッチが搭載されており、その先にM.2 SSDを最大4枚搭載することができる。
PCI Express Gen 3 Carrier Board for 4 M.2 SSD modules - Amfeltec

形状は1Slot幅のフルハイト・ハーフレングス(FHHL)なので、少なくともGPUを搭載するようなスロットであれば余裕で搭載できる*1。今まで最大でもSSD x3枚構成でしかスループットを計測できていなかったので、果たして、理論合計帯域がPCIe x16に達した状態で、SSD-to-GPUダイレクト転送が想定通りに機能するのかというのを試すため、このデバイスをカナダから取り寄せてみた。

お値段 540.14USD也 (本体 465.00USD + 送料/手数料 75.14USD)

で、届いたブツがこれ。

これに、M.2接続のコンシューマ製品では最高のスループットを誇るSamsung社のSSD PRO 960を4枚挿すことにする。


※写真では箱が2つですが、512GB版を4枚買いました。

ヒートシンクアイネックスHM-21という高さの低いものを購入。結果的に、このH5.1mmという背の低さが1Uサーバの筐体にうまくフィットすることになった。


こういった感じで、表面/裏面それぞれ2枚ずつM.2 SSDを搭載することができる。


実際にはヒートシンクを搭載するので、SSDのロゴは隠れます。


表面/裏面にそれぞれ2枚ずつ、計4枚のSSD 960PROが搭載されているのがお分かりだろうか。


5018GR-Tサーバに搭載した様子。
奥側のPCIe x16スロットにはTesla P40が、手前のPCIe x16スロットにはキャリアボード経由でSSDが4枚搭載されている。
Samsungのカタログスペックによると、SSD 960PROのSeqReadは3.5GB/sという事なので、もし4枚のSSDからフルスピードでデータを読み出せれば、合計の転送速度は14.0GB/sとなり、目標とする10GB/sを上回ることになる。

さて、どうなるか。

まず、4枚のSSDがOSで認識されていることを確認。

[kaigai@saba ~]$ lspci -v | grep Samsung
05:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a804 (prog-if 02 [NVM Express])
        Subsystem: Samsung Electronics Co Ltd Device a801
06:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a804 (prog-if 02 [NVM Express])
        Subsystem: Samsung Electronics Co Ltd Device a801
07:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a804 (prog-if 02 [NVM Express])
        Subsystem: Samsung Electronics Co Ltd Device a801
08:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a804 (prog-if 02 [NVM Express])
        Subsystem: Samsung Electronics Co Ltd Device a801

きちんとデバイスファイルも作成されている。

[kaigai@saba ~]$ ls -l /dev/nvme?n1
brw-rw----. 1 root disk 259, 1 May 28 14:08 /dev/nvme0n1
brw-rw----. 1 root disk 259, 3 May 28 14:08 /dev/nvme1n1
brw-rw----. 1 root disk 259, 2 May 28 14:09 /dev/nvme2n1
brw-rw----. 1 root disk 259, 0 May 28 14:09 /dev/nvme3n1

とりあえず、RAID0構成の違いによるスループットの差を見るため、1個のSSDをそれぞれ3つの区画に分け、2枚構成/3枚構成/4枚構成でのデータ転送速度を計測してみる。

# mdadm -C /dev/md2 -c 128 -l 0 -n 2 /dev/nvme0n1p1 /dev/nvme1n1p1
# mdadm -C /dev/md3 -c 128 -l 0 -n 3 /dev/nvme0n1p2 /dev/nvme1n1p2 \
                                     /dev/nvme2n1p2
# mdadm -C /dev/md4 -c 128 -l 0 -n 4 /dev/nvme0n1p3 /dev/nvme1n1p3 \
                                     /dev/nvme2n1p3 /dev/nvme3n1p3

まず、SSD 2枚によるSSD-to-GPUダイレクト転送の実験。

[kaigai@saba utils]$ ./nvme_test /opt/nvme2/100GB
GPU[0] Tesla P40 - file: /opt/nvme2/100GB, i/o size: 100.00GB, buffer 32MB x 6
read: 100.00GB, time: 15.36sec, throughput: 6.51GB/s
sem_wait: 10177ms, nr_ram2gpu: 0, nr_ssd2gpu: 13107200, average DMA blocks: 256.00

スループットは 6.51GB/s で、理論限界3.5GB/sのSSDを2枚束ねたという点では上出来。

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.06    0.00    1.36    0.00    0.00   98.58

Device:            tps    MB_read/s    MB_wrtn/s    MB_read    MB_wrtn
nvme0n1       26398.00      3299.75         0.00       6599          0
nvme3n1           0.00         0.00         0.00          0          0
nvme1n1       26261.50      3282.69         0.00       6565          0
nvme2n1           0.00         0.00         0.00          0          0
md2           52659.00      6582.38         0.00      13164          0
md3               0.00         0.00         0.00          0          0
md4               0.00         0.00         0.00          0          0

実行中、iostatも概ねその辺の値を記録している。

次に、SSD 3枚によるSSD-to-GPUダイレクト転送の実験。

[kaigai@saba utils]$ ./nvme_test /opt/nvme3/100GB
GPU[0] Tesla P40 - file: /opt/nvme3/100GB, i/o size: 100.00GB, buffer 32MB x 6
read: 100.00GB, time: 10.73sec, throughput: 9.32GB/s
sem_wait: 6193ms, nr_ram2gpu: 0, nr_ssd2gpu: 13107200, average DMA blocks: 256.00

スループットは 9.32GB/s まで上がり、理論限界10.5GB/sに対してなかなかの値。

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.08    0.00    1.80    0.00    0.00   98.12

Device:            tps    MB_read/s    MB_wrtn/s    MB_read    MB_wrtn
nvme0n1       25458.00      3182.25         0.00       6364          0
nvme3n1           0.00         0.00         0.00          0          0
nvme1n1       25464.50      3183.12         0.00       6366          0
nvme2n1       25458.50      3182.31         0.00       6364          0
md2               0.00         0.00         0.00          0          0
md3           76382.00      9547.75         0.00      19095          0
md4               0.00         0.00         0.00          0          0

実行中のiostatによれば、各デバイスは概ね3.1GB/sのスループットを記録していた模様。

最後に、SSD 4枚によるSSD-to-GPUダイレクト転送の実験。

[kaigai@saba utils]$ ./nvme_test /opt/nvme4/100GB
GPU[0] Tesla P40 - file: /opt/nvme4/100GB, i/o size: 100.00GB, buffer 32MB x 6
read: 100.00GB, time: 10.56sec, throughput: 9.47GB/s
sem_wait: 5818ms, nr_ram2gpu: 0, nr_ssd2gpu: 13107200, average DMA blocks: 256.00

おや、流石に10GB/s近くなり、他のところで苦しくなってきたのか?
9.5GB/s近辺でデータ転送のスループットが頭打ちとなっている。

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.06    0.00    1.88    0.00    0.00   98.05

Device:            tps    MB_read/s    MB_wrtn/s    MB_read    MB_wrtn
nvme0n1       19392.00      2423.94         0.00       4847          0
nvme3n1       19407.00      2425.88         0.00       4851          0
nvme1n1       19415.50      2426.94         0.00       4853          0
nvme2n1       19407.50      2425.94         0.00       4851          0
md2               0.00         0.00         0.00          0          0
md3               0.00         0.00         0.00          0          0
md4           77621.00      9702.62         0.00      19405          0

iostatを眺めてみると、一枚あたりの転送性能は2.4GB/s程度に落ち込んでいる。
GPU側でデータを受ける方の限界や、あるいはライザカード上のPCIeスイッチが被疑という事も考えられるが、この辺は別な環境を用意して切り分けができるようになるまではペンディングといったところか。

この手のカードは、製品構成を考える時に候補に入れるかどうかは(主に保守サポートの問題で)結構悩ましいが、開発・デバッグ用途でなら単にデータ転送レート10GB/s近くを出せるデバイスという位置づけで十分使える。

というわけで、ストレージの帯域にお悩みの週末プログラマの方は、Amfeltec社 SKU-086-34(PCIe Carrier board for 4 M.2 SSD modules)ボードでも試してみてはいかがでしょうか?

※ なお『その②』以降の予定は今のところ未定です。

*1:さらにパッシブファン用GPU向けの風量が供給されているので、ヒートシンクさえ付ければThermal Throttlingが発動するレベルまで温度は上がらないハズ