PCI Express (PCIe) for Networkers

# この記事は、カーネル/VM Advent Calendar 32日目 (2011年1月7日)の記事です。

昨年 IA Server上で動作する Vyatta という Software Router の性能測定やってた時に、ふと浮かんだ疑問が「PCIe の実効性能ってどんなもん?」

というわけで「ネットワーク屋さんがボトルネックを考える時に必要なレベル」を目指して、PCIe を調べてみました。

PCIeの特徴

特徴は色々とありますが、ネットワーク屋さんとして知っておくべき主な特徴は以下の項目と思われますので、それらを解説していきます。

  1. point-to-point接続のシリアル通信
  2. 階層構造をもったアーキテクチャ
  3. パケットベースのプロトコル
  4. ロスレス(データリンク層でのフロー制御)
  5. レーンのアグリゲーション(物理層)
  6. インバンドでの割込み処理

point-to-point接続のシリアル通信

ブリッジやスイッチファブリック、NICといったPCIeノード間は、片方向2本の配線、計4本の配線で接続されます。「PCIe 1.1 = 2.5Gbps」と言った時は片方向の帯域を表し、全二重帯域では 5Gbps となります。
また、データ信号の中にクロックを埋め込んでおり、複数配線の同期をとる必要が無くなり、高クロックでも動作が可能となっています。

レーン、リンク、ポート

また、両方向の配線計4本をまとめて「レーン」と呼び、これをアグリゲーションして、ノード間のリンク速度を2倍、4倍 … 32倍と増やしていく事が可能となっています。

リンクの帯域はPCIe 1.1で片方向2.5Gbps 、双方向で5.0Gbps、PCIe 2.0ではその倍となります。

さらに物理層では「8b/10b符号化」を使って転送しているのでデータ帯域は0.8倍(2.0Gbps=0.5GBytes/s)となり、符号化オーバーヘッドを考慮した理論帯域は以下グラフのようになります

このグラフを見るとイーサネット(1,10Gbps)と並べると最低限必要な帯域として
・1Gbps = PCe1.1 x 1
・10Gbps = PCe1.1 x 8, PCIe2.0 x 4
という事がわかります。

bandwidth

※ アグリゲーションに伴うオーバーヘッドは後ほど「レーンのアグリゲーション(物理層)」にて説明します。

階層構造をもったアーキテクチャ

以前のPCIではロジカルなプロトコルや物理的な実装方法が明確な階層構造になっていなかったので、速度アップするのも考慮点が多く大変でした。
PCIeでは、以下のように物理層、データリンク層、トランザクション層と分かれているので、物理層だけの変更で 2.5Gbps -> 5Gbps といった速度向上が可能となっています。

PCIe Layer

※ 各レイヤ(層)の動作概要はのちほど。

パケットベースのプロトコル

ソフトウェア層からもらったデータにそれぞれの層でヘッダを付けて渡していく、TCP/IP over Ethernetと同じような構造となっています。

PCIePacket

性能を考える際には当然これらのオーバーヘッドを考慮する必要があり、データ・サイズ(バイト)毎のヘッダオーバーヘッドを考慮した実効帯域が下の表となります。

Throughput

なお、データ・サイズはチップセットやノード(NIC等)に依存するらしく、ネットワーク系では64Bが使われる事が多いらしいです。。。

「らしい」というのは「PCIe オーバーヘッドは 20% …」とか「ペイロードサイズを64Bとすると…」という資料を見かけた事があるというだけで、調べきれてません。

色々調べてもどういう実装(チップ等)が多いかの情報が見当たらないので、情報を持つ識者はぜひコメント頂けるとありがたいです。m(_ _)m

※ これを聞きたくてBLOGを書いた、というのが実情だったり。

トランザクション層

PCIeのトランザクション層はメモリからNIC等、End to Endの通信を指し、通信要求の出し側・受け側により、各エンドをリクエスタ(要求を出す側)コンプリータ(要求を受ける側)と呼びます。

ECRC(End to End CRC) によるエラー検知を実施しているが、データリンク層と違いエラー検知時の動作は実装依存となっています。(オプション)

トランザクションを動作で分類すると「ノン・ポステッド」と「ポステッド」の2種類があり、さらにタイプの違いを加えると以下8種類となります。

TransactionType

「ノン・ポステッド」とは、リクエストTLP(Transaction Layer Packet)を受信したコンプリータがコンプリーションTLPを返信する、ACK付きの通信で、Writeの時はリクエストTLPに、Readの時はコンプリーションTLPにデータが含まれます。

NonPosted

「ポステッド」とは、コンプリーションTLPの無い、投げっぱなしの通信です。ACKが無い代わりにパフォーマンスはノン・ポステッドより高くなります。

ノン・ポステッドの場合、コンプリーションTLPを受信する前にリクエストTLPを送信する事が可能であり、その送信タイミングにより性能差がでるとの事です。

NonPostedFlow出典:Altera PCI Express 高性能 リファレンス・デザイン Page 5
http://www.altera.co.jp/literature/an/an456_j.pdf

データリンク層

PCIeのフロー制御はデータリンク層で実施され、End to End ではなく各リンク毎に実施されます。
例:NIC(リクエスタ) –[DLL]– PCIe Fabric –[DLL]– コンプリータ(メモリ)

また、データを運ぶパケットに加え、TLP送達確認、電力管理、フロー制御情報用のパケット等すべて含めてDLLP(Data Link Layer Packet)と呼ばれます。

フロー制御は「クレジットベース」で実施し、TLPにシリアル番号を付加して到達確認を実施します。
特に到達確認用のパケットを Ack/Nak DLLPと呼び、フロー制御情報(クレジット管理)をフロー制御DLLPと呼びます。

以下の図左は正常系(ロス無し)で、複数の SEQ# に対し受信した SEQ# 分まとめてACKする事も、1個毎にACKする事も可能です。

右は異常系(ロスあり)で、SEQ#11を受信すべきところ SEQ#12 を受信したため、受信済みの SEQ#10 NAK を送信する事により SEQ#11 からの再送を要求してます。

ACKNACK

ACKがくるまで各 SEQ# のパケットはバッファに保存する事により、ロスレスを実現しています。
また、送信可能なバイト数を表す「クレジット」が0になった時点で送信を停止し、受信側で処理したのちにフロー制御DLLPにより、増加したクレジットを送信側に通知する事によりQoSを実現しています。

レーンのアグリゲーション(物理層)

PCIeの物理層では電気的にエラー無く転送できるように以下のような処理を実施しています。

  • フレーミング
    • データリンク層からのパケットの前後に Start/End CHRを付与
    • STP = Start TLP, SDP =Start DLLP
  • 8b/10b変換(25% overhead, 実効帯域 80%)
  • スクランブル

また、レーンが複数ある場合、バイト単位で複数レーンにフレームをストライピングします。
この際、フレームの先頭(STP/SDP)が必ず最初のレーンにくるようにフレームの終わり(END後)にパディングをします。

この際、パディング(PAD)分がオーバーヘッドとなります。

Striping

インバンドでの割込み処理(トランザクション層)

ほとんど帯域面でのオーバヘッドはありませんが、PCIeでは割込み通知もデータと同じ配線を使用し、MSI/MSI-X(Message Signaled Interrupt)と呼ばれます。
MSI-Xは割込みをかけるCPU(Core)を指定できる事から、IPパケットの Source/Dest IP Addr や TCP Port により割込みするCPUを分散させる等、マルチCPU・マルチCoreでのネットワーク性能向上に欠かせない機能となっています。

なお、PCIで使用された INTx(INTA#~INTD#)型の割込みも互換性のためにサポート(エミュレーション)しています。

まとめ

PCIeによるオーバーヘッドをまとめると以下のようになります。

  • 8b/10bエンコーディングと、各レイヤのヘッダ(フレーミング)によるオーバーヘッドが一番大きい。
    • 8b/10b:実効帯域=80%
    • ヘッダ:データサイズ=64Bの場合、実効帯域=84%
  • ノン・ポステッドなトランザクションの場合、リクエストTLP送信とコンプリーションTLP受信タイミングにより実効速度が大きく低下する場合がある。
  • 複数レーンの場合、フレームサイズによってはパディングのオーバーヘッドが発生する。
  • その他シグナリング(TLP, DLLP)も同じ帯域を使用するため、多少のオーバーヘッドが発生する。

最初の 8b/10b 以外は PCIeにてどのようなデータサイズを使用するか、リクエストTLP送信タイミング等実装に大きく依存しますが、市販のNICの実装状況に関しては調査しきれていないのは前述の通りとなります。

なので 64Bデータを使用していると仮定して 80% x 84% = 67.2% を最大実効帯域とみて余裕をもったサイジングをし、NICやドライバによる性能差等の切り分けを始めるのが良いかと思います。

ちなみに67.2%とは、PCIe 1.1 (2.0) の場合、片方向 1.68Gbps (3.36Gbps) となります。

というわけで簡単ですが、PCI Express (PCIe) の概要解説でした。

実装に関して情報をお持ちのかた、ぜひコメントや Twitter @ebiken へのメッセお願いします~ m(_ _)m

参考文献

blogebikenme について

http://twilog.org/ebiken : Interested in Virtualization, IP networking and performance tuning. But most of the time drinking wine or Belgian beer.
カテゴリー: Performance パーマリンク

PCI Express (PCIe) for Networkers への1件のフィードバック

  1. terrasense より:

    わたけんさんによる payload Size 確認方法等の解説

    ・デバイスごとの最大ペイロードサイズ = lspci -xxxxvvvv でみれる
    ・コントローラのスペックシートにたいてい書いてある
    ・Read に対する Completion を分割することを許していて… 64B 単位で区切られる
    etc.

    詳細はこちらに書いて頂きました。ありがとうございます!
    http://d.hatena.ne.jp/wataken44/20110111/p1

コメントを残す

コメントを投稿するには、以下のいずれかでログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中