Routing Stringのインプリメントもまた簡単である。例えばPhoto01の様に5段のHubが接続されている構造を考える。この場合、Depth 0のHubは0x00000というRoute StringがUS Port0から渡される。この場合Depth 0はMSBに0x00001,0x00002,....0x0000Fまでを割り振る形となる。この結果、Hub Depth 0のDS Port 1は0x00001というRoute Stringを持つ事になる。さてこのHub Depth 0のDS Port 1とHub Depth 1のUS Portが繋がっていると、Hub Depth 1には0x00001というRoute Stringが渡される。ここで、その4bit右に0x00010~0x000F0を加えたものが、Hub Depth 1のDS Port 1~Port 15のRoute Stringとなる。

Photo01: 一番上がRoot Hubということになる。ちなみにちょっと見えにくいが、Depth 0のPort 1がDepth 1のUS Portに、Depth 1のPort 2がDepth 2のUS Portに、Depth 2のPort 3がDepth 3のUS Portに、Depth 3のPort 4がDepth 4のUS Portにそれぞれ接続されている。

以下システムは同じで、Depth 2は0x00021、Depth 3は0x00321、Depth 4は0x04321がそれぞれRoute Stringとなり、そこに各々ポート毎に0x1~0xFまでを割り振る形になる。こう書くと、ではHubは現在のDepthをどうやって判断するのか?という話であるが、別に判断しなくても渡されたRoute Stringを頭から4bitづつ舐めてゆき、それが0x0であれば次の4bitを検索、そこが0x0であれば検索終了で、何回4bitシフトしたか、からDepthが判断できる。またこの方式なら、全てのDeviceにUniqueなRouteStringが割り当てられるし、かつRouteStringで一意に経路も確定でき、かつHub自身も配下のDeviceへのRoutingのHandlingが容易になる。

そのRoutingであるが、基本的にはStore & Forwardで実現することになる(Photo02)。実際PowerManagementを含む諸々のパケット判断をHubで行う必要があるし、ポート毎に4つの送受信バッファを設け、これでFlow Controlを行っている事を考えると、RoutingでわざわざCut Throughを使って無理やりLatencyを短縮させる意味は殆ど無いだろう。ただしEthernetと異なり、その動きはUpstreamとDownstreamで異なる。Downstreamの場合、Photo02左の様に受け取ったPacketを、RouteStringを参照しながらRoutingするという作業が入る(これを行うのがHeader Routerとなる)。対してUpstreamの場合は、無条件でHostに向けて纏めて送り出す形になる。なのでRoutingの必要性はなく、そのためHeader Aggregaterが配される形だ。

Photo02: 技術的にはCut Throughを使うことは可能だし、Route Stringはヘッダの比較的先頭にあるから、理論上はCut Throughを使うことによるレイテンシ短縮効果は期待できるだろうが、問題はそこまで低レイテンシを必要とするアプリケーションが無いことだろう。昨今だとEthernetでCut Throughを使うのは、HPC向けのInterconnectにEthernetを流用する場合程度で、あとはInfinibandあたりしか利用例がなかったと記憶している。

Hubが満たすべき条件、を簡単にまとめたのがこちら(Photo03)である。ここに出てくる"eight header packets"がちょっと判りにくいかもしれないので、解説したい。ここでの話はUpstream Portから受信してDownstream Portに配分する場合である。Photo02の左図の様に、HubはUpstream Portに4つ、Downstream Portにそれぞれ4つづつBufferを設けている。ここでUpstream Portが上位から連続してHeader Packetを受信し、それが全部Downstream Port 1にRoutingされるべき、なんてケースを考えよう。前提として全てのBufferは空である。この状態でHubはまずPacket Header 1~4までを受信するが、受信したら直ちにそれをDownstream Port 1のBufferにRoutingする。この結果、Upstream Port側のHeader Bufferは空になるので、引き続きPacket Header 5~8までを受信できることになる。要するにUpstream Portで正常に受信できたら、すぐさまRoutingせよ、というのがココで言っている話で、この結果として特定のDownstream Port向けのPacket Headerを最大8つまで保持することが可能、という事になる。Photo04はこれをもう少し判りやすく示したものだ。Header 1~6まで6つのHeader PacketがUpstream Portから到達しており、このうちHeader 1~5まではDownstream Port 1向けのものである。ところがDownstream Port 1はLink stateがU2になっており、現在は送り出すことが出来ない。そこで、まずHeader 1~4はRoutingされた上でDownstream Port 1のHeader Bufferに蓄えられた状態でU0 Stateになるのを待ち、Header 5はUpstream PortのHeader Bufferに引き続き残ることになる。この状態で、Downstream Portあたり最大8つまでのHeader Packetをバッファに蓄えられるわけだ。

Photo03: この内容は、Specificationの10.7.4 "Header Packet Buffer Architecture"に記載されている。

Photo04: この場合、Header 5は引き続きUpstream PortのHeader Bufferに残るが、Header 6はDownstream Port 4に送ることができる。

ただ勿論8つのBufferが全部埋まった状態では、それ以上Header PacketをUpstream Portから受け取る事ができないので、以後はDownstream PortがU0に復帰する(事で、全てのBufferの内容をDownstream Portに送り出す)か、あるいはPortがDisabledになるなどでHeader Bufferの内容を破棄するといった事が起きない限り、HubのDownstream側の動作はHold状態に陥ることになる。

(続く)