PCIe と高速インターコネクト

このページの目次

Gen 4×4 SSD を Gen 4 マザーボードに接続しても、必ずしも約 8 GB/s の帯域を独占できるわけではありません。スロットにはレーンが 2 本しか接続されていない場合や、スイッチチップやチップセットを介して他のデバイスとアップリンクを共有している可能性があります。パフォーマンスを説明するには、実際のトポロジをまず図示し、リンクレート、符号化後の帯域幅、トランザクションオーバーヘッド、およびデバイスの処理速度を区別する必要があります。

確認すべき問題この記事の入り口重要な定義
x4/x16 は何を数えているのかレーンとリンク1つのレーンには双方向の差動チャネルがあり、複数のレーンで1つのリンクを構成する
各世代でどれくらい伝送できるかレートと符号化単方向、10進数の GB/s、オーバーヘッドを控除済みか否か
なぜ複数のデバイスが同時に遅くなるのかトポロジと共有アップリンク各ホップにおけるリンクとトラフィックの方向
なぜ読み書きでパフォーマンスが異なるのかTLP と在途要求posted write、read completion、レイテンシと並行性
デバイスがなぜ低速化したり検出されなかったりするのかトレーニングと列挙電気的状態、リソース割り当て、ドライバと DMA

レーンは物理的な並列度、Generation はリンクレートのレベル

1つのレーンには、1対の送信差動線と1対の受信差動線が含まれており、2つの方向で同時に動作します。x4 リンクは4本のレーンを組み合わせて伝送しますが、これは4つの独立してアドレス指定可能なデバイスではありません。x16 の高速信号は合計 16×4=64 本の導線を持ちますが、電源、グランド、参照クロック、およびサイドバンド制御は含まれません。

スロットの機械的な長さ、電気的な配線、および現在ネゴシエートされた幅は異なる場合があります。x16 の長いスロットでも x4 しか接続されていない可能性があります。マザーボードは、別のデバイスを挿入した後にポートリソースを再割り当てすることもあります。 bifurcation(分割)をサポートするルートポートは、1組のレーンを複数の独立したリンクに構成できますが、パッシブなアダプタボード自体が PCIe スイッチ機能を自然に実現するわけではなく、ファームウェアとハードウェアの両方が対応する分割をサポートする必要があります。

帯域幅はまず単方向で宣言され、その後対応する世代のオーバーヘッドが差し引かれる

以下の Gen 1~5 の数値は、ライン符号化を差し引いたものですが、⁠トランザクションパケット、リンク制御、その他のオーバーヘッドは差し引かれていません⁠。GB は 10⁹ バイト(10進数)を使用し、GiB ではありません。

ジェネレーション公称伝送レート信号/符号化概要1レーンあたりの単方向予算x16 単方向予算
Gen 12.5 GT/sNRZ、8b/10b0.250 GB/s4.000 GB/s
Gen 25 GT/sNRZ、8b/10b0.500 GB/s8.000 GB/s
Gen 38 GT/sNRZ、128b/130b0.985 GB/s15.754 GB/s
Gen 416 GT/sNRZ、128b/130b1.969 GB/s31.508 GB/s
Gen 532 GT/sNRZ、128b/130b3.938 GB/s63.015 GB/s
Gen 664 GT/sPAM4、FLIT/FEC原始ビットレート換算で 8 GB/s、FLIT オーバーヘッド未控除原始 128 GB/s、FLIT オーバーヘッド未控除
Gen 7128 GT/sPAM4、FLIT/FEC原始ビットレート換算で 16 GB/s、FLIT オーバーヘッド未控除原始 256 GB/s、FLIT オーバーヘッド未控除

例えば Gen 4×4 の場合:16×10⁹×128/130×4/8≈7.877×10⁹ バイト/秒。フルデュプレックスとは、もう一方の方向にも同様の能力があることを意味し、双方向と 15.754 GB/s を1回の単方向 SSD 読み取りの上限として扱うことはできません。

Gen 6 の 64 GT/s は PAM4 を使用し、1つのシンボルで2ビットを伝送します。シンボルレートは公称 GT/s と NRZ のように1対1で対応しなくなります。固定の 256 バイト FLIT を採用し、誤り訂正などのメカニズムを追加しているため、128/130 を掛けるだけでは最終的な有効帯域幅とは言えません。1つの FLIT の TLP 領域には複数のトランザクションパケットを格納でき、領域内にはトランザクションヘッダーやパディングが含まれる可能性があり、アプリケーションの純粋なペイロードは FLIT のサイズ全体に直接等しくなりません。PCI-SIG:FLIT、PAM4、および FEC

PCIe 7.0 の 128 GT/s 仕様は 2025 年 6 月にリリースされました。仕様のリリース、コントローラのサポート、量産マザーボード、および特定のマシンでの実際のリンク能力は異なる状態であり、仕様の世代だけで現在のデバイスの利用可能なレートを推測してはいけません。PCI-SIG:PCIe 7.0 リリース

トポロジ:各セグメントはポイントツーポイントだが、システム全体ではボトルネックを共有する可能性がある

Root Complex はプロセッサ/メモリシステムを PCIe 階層に接続し、Root Port は対応するポートです。Endpoint はデバイス機能を提供します。Switch はアップリンクとダウンリンクポートで階層を拡張し、トランザクションをルーティングしますが、すべてのダウンリンクポートが個別に完全な独占アップリンクを得るわけではありません。

Root PortホストメモリへPCIe Switch経路に応じて転送Gen 4 ×4共有アップリンクSSD AGen 4 ×4SSD BGen 4 ×42つのダウンリンク x4 が、1つのアップリンク x4 を x8 にするわけではない2つの SSD がホストへの同方向アクセス:合計は依然としてアップリンクの符号化後上限約 7.877 GB/s に制約されるパケットオーバーヘッドを無視した教育的トポロジ;デバイス間 P2P、スイッチパス、およびプラットフォームルーティングポリシーは個別に分析する必要がある。

2つの SSD がそれぞれ Gen 4×4 のダウンリンクを持ち、Gen 4×4 のアップリンクを共有し、同時にホストメモリへ 5 GB/s で転送する場合、合計必要量は 10 GB/s となり、アップリンクの符号化後上限である約 7.877 GB/s を超えています。他のオーバーヘッドを無視しても、各 SSD が長期的に 5 GB/s を維持することは不可能です。実際の割り当てはアービトレーションとトラフィックに依存し、必ずしも厳密に半分ずつになるとは限りません。

チップセットの下に接続されたストレージ、ネットワーク、USB もホストインターコネクトを共有する可能性があります。Intel DMI や異なる AMD プラットフォームのチップセット接続には、それぞれ独自の幅と実装があり、「DMI は本質的に PCIe x8 である」などと固定して描いたり、AMD チップセットのアップリンクを Infinity Fabric と直接同一視したりすることはできません。特定のプロセッサとマザーボードのブロック図を確認することが、あるブランドの統一されたレーン数だけを暗記するよりも信頼できます。

P2P トランザクションはローカル階層で転送される場合もあれば、プラットフォーム、ACS、IOMMU、またはドライバのサポートにより制限される場合もあります。同じ Switch が見えていても、2つのデバイス間のすべての DMA が直接実行できるわけではありません。カーネル内の PCIe ドライバモデル

3層プロトコル:リンクが正しく受信しても、デバイスがビジネスロジックを完了したわけではない

レイヤー主な責任教育的に混同されやすい境界
Transactionメモリ読み書き、設定アクセス、メッセージなどの TLP要求の完了とデータの永続化は同義語ではない
Data Link隣接リンク間の信頼性のある伝達、フロー制御関連メカニズムエンドツーエンドのビジネス確認ではない
Physicalシリアル送受信、トレーニング、符号化、および電気的リンクトレーニングの成功がドライバの準備完了を意味するわけではない

一般的な非 FLIT モードでは、リンク層はシーケンス番号、LCRC、および ACK/NAK リプレイメカニズムを使用します。Gen 6 FLIT モードでは保護とリプレイの単位が異なるため、古いパケットフォーマットをそのまま一般化することはできません。誤り訂正/リプレイも帯域幅を消費するため、繰り返し修正可能なエラーを「パフォーマンスに影響がない」と単純に扱うべきではありません。

メモリ書き込みは通常 posted request であり、対応するトランザクション Completion の返却を要求しません。メモリ読み込みは non-posted request であり、Completion の返却が必要で、通常はデータも伴います。Completion がないからといって、書き込みがすべての操作を無秩序に飛び越えられるわけではなく、さらに SSD への書き込みが完了したことを意味するわけではありません。レジスタ読み戻し、DMA バリア、デバイスコマンドの完了、およびストレージの永続化は、それぞれ異なる保証レベルに属します。

RequesterCompleterMemory Read、Tag 0、256 B を要求Memory Read、Tag 1、256 B を要求Completion with Data、Tag 0Completion with Data、Tag 1メモリ読み込みには Completion の返却が必要:往復レイテンシをカバーするために複数の未完了の要求を維持するTag は未完了の要求のマッチングに使用されます。1つの要求は複数の Completion で返される可能性があり、返却順序と制限はプロトコルに従って処理されます。

Requester は Tag を使用して未完了の読み込み要求を管理し、1つの要求が複数の Completion に分割される場合があります。読み込みスループットはリンクレートだけでなく、在途状態にできるデータ量と往復レイテンシにも制限されます。32 筆を許可し、各筆が 256 B、平均往復レイテンシが 2 μs と仮定すると、理想的なウィンドウ上限は約 32×256/2μs=4.096 GB/s となり、リンクの利用可能帯域幅がそれ以上にあっても埋まらない可能性があります。並行性を増やすことで改善できますが、Tag、バッファ、クレジット、デバイス、およびメモリの制限にも直面します。Intel:PCIe スループットに影響を与える要因

MPS はトランザクションパケットの最大データペイロードを制限し、MRRS は読み込み要求の最大サイズを制限します。これらは同一のパラメータではありません。より大きな要求でも複数の Completion に分割される可能性があります。これらの値を調整するには、パス全体とデバイスの能力に適合させる必要があり、「一律に最大値に設定すれば最速になる」とは限りません。

リンクが空いていてもデータを待つ理由は?

既定の32要求・2 μsでは窓予算4.096 GB/s。並行数を増やすとリンク上限に達し、RTTを増やすと折点が右へ動く。これは読出しCompletion窓であり、NVMe業務読出しのPCIe方向そのものではない。

図を準備しています
リンクが空いていてもデータを待つ理由は?

読出しはCompletionで窓を再利用するため、窓/RTTがリンク容量より先に制限になる。

電源投入からドライバ使用まで:トレーニングと列挙は2段階で理解する

物理リンクは受信検出、トレーニングシーケンス、幅/レートの確立、および対応するイコライゼーションを経て利用可能な状態に入ります。これらの状態遷移は LTSSM で記述されることが多いです。両端の最高能力、配線、ファームウェアポリシー、および信号品質が最終結果を決定し、より狭い幅やより低いレートに降下する可能性があります。リカバリ状態は再トレーニングにも使用されます。

その後、ファームウェア/OS は設定スペースを通じてデバイスとブリッジを検出し、バス番号とリソースウィンドウを割り当てます。BAR はデバイスが必要とするアドレス空間の領域を記述し、ホストがアドレスを割り当てた後に、ドライバがマッピングし、デバイスの規則に従って MMIO にアクセスできます。BAR は通常のメモリスティックではなく、物理デバイスを「RAM にコピーする」ものでもありません。

デバイスが DMA を実行するには、バスマスター能力、正しいマッピング、IOMMU の権限、およびドライバの同期が必要です。リンクが L0 にあり、lspci でデバイスがリストされていても、データ転送が行われない場合は、ドライバ、リソース、または DMA の設定に問題がある可能性があり、必ずしもスロットの交換が必要というわけではありません。IOMMU と DMA API

物理設計は単一の等しい数字の羅列だけを暗記してはいけない

PCIe シリアル受信は CDR を介してデータからタイミングを復元しますが、多くのプラットフォームでは参照クロックを提供し続けています。「クロック埋め込み」は、基板に REFCLK がないことを意味しません。Common Clock、SRNS、SRIS は異なる参照方式であり、両端の能力と SSC 設定と一致させる必要があり、現在すべてが SRIS を採用していると断言することはできません。Intel:SRIS の適用背景

交流結合は通常、送信パスに合わせて配置され、各方向に対応する送信端があります。リンクの両端に機械的にキャパシタセットを追加しないでください。キャパシタ値、位置、差動インピーダンス、損失、ビアスタブ、および長さのばらつきの要件は、目標仕様、パッケージ、およびベンダーの配線ガイドラインに基づいて決定する必要があります。内部スキューとレーン間スキューは異なる制約であり、「すべての P/N は 5 mil 未満でなければならない」と一律に書くのは条件が不足しており、より重要な損失予算を隠蔽します。

Redriver は主にアナログ信号の損失を補償し、Retimer はさらにクロック/データ復元と再送信を行います。両者は消費電力、レイテンシ、互換性、およびトレーニングサポートが異なり、アンプを1つ追加するだけでリンクを無限に延長できるとは考えられません。継続的なリターンプレーン、リターンパス、およびコネクタの遷移が基本です。

NVMe、ReBAR、CXL はそれぞれ PCIe 上に何を追加するのか

NVMe はストレージコマンドとキューモデルであり、PCIe は一般的なローカル転送基盤の一つです。NVMe over Fabrics では、他のネットワーク転送も使用できます。マルチキューにより、異なる送信者が競合を減らし、並行性を維持できますが、仕様で表現できるキュー数/深さが、各コントローラが上限を実装していることを意味するわけではありません。ディスク読み込みはビジネスセマンティクス上「読み込み」ですが、コントローラがデータをホスト RAM に送信する際には通常 PCIe Memory Write を送信するため、ビジネス方向とトランザクションタイプを混同してはいけません。Intel:I/O データフローの例

Resizable BAR は、デバイスがサポートするサイズから BAR ウィンドウを選択できるようにします。より大きなウィンドウは、VRAM ウィンドウの再マッピングなどのオーバーヘッドを削減する可能性があります。256 MiB は一部の古い GPU の一般的なウィンドウサイズですが、すべての PCIe BAR の統一された上限ではありません。ReBAR はレーン帯域幅を自動的に向上させるわけでも、すべてのコピーを削減する保証もありません。ファームウェアアドレススペース、GPU、ドライバ、およびアプリケーションが、利用可能性と収益を共同で決定します。PCI-SIG:Resizable BAR

CXL は PCIe の物理基盤を利用し、CXL.io、CXL.cache、CXL.mem などのプロトコルセマンティクスを追加し、一貫性とメモリアクセスのシナリオに役立てます。通常の PCIe デバイスは、類似のスロットに挿入しただけでは CXL メモリデバイスにはなりません。ホスト、デバイス、ファームウェア、およびソフトウェアの対応するサポートが必要です。CXL アライアンス:プロトコルと一貫性の位置づけ

GPU のワークロードが PCIe に敏感な程度は、データが VRAM に長期間滞在するかどうか、頻繁に交換されるかどうか、VRAM の容量と同期方法に依存します。「x8 に固定すると 1%~3% の損失」といった一般的な結論を排除し、GPU シリーズ名から予測するのではなく、実際のワークセットを測定する必要があります。

Linux ではまず現在のリンクを見てから、最大能力を見る

lspci -t
lspci -nn
# アドレスを上一步で確認した対象デバイスの BDF に置き換える。
lspci -s 0000:01:00.0 -vv

LnkCap(能力)と LnkSta(現在の速度/幅)に注目し、ブリッジおよびルートポートを上にたどって確認する。設定スペースの読み取りは権限制限の影響を受けるため、出力が不完全になる可能性がある。Linux PCI sysfs には、current_link_speed、current_link_width、max_link_speed、max_link_width などの読み取り専用属性も提供されているが、すべてのデバイスや設定で全フィールドが存在するわけではない。フィールドと単位は Linux PCI sysfs ABI で確認できます。

1回のアイドル時のサンプリングで負荷状態を断定しないでください。デバイスは動的にレートを下げて省電力化する可能性があり、リンクの異常が実際にデグラデーションを引き起こしている可能性もあります。負荷、AER ログ、およびパストポロジと組み合わせて分析する必要があります。ここでは読み取り方法のみを示しており、リンク制御の変更、再トレーニング、またはリソースレジスタについては言及していません。

符号化と在途ウィンドウの再計算

from fractions import Fraction as F

per_lane = F(16_000_000_000)*F(128,130)/8
x4 = per_lane*4
assert x4 == F(102_400_000_000,13)
assert float(x4)/1e9 < 8
assert 2*5e9 > x4
window_bytes = 32*256
window_rate = F(window_bytes)/F(2,1_000_000)
assert window_rate == 4_096_000_000
assert window_rate < x4
needed = x4*F(2,1_000_000)
assert needed > window_bytes
print('Gen 4×4 符号化後単方向上限:', round(float(x4)/1e9, 6), 'GB/s')
print('32 筆 256 B、2 μs 往復のウィンドウ上限:', float(window_rate)/1e9, 'GB/s')

上記は明確な仮定に基づく予算の検証のみを行い、実際の GPU、SSD、または PCIe スループットのテストは行っていません。

さらに参照する