(20200729 作業メモ) NVLinkを利用する

29 7月

NVLinkを利用し,ビデオカードを2枚刺して計算してみたい。以下,主なパーツをあげます。

  • CPU : Core i5 9500
  • MB : ASRock Z390 Extreme4
  • GPU : RTX 2070 Super X 2 (ASUS DUAL-RTX2070S-O8G-EVO)
  • NVLink : ASUS ROG-NVLINK-3
  • Case : SilverStone SST-RM400
  • 電源 : Seasonic SSR-850FX

あまりにも2枚のカードの間に隙間が無かったので,ビデオカードのカバーを片方外しました。ケースファンの風を直接あてて冷却を補助しています。

他の角度のものもあげます。

下記のサイトに従って作業した。

  • 参考サイト:UbuntuでGPUマシーンを構築する
  • とくに今のところ NVLink に対応した作業が無い。色々なコマンドの応答からは2枚とも認識されていることは分かるが,NVLink が機能していることを確かめるにはどうしたら良いのか?

    温度をモニターしたいと思って,Psensor というソフトをインストールした。

  • 参考サイト:ubuntuでGPU, CPU温度などをグラフィカルに監視するpsensorを使う
  • 下図が計算中の観測。温度上昇にやや遅れて,ファンの回転数が上昇している。計測できるのは,ビデオカードの温度,ファンの回転数,メモリーの使用状況などである。

    メモリーや温度の上昇から見て,2枚目のビデオカードは利用されていない。もう少し大きな計算をやってみた方がよさそう。上記の計算は CUPY を利用したものである。NVLink が機能することと CUPY がNVLink 上で利用可能となるまでにはかなり隔たりがあるのかもしれない。

    (20200803)
    NVLink に関する応答メッセージを見つけた。dmesg | grep -i nvidia への応答の中に nvidia-nvlink: Nvlink Core is being initialized とある。

    dmesg | grep -i nvidia
    [    2.872886] nvidia: loading out-of-tree module taints kernel.
    [    2.872892] nvidia: module license 'NVIDIA' taints kernel.
    [    2.876488] nvidia: module verification failed: signature and/or required key missing - tainting kernel
    [    2.882683] nvidia-nvlink: Nvlink Core is being initialized, major device number 239
    [    2.883223] nvidia 0000:01:00.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=none:owns=io+mem
    [    2.927112] nvidia 0000:02:00.0: enabling device (0000 -> 0003)
    [    2.927191] nvidia 0000:02:00.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=none:owns=none
    [    2.976932] NVRM: loading NVIDIA UNIX x86_64 Kernel Module  450.51.06  Sun Jul 19 20:02:54 UTC 2020
    [    2.998138] nvidia-modeset: Loading NVIDIA Kernel Mode Setting Driver for UNIX platforms  450.51.06  Sun Jul 19 20:06:42 UTC 2020
    [    2.999991] [drm] [nvidia-drm] [GPU ID 0x00000100] Loading driver
    [    2.999992] [drm] Initialized nvidia-drm 0.0.0 20160202 for 0000:01:00.0 on minor 0
    [    3.000411] [drm] [nvidia-drm] [GPU ID 0x00000200] Loading driver
    [    3.000412] [drm] Initialized nvidia-drm 0.0.0 20160202 for 0000:02:00.0 on minor 1
    [    3.012872] nvidia-uvm: Loaded the UVM driver, major device number 236.
    [    3.436405] input: HDA NVidia HDMI/DP,pcm=3 as /devices/pci0000:00/0000:00:01.1/0000:02:00.1/sound/card2/input15
    [    3.436444] input: HDA NVidia HDMI/DP,pcm=7 as /devices/pci0000:00/0000:00:01.1/0000:02:00.1/sound/card2/input17
    [    3.436506] input: HDA NVidia HDMI/DP,pcm=8 as /devices/pci0000:00/0000:00:01.1/0000:02:00.1/sound/card2/input19
    [    3.436544] input: HDA NVidia HDMI/DP,pcm=9 as /devices/pci0000:00/0000:00:01.1/0000:02:00.1/sound/card2/input21
    [    3.436638] input: HDA NVidia HDMI/DP,pcm=3 as /devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1/input14
    [    3.436663] input: HDA NVidia HDMI/DP,pcm=7 as /devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1/input16
    [    3.436691] input: HDA NVidia HDMI/DP,pcm=8 as /devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1/input18
    [    3.436718] input: HDA NVidia HDMI/DP,pcm=9 as /devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1/input20
    [10301.646637] nvidia-modeset: WARNING: GPU:0: Unable to read EDID for display device Eizo EV2736W (HDMI-0)

    上手く行っているのだろうか?nvidia-smi nvlink -c の出力は下記のような感じ。

    nvidia-smi nvlink -c
    GPU 0: GeForce RTX 2070 SUPER (UUID: GPU-34242219-6f19-24de-f016-787c4f3cb2d0)
    	 Link 0, P2P is supported: true
    	 Link 0, Access to system memory supported: true
    	 Link 0, P2P atomics supported: true
    	 Link 0, System memory atomics supported: true
    	 Link 0, SLI is supported: true
    	 Link 0, Link is supported: false
    GPU 1: GeForce RTX 2070 SUPER (UUID: GPU-aed31587-58ba-52cc-a909-6906c3635b30)
    	 Link 0, P2P is supported: true
    	 Link 0, Access to system memory supported: true
    	 Link 0, P2P atomics supported: true
    	 Link 0, System memory atomics supported: true
    	 Link 0, SLI is supported: true
    	 Link 0, Link is supported: false

    nvidia-smi nvlink -s の出力は下記。

    nvidia-smi nvlink -s
    GPU 0: GeForce RTX 2070 SUPER (UUID: GPU-34242219-6f19-24de-f016-787c4f3cb2d0)
    	 Link 0: 25.781 GB/s
    GPU 1: GeForce RTX 2070 SUPER (UUID: GPU-aed31587-58ba-52cc-a909-6906c3635b30)
    	 Link 0: 25.781 GB/s
    

    CUDA サンプルを試してみる。サンプルのコンパイルをやって,端末から起動する。下図は nbody というサンプル。ファイルをダブルクリックでは動かない。ライブラリーがないとか怒られる。

    メモリーをほとんど使用しない。これで 1 % ぐらいだ。このデモでは,温度が急上昇する。85度ぐらいまで一気に上がる。少し怖くなって,どこまで上昇するかは試さなかった。デモを止めると急降下する。

    2つのビデオカードを使用して実行するように、オプションをつけて nbody -numdevices=2 としてみた。2000 GFLOP/S 程度だったのが、4000 GFLOP/S あたりに倍増している。

    両方の CPU の温度が上昇している。2つのビデオカードの温度に差がありすぎる。

    (20200804)
    ビデオカードのカバーを再び付けてみた。二つのカードの温度の開きは20度ぐらい。最高温度は85度だった。こちらにするべきか?

    同じ条件で,カバー無しの方を計測してみたら,最高温度が82度だった。当初の計画通りカバー無しの方で行くことにする。

    下記のサイトにしたがって、いくらか確認してみた。

    参考サイト:NVLINK on RTX 2080 TensorFlow and Peer-to-Peer Performance with Linux

    CUDA サンプルにある simpleP2P を実行してみた。

    ./simpleP2P 
    [./simpleP2P] - Starting...
    Checking for multiple GPUs...
    CUDA-capable device count: 2
    
    Checking GPU(s) for support of peer to peer memory access...
    > Peer access from GeForce RTX 2070 SUPER (GPU0) -> GeForce RTX 2070 SUPER (GPU1) : Yes
    > Peer access from GeForce RTX 2070 SUPER (GPU1) -> GeForce RTX 2070 SUPER (GPU0) : Yes
    Enabling peer access between GPU0 and GPU1...
    Allocating buffers (64MB on GPU0, GPU1 and CPU Host)...
    Creating event handles...
    cudaMemcpyPeer / cudaMemcpy between GPU0 and GPU1: 22.53GB/s
    Preparing host buffer and memcpy to GPU0...
    Run kernel on GPU1, taking source data from GPU0 and writing to GPU1...
    Run kernel on GPU0, taking source data from GPU1 and writing to GPU0...
    Copy data back to host from GPU0 and verify results...
    Disabling peer access...
    Shutting down...
    Test passed

    CUDA サンプルにある p2pBandwidthLatencyTest を実行してみた。

    ./p2pBandwidthLatencyTest 
    [P2P (Peer-to-Peer) GPU Bandwidth Latency Test]
    Device: 0, GeForce RTX 2070 SUPER, pciBusID: 1, pciDeviceID: 0, pciDomainID:0
    Device: 1, GeForce RTX 2070 SUPER, pciBusID: 2, pciDeviceID: 0, pciDomainID:0
    Device=0 CAN Access Peer Device=1
    Device=1 CAN Access Peer Device=0
    
    ***NOTE: In case a device doesn't have P2P access to other one, it falls back to normal memcopy procedure.
    So you can see lesser Bandwidth (GB/s) and unstable Latency (us) in those cases.
    
    P2P Connectivity Matrix
         D\D     0     1
         0	     1     1
         1	     1     1
    Unidirectional P2P=Disabled Bandwidth Matrix (GB/s)
       D\D     0      1 
         0 377.78   6.09 
         1   6.10 388.04 
    Unidirectional P2P=Enabled Bandwidth (P2P Writes) Matrix (GB/s)
       D\D     0      1 
         0 388.37  24.23 
         1  24.23 387.52 
    Bidirectional P2P=Disabled Bandwidth Matrix (GB/s)
       D\D     0      1 
         0 385.93   9.21 
         1   9.21 384.11 
    Bidirectional P2P=Enabled Bandwidth Matrix (GB/s)
       D\D     0      1 
         0 387.50  48.38 
         1  48.07 383.19 
    P2P=Disabled Latency Matrix (us)
       GPU     0      1 
         0   1.21  13.10 
         1  13.15   1.23 
    
       CPU     0      1 
         0   1.99   5.23 
         1   5.22   1.92 
    P2P=Enabled Latency (P2P Writes) Matrix (us)
       GPU     0      1 
         0   1.20   0.75 
         1   0.70   1.24 
    
       CPU     0      1 
         0   1.95   1.68 
         1   1.82   2.09 
    
    NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.

    (20200806)
    CUPY のマニュアルを読んでいると、GPU を切り替えるというコマンドがあった。

    # coding: utf-8
    import sys, os
    import numpy as np
    import cupy as cp
    
    cp.cuda.Device(1).use()

    上記の最後のコードで使用する GPU を切り替える。そうすると確かに2番めの GPU で計算し始めたようで、2番めのビデオカードの温度が上昇した。

    (20200810)
    https://www.v-t.co.jp/product/gpuphi/nvlink/には下記のようにある。

      Quadro(RTX/GP/GV)シリーズの2つの GPUを、NVLinkを用いたNVLink Bridgeで接続することにより、従来のPCIeバス間の通信よりも高速に通信することが可能です。対応したアプリケーションを利用すれば、マルチGPU 構成でメモリとパフォーマンスを簡単に拡張できます。
      例えば、2つのQuadro RTX 8000をQuadro RTX 8000 NVLink HB ブリッジで接続し、最大毎秒 100 GB の帯域幅、及び合計96GBのGDDR6 メモリとして、大規模なレンダリング、AI、バーチャル リアリティ、ビジュアライゼーションのワークロードに対応できます。
      ただしGeForce RTX 20シリーズ(2060は未対応)では、接続インターフェイスとしての利用に留まり、メモリやCUDAコアを統合して扱うことはできませんが、P2PでのGPU間のデータ転送は高速化されます。一方で、ソフトウェア的な互換性は維持されているため、「SLI」対応アプリケーションは「NVLink SLI」でもそのまま使用することができます。

    これからすると,私のレベルでは NVLink の恩恵にはあずかれそうにない。先にあげたリンク先

    ここに記述されている内容に期待するぐらいだろうか。