🛣️

NVIDIA製GPUのPCI Expressのリンク速度を調べる(Linuxの場合)

2021/11/27に公開

はじめに

昨今ではPCI Express 4.0(Gen4)対応のCPU、マザーボード、GPUが一般的に流通するようになりましたね。
そんな中、GPUをセットアップしていて、ふと思いました。「本当にPCI Express 4.0で動作しているのだろうか?」と。

そこで今回は、PCI Expressの世代、帯域、レーン数などを調べる方法を整理してみました。

具体的には、以下の3つのコマンドを紹介します。

  • nvidia-smi -a
  • nvidia-smi --format=csv --query-gpu=index,gpu_bus_id,name,pcie.link.gen.max,pcie.link.gen.current,pcie.link.width.max,pcie.link.width.current
  • sudo lspci -s [バス番号] -vv

nvidia-smiコマンドを使用する方法(NVIDIA製GPUの場合)

NVIDIA製GPUの場合、nvidia-smiコマンドでPCI Expressのリンク速度を調べることができます。

1つ目は、nvidia-smi -aを使用する方法です。具体例(抜粋)を以下に示します。

$ nvidia-smi -a
...
Attached GPUs                             : 1
GPU 00000000:2D:00.0
...
    PCI
        Bus                               : 0x2D
        Device                            : 0x00
        Domain                            : 0x0000
        Device Id                         : 0x1B8110DE
        Bus Id                            : 00000000:2D:00.0
        Sub System Id                     : 0x1B8110DE
        GPU Link Info
            PCIe Generation
                Max                       : 3
                Current                   : 1
            Link Width
                Max                       : 16x
                Current                   : 16x
...

上記の例では、PCI Expressの3.0(Gen3)をサポートしているGPUが、現状では1.0(Gen1)で動作しています。
また、レーン数は最大x16をサポートしており、現状でもx16でリンクしていることを示しています。
「PCI Express 3.0対応なのに1.0?」と思われるかも知れませんが、(少なくともGPUの)PCI Expressのリンク速度は可変のようで、GPUが動作している最中には、PCI Express 3.0 x16でリンクしていました。

2つ目は、nvidia-smi --query-gpuを使用する方法です。nvidia-smi -aはすべての情報を出力してくれて便利ではあるのですが、出力結果が長く、複数のGPUが接続されている場合の表示も見づらいです。

--query-gpuオプションには、出力する項目名を指定することができます。具体例を以下に示します。

$ nvidia-smi --format=csv --query-gpu=index,gpu_bus_id,name,pcie.link.gen.max,pcie.link.gen.current,pcie.link.width.max,pcie.link.width.current
index, pci.bus_id, name, pcie.link.gen.max, pcie.link.gen.current, pcie.link.width.max, pcie.link.width.current
0, 00000000:2D:00.0, GeForce GTX 1070, 3, 1, 16, 16

上記の例だと、最後の4列がPCI Expressの「最大の世代」、「現在の世代」、「最大のレーン数」、「現在のレーン数」を示します。

フォーマットとしてCSVを指定した場合、上記のように1GPUが1行として出力され、複数のGPUが搭載されている場合も見やすいです。

lspciコマンドを使用する方法(ボードの種類を問わず)

nvidia-smiコマンドはNVIDIA製GPUの場合のみに使うことができますが、lspciコマンドを使えばGPUのメーカー、ボードの種類を問わずにリンク速度を調べることができます。

lspciコマンドを使う場合、以下の2段階で実行するのがオススメです。バス番号を指定せずに、全デバイスの詳細情報を出力することもできますが、出力が膨大すぎて見づらいです。

  1. lspciコマンドとgrepコマンドを組み合わせてバス番号を調べる。
  2. lspciコマンドにバス番号(-s)を指定して詳細情報(-vv)を表示する。(詳細情報の取得にはroot権限が必要)

具体例を以下に示します。

$ lspci | grep -i nvidia
2d:00.0 VGA compatible controller: NVIDIA Corporation GP104 [GeForce GTX 1070] (rev a1)
2d:00.1 Audio device: NVIDIA Corporation GP104 High Definition Audio Controller (rev a1)

$ sudo lspci -s 2d:00.0 -vv
2d:00.0 VGA compatible controller: NVIDIA Corporation GP104 [GeForce GTX 1070] (rev a1) (prog-if 00 [VGA controller])
        Subsystem: NVIDIA Corporation GP104 [GeForce GTX 1070]
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0
        Interrupt: pin A routed to IRQ 97
        Region 0: Memory at f6000000 (32-bit, non-prefetchable) [size=16M]
        Region 1: Memory at e0000000 (64-bit, prefetchable) [size=256M]
        Region 3: Memory at f0000000 (64-bit, prefetchable) [size=32M]
        Region 5: I/O ports at e000 [size=128]
        Expansion ROM at 000c0000 [virtual] [disabled] [size=128K]
        Capabilities: [60] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [68] MSI: Enable+ Count=1/1 Maskable- 64bit+
                Address: 00000000fee00000  Data: 0000
        Capabilities: [78] Express (v2) Legacy Endpoint, MSI 00
                DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s unlimited, L1 <64us
                        ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
                DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
                        RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+
                        MaxPayload 256 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
                LnkCap: Port #0, Speed 8GT/s, Width x16, ASPM L0s L1, Exit Latency L0s <512ns, L1 <16us
                        ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
                LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
                        ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed 2.5GT/s (downgraded), Width x16 (ok)
                        TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
                DevCap2: Completion Timeout: Range AB, TimeoutDis+, NROPrPrP-, LTR+
                         10BitTagComp-, 10BitTagReq-, OBFF Via message, ExtFmt-, EETLPPrefix-
                         EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
                         FRS-
                         AtomicOpsCap: 32bit- 64bit- 128bitCAS-
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR+, OBFF Disabled
                         AtomicOpsCtl: ReqEn-
                LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance De-emphasis: -6dB
                LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete+, EqualizationPhase1+
                         EqualizationPhase2+, EqualizationPhase3+, LinkEqualizationRequest-
        Capabilities: [100 v1] Virtual Channel
                Caps:   LPEVC=0 RefClk=100ns PATEntryBits=1
                Arb:    Fixed- WRR32- WRR64- WRR128-
                Ctrl:   ArbSelect=Fixed
                Status: InProgress-
                VC0:    Caps:   PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
                        Arb:    Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
                        Ctrl:   Enable+ ID=0 ArbSelect=Fixed TC/VC=01
                        Status: NegoPending- InProgress-
        Capabilities: [250 v1] Latency Tolerance Reporting
                Max snoop latency: 34326183936ns
                Max no snoop latency: 34326183936ns
        Capabilities: [128 v1] Power Budgeting <?>
        Capabilities: [420 v2] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
                AERCap: First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
                        MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
                HeaderLog: 00000000 00000000 00000000 00000000
        Capabilities: [600 v1] Vendor Specific Information: ID=0001 Rev=1 Len=024 <?>
        Capabilities: [900 v1] Secondary PCI Express
                LnkCtl3: LnkEquIntrruptEn-, PerformEqu-
                LaneErrStat: 0
        Kernel driver in use: nvidia
        Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia

多くの情報が出力されていますが重要なのは以下の2行だけです。

LnkCap: Port #0, Speed 8GT/s, Width x16, ASPM L0s L1, Exit Latency L0s <512ns, L1 <16us
LnkSta: Speed 2.5GT/s (downgraded), Width x16 (ok)

LnkCapは能力(Capability)を示し、上記の例では最大8GT/sの転送速度、最大x16レーンのリンクをサポートしていること示しています。転送速度は1レーン、片方向あたりの速度が出力されており、8GT/sはPCI Express 3.0(Gen3)を意味します。

LnkStaは状態(Status)を示し、上記の例では2.5GT/sの転送速度(ダウングレード状態)、x16レーンでリンクしていることを示しています。2.5GT/sはPCI Express 1.0(Gen1)を意味します。
最大値よりも現在値が小さい理由は、nvidia-smiの項目で示した通りです。

なお、転送速度とPCI Expressの世代の対応についてはWikipediaを参照ください。

最後に

nvidia-smiコマンド、lspciコマンドを使ってPCI Expressの世代、レーン数などのリンク状態を調べる方法を紹介しました。

前述の通り、PCI Expressのリンク速度は可変なので、GPUを動かしつつ、リンク速度を調べてみてください。(この件について、もっと良い方法があれば情報求む!)

参考資料

https://ja.wikipedia.org/wiki/PCI_Express

https://qiita.com/miyamotok0105/items/1b34e548f96ef7d40370

Discussion