# RoCE: [RDMA/RoCE Solutions](https://mellanox.my.site.com/mellanoxcommunity/s/article/rdma-roce-solutions) 便利リンク集。ここから色々なリンクに飛べる。 # ROCE: [RECOMMENDED NETWORK CONFIGURATION EXAMPLES FOR ROCE DEPLOYMENT](https://enterprise-support.nvidia.com/s/article/recommended-network-configuration-examples-for-roce-deployment) リンク集要素が強い。Lossy/Losslessなどの要求の比較を表にしたページ。 Lossyファブリックは最もシンプルなネットワークである。ネットワーク側での制御は一切行わず、クライアント側がECNサポートすることで制御を行う。ただし、ネットワークがECNをサポートしていることが求められる(必須かは不明)。 Lossy + QoS。PFCを用いない構成。QoSでの制御を行う。 Loesslessファブリック。PFCを用いる。これは大規模なパフォーマンス環境に必要で、PCIe側からのバックプレッシャーを受けるシステムに有効。多分、ストレージへのトラフィックを捌ききれない、ということか? # ROCE: [ROCE CONFIGURATION FOR CISCO SWITCHES](https://enterprise-support.nvidia.com/s/article/roce-configuration-for-cisco-switches) 1行1行ちゃんと読むことを推奨。最小かつ凝縮されている。キーワードレベルまでちゃんと追うこと。(例えば、RED with ECNが使われている、など。) # ROCE: [NETWORK CONSIDERATIONS FOR GLOBAL PAUSE, PFC AND QOS WITH MELLANOX SWITCHES AND ADAPTERS](https://enterprise-support.nvidia.com/s/article/network-considerations-for-global-pause--pfc-and-qos-with-mellanox-switches-and-adapters) PFCではないPAUSEフレームは802.3xで定義されているflow controlの仕組みである。受信側が溢れそうな時に送信側に対して一定時間待機するようなPAUSEフレームを創出し、送信側は一定時間送信を止める。 これは幾つのかの欠点ある。最も致命的なのはあらゆるQoSのパケットをPAUSEすることである。つまり、異なるQoS制御、異なる要求のフレームが含まれても全てを止めてしまうことだ。特に複数のスイッチが存在する場合、その輻輳に関係のない通信が巻き込まれてしまう可能性もある。(訳註:ここは厳密な具体例がわからない) IEEE 802.1Qbb PFCはこれを8クラス毎に拡張したものである。VLAN タグ(IEEE 802.1p)内のビットを使い、対象クラスに向けてPAUSEをする。 ここで注意すべきこととして、PFCとGlobalPAUSEは同時にEnableすることはできない。 PFCとGlobal PAUSEは共存可能と言った。しかし、同時に使われるのは避けるべきだ。なぜならグローバルのポーズは全てを止めてしまうからだ。 QoSについて述べる。ネットワークはQoSがない場合、すべてのフレームの優先度を区別せず、1つのバッファのみですべてのトラフィックが管理される。QoSを用いるとフレームは区別できる。PFCを有効にすべきなのはRoCEを通しているQoSのTCである。 ここで、Weighted Round RobinはETSと言える。なぜならトラフィッククラス毎の重みに基づいたラウンドロビンがなされるからである。 # ROCE: [INTRODUCTION TO RESILIENT ROCE - FAQ](https://enterprise-support.nvidia.com/s/article/introduction-to-resilient-roce---faq) ConnectX-4以降を推奨される。(なぜ?) Resilient RoCEはフローコントロール、つまり、PFCが有効でないネットワーク上でのROCEトラフィックを流すものである。 ネットワーク上ではECNがMUSTである。PFCが有効であることが望ましい(SHOULD)がMUSTではない。ECNのみが用いられる場合、適切にPFCを有効にした場合と異なりロスが発生しうる。 # ROCE: [UNDERSTANDING ROCEV2 CONGESTION MANAGEMENT](https://enterprise-support.nvidia.com/s/article/understanding-rocev2-congestion-management) ネットワークの輻輳はスイッチが多ポートであり、Many-Oneの通信が発生する限り防げないものである。そこでスイッチにはバッファが入っている。ロスレスのネットワークとは、バッファが溢れないようにフローを制御する仕組みそのものである。しかし、`輻輳制御とはうまく行わないと逆に輻輳を広げる`ことに注意しないとならない。 `ここで図を見る。`1つのシナリオでは、既に100%を受信しているポートGがあり、新規に他のスイッチのクライアントがG宛のトラフィックを吐きたいとする。この時スイッチ間でフロー制御を送りF側のスイッチにバックプレッシャーをかける。この結果、スイッチ内の処理が処理され次第、Fが処理される。 一方で、このケースのままそのクラスを使う(注意:ここではVoQは考慮されていない)トラフィックがそのスイッチを通過しようとした場合、F->Gでバックプレッシャーを受けているクラスではトラフィックが溢れてしまう。 このような問題を解決するためにECNが使われている。なぜなら、QoSだけではなく輻輳制御が必要とされている。AからBのポートは適切にECNによって帯域を下げ、他のトラフィックが通過しようとすればさらにECNで帯域を下げる。これによってPFC発生なくE2Eでの帯域制御が行われる。 # RoCE - ECN: [Introduction to Congestion Control for RoCE](https://docs.broadcom.com/doc/NCC-WP1XX) Broadcomのホワイトペーパー。ECN入門として最適。 ## はじめに 少なくともEhternetを使っている以上、リンク以上のトラフィックがリンクに集中することがある。Congestionと呼ばれる。これを輻輳(Congestion)と呼び、そのための輻輳制御(CC: Congestion Control)がある。 輻輳制御というと何をイメージするだろうか?TCP輻輳制御が最も最初に思い浮かぶだろう。しかしAI/MLなどのデータセンタでは異なる輻輳制御が行われている。 CCを語るにあたり用語を定義する。 - Utilization(利用率): SrcからDestに対する利用率。アプリケーションデータレート。 - Waste(無駄?うまく訳がない): 輻輳制御のためのパケット・ヘッダなどで消費されるリソース。 - Buffer consumption(バッファ使用率): NW装置の消費するメモリ量。 - Latency(遅延): srcからdstまでの時間 - Fairness(公平性): そのサービスを使っているの利用者が得られるサービスのバランス。 帯域制御自身は古典的なもの。TCPに注目すると以下のような変化があった。 - 高密度で構造的なネットワークになっておりリンクが広いネットワーク(=つまり、最近のSpine/Leaf NWと捉えていいだろう)において、小さいRTT。つまり、バッファリングは最小の利用量であって欲しい。 - アプリケーションの待ち時間が最小であるようなトランスポート 尚、ECNの中では次のような言葉が使われる。 - RP: Reaction Point: 送信者。つまり、輻輳について制御(reaction)が必要な人) - CP: Confestion Point: 輻輳を検知したポイント。スイッチなど。つまり、ECNを`0b10 -> 0b11`にする人 - NP: Notification Point: 受信者。つまり、CPで`0b11`になったのに気がつき、(RoCEなら)CNPを返す人 ## RoCE, RDMA まず、RoCEは以下の3種類のメッセージをサポートする。 - Messages : RDMA送信 - Remote memory access: RDMA送受信 - Atomic なremote memory access – 一貫性のあるRDMA操作 これらの機能をHWにどこまで実装させるかという議論は今も続いているだろうが、RoCE NIC(RNIC: RoCE対応NICとしていいだろう)を使うことで以下のようなメリットがある。 - アプリケーションのバッファをゼロコピー転送 - カーネルバイパス - メモリアクセスと同じようにNICにアクセスできる RoCEの中心となるのはP2Pの通信である。そして、セグメンテーション・信頼性・シーケンス保証・エラー訂正などをオフロードされたRNICによって実現されるのが一般的だろう。 RoCEv2ではCNP(輻輳通知パケット: Congestion Notification Packet)が定義されている。 ECNとは受信側がCongestion Experienced (輻輳検知: CE)を受け取っパケットに含まれるものであり2つの区間でマーキングされうる。`1: 送信側より先の中継スイッチ`か`2: 受信側のNIC`である。ここで、RoCEv2ではマーキングの仕組みとCNPだけを定義していることに注意すべきである。 RoCEv2では以下の内容は定義されて`いない`。 - ECをマークするタイミング(どのキューの深さで?どんな確率で?) -aECNを受け取った後にCNPを生成するタイミング - CNPを受信した時のレートの調整方法 RoCEv2のCNPフレームについて確認しておく。IPとしてはUDPのフレームでIBとして送られる。BTH: Base Transport Header. (IB トランスポート)は以下の値にする。 - Dest QPN - Op: 0b10000001 - PSN = SR = M = 0 - P_KEYはマークされてきたパケットのBTHのものと同じにする ## PFC Ethernetのフロー制御とPFC(優先フロー制御: priority flow control)がある。しかし、PFCはECNに比べると無駄以外の効果は低い。 PFCを説明する。これは、8つのトラフィッククラスのフローを制御する仕組みである。この閾値を適切に設定すればリンク上のパケットドロップを防ぐことができる。別の言い方をすると、PFCとは`ロスレスTC`を実装できる。 ただし、PFCとはそのTCの全てが抑制されてしまう。つまり、実際に高負荷すぎる通信`以外も抑制`してしまう。これを輻輳拡散(congestion spreading)と呼ぶ。Fig3でこれを説明しよう。 1. NIC B、C、D、FがNIC Gに対する`N:1 incast`を通信を行う 2. NIC GへのEgressQが埋まる 3. Dest側のSW2はそのTCに関する全ポートのフローにバックプレッシャーをかけ、NIC G宛の可能性があるパケットを`他のフローを含めて`受入れを停止させる 4. すなわち、送信元から送信先のスイッチリンクにおいてそのTCの通信ができなくなる 5. 装置2からのバックプレッシャーを受けて本装置1は全ポート本装置2へ向かう`可能性のあるパケット`の受け入れができなくなる 6. これによって同一SW内の折り返しであり、無関係であるはずのNIC AからNIC Eへのパスのトラフィックも抑制される PFCは以下のことからネットワークのパフォーマンスを定価させる - キューがいっぱいになることによる待ち時間は非常に長い(間違っているかも:Flow control turnaround latency compounds the already high queuing delay) - フロー制御によりキューイング発生するのですでに高いキューイング遅延をさらに悪化させる - 混雑していないフローが混雑したフローの犠牲になり公平性が失われる PFCは瞬間的なバーストに対しては効果的な対応となることもあるが、定常的な高負荷に対して適切に動作しないだろう。PFCとは高いコストではあるがセーフティーネットを提供するものである。つまり、`PFCとは低レイテンシを提供しないし、高い利用率を提供しない`。 ## DCTCP BroadcomのTrident, Tomahawkといったチップは非常に高い帯域を出せますが、バッファリング容量は高くはありません。DCTCP(DataCenter TCP)は輻輳管理を持ったTCPで高い利用率と効率を保ちバッファを多く使用しませんし、レイテンシも短いです。TCPの基本的な考え方はネットワークパスそのものをタイマーとして捉える仕組みです。 DCTCPの制御方法について述べる。 - NW装置が制御に関わる。装置はキューに入っているパケットのうち、staticに設定された閾値よりも長いパケットをマークする。従来型TCPと違いでも、AQM(Active Q Management)はあったが以下の点で異なる。 - 1: その瞬間のキューの長さを用いる。古典的なAQMでは平均的な長さを用いる。 - 2: 全てのパケットをマークする。古典的なAQMではマークするかしないかのどちらかである。 - 受信側はすべてのECN CEパケットに対してECN-Echo指示を(ACK時に)送信します。従来のAQMでは、送信者がECN-Echoを承認するまで、単一のECN CEに対してECN-Echoをマークしました。マーキングは、従来のAQMではまれなイベントであると想定されているが、DCTCPでは一般的なイベントである。 - DCTCP送信者はTCPと同じ方法で送信ウィンドウサイズを増加させる(スロースタート) - DCTCP送信者は送信パケットに対するECNエコーの受信率の移動平均を使用して、輻輳が発生する確率`CP`を計算する。そして、送信ウィンドウサイズを`(1 - CP / 2)`だけ小さくする。 このようにDCTCPは輻輳がないならウィンドウを減らさず、服装が発生したらウィンドウを半分にします。このかなり極端な調整をDCTCPは行います。DCTCPは輻輳を送信者に適切に伝え、高速に調整を行わせます。DCTCPがバッファ消費量を少なくするための工夫です。(recuraki: 徐々に調整などをするとバッファが徐々に溢れなくなる、ような挙動であるが、一気にカットオフするのでバッファの溢れを一旦なくせる) ## RoCE TCPとRoCEの違いをまず述べる。 - TCPはストリームを管理するが、RoCEは`メッセージベースで制御`を行う - TCPはソフトウェアベースで管理されるだろうが、RoCEは`ハードウェアで実装`される - TCPはインフライトウィンドウを制御するのに対して、RoCEは`伝送レートの制御`を行う `BroadcomのNICでは`(つまり汎用的なものでないことに注意)。`DCQCN-p`はキューがある閾値を超えると直線的に増加するマーキング確率を用いてマーキングを行う。`DCQCN-d`はDCTCPのようにキューが一定を超えると100%の確率でマーキングする。という違いがある。決定論的なECNマーキングポリシーを使用します。この両者はとても似ている。しかし、ECNマーク数 = CNPの数が大きく異なるので制御のされ方が全く異なる。`DCQCN-p`は一部のパケットだけがECNマークされるのでCNPのマークは少ない。このため、キューの負荷は適当なバランスが行われるまで伸びていく。一方で`DCQCN-d`はCNPが一気にマークされるので、(負荷はある程度一気に下がるが)NICの負荷は高くなる。 そもそもなぜ独自の実装を作っているか?DCQCNには幾つの欠陥がある。これを述べている主要な論文として“Congestion control for largescale rdma deployments”がある。輻輳制御は大きく2つの操作を行う。1:輻輳が発生していないならレートを上げる と 2:輻輳が起こっているならレートを下げる であり、これらは別々のポリシで制御される。以下で詳細に見ていくので用語を定義しよう。 - RC – Current transmit rate(現在レート) - RT – Target transmit rate(目標レート) ここで、CC(輻輳制御)が行われるタイミングは45usがデフォルト(変更可能)となっており、極端に敏感な時間ではない。この期間ごとに届いたCNPパケットの数をカウントして適切な制御を行う。BroadcomのNICではフローごとにこの値をstatしており、この処理はハードウェアに完全にオフロードされている。 ## DCQCN: RoCEによる送信レート増加 DCQCNによるウィンドウ増加ではなくて純粋なレートコントロールを行っている。これはEEE 802.1Qau Quantized Congestion Notification (QCN) に従う。 送信レートの増加は(自分の物理帯域の最大に立っていているのでなければ)CNPを受け取った瞬間から開始される。まず、送信レート増加の2つの状態を述べる。 - 1: 高速リカバリ(Fast Recovery): まず、目標帯域を従来(つまり、CNPを受け取る前の帯域)にする。その後、今の帯域を`(RT+RC)/2`にしていく。つまり、今の帯域と目標帯域の真ん中に送信レートを変更する。高速リカバリは3回行われ、次の2:アクティブ増加に移る。もし高速リカバリが3回行われないのであれば、帯域を落とした後に高速リカバリが行われる。もし高速リカバリをずっと続けるならば、これは元の帯域に対して`1/2 + 1/4 + 1/8....`をしていくので元の帯域には戻らない。 - 2: アクティブ増加(Active Increase): 高速リカバリの後、目標帯域RTを`RT = RC + RAI`にして`RC = (RC+RT)/2`にする、を繰り返す。これはCNPを受け取るか、リンク帯域にぶつかるまで繰り返す。RAIは静的な値である(と思う)つまり、徐々に目標帯域をあげていき、現在の帯域とその値の真ん中に値を設定する。 ということらしい。2はわざわざRTを設定しなくても`RC+RAI/2`でいいのでは?と思うが、実装的に`(RT+RC)/2`部分を同じロジックで回したいからだろう。 ## DCQCN: RoCEによる送信レートの抑制 では、CNPを受け取った時のレートはどのように減少させるかを考える。輻輳割合(CP: congestion probability)を導入しよう。 先ほど述べた`DCQCN-p`と`DCQCN-d`でアプローチは異なる。`d`は100%にマーキングされるので、送ったパケットに対してどのくらいのパケットがマーキングされたかがわかる。常に溢れそうなキューに入ったら100%にマーキングされるし、とても局所的なバーストに巻き込まれたなら1パケットだけがマーキングされるかもしれない。そこで、ある周期において送信したパケットと受信したCNPの比率をCPとして計算する。これは0-1の割合で示される。`p`は確率的マーキングであったので考え方が違う。まず、`F`はCNPを受信したら1, CNPを受信しなかったら0にする。そして、重み`g`を用意しておき、CNPを受け取るたび、`F=F*g`とする。つまり、CNPが(確率的に)たくさんマーキングされていたらFは大きくなる。 いずれにしても以下の通り計算される。 - F = CNP受信数 / Txした数 - CP = (1 – g) × CP + F × g - RT = RC - RC = RC × (1 – CP / 2) つまり、 - CPとはパケットが輻輳する移動平均の確率である(0-1) - RTは今の値になる(つまり、送信レート増加の際のターゲットになる) - CPが最大である場合、レートは半分になる ## BroadcomのDCQCNに対する工夫 NICのReaction Pointの各種タイマーは適当なジッタを入れる。そうしないとネットワーク全体が調和して制御をした際に、1:大きなバーストの発生 2:PFCの発動を防止できる。また、`Active increase`はあまり素早く帯域を使いきれない。そこでBroadcomはCNPを受信していない期間が長ければ増加(RAI)を大きくして素早く帯域を使えるようにしている。