NVIDIA製GPUのPCI Expressのリンク速度を調べる(Linuxの場合)
はじめに
昨今では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段階で実行するのがオススメです。バス番号を指定せずに、全デバイスの詳細情報を出力することもできますが、出力が膨大すぎて見づらいです。
-
lspci
コマンドとgrep
コマンドを組み合わせてバス番号を調べる。 -
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を動かしつつ、リンク速度を調べてみてください。(この件について、もっと良い方法があれば情報求む!)
参考資料
Discussion