さて、ここからが新しいというか深い話である。以前のパイプラインの構造をもう少し細かく説明したのがこちらである(Photo08)。大雑把に言って2命令のIn-Order Superscalarと以前はご紹介したわけだが、実際には9つ(ALU×7、FPU×2)のExecution Pipelineを持つと言う、まるでCortex-A57とかCortex-A72並の重厚なパイプライン構造になっている事が判る。

Photo08:In-orderのプロセッサとしては類を見ないほど重厚な構成で、とてもMCU向けとは思えない

まずLoadに関しては、FPUで64bit(Double Precision)を扱う場合と、MACユニットで32bit×32bit+64bitを行うケースでは1cycleあたり32bit×2のLoadが必要なことからDual構成となっている。これを64bit×1としなかったのは、内部のバッファは基本的に32bitのままで、特定ユニットのみが64bit幅になっている事と、DSPやFPUを使わない限り基本は32bitのLoadで足りる(から片方だけ動かせば済む)という効率性を考えてのことだろう。ALUはFull FunctionのALU0と、Limited FunctionのALU1の非対称構成だが、これで通常の用途には十分足りるだろう。Storeのみ4cycleを必要とするが、こちらはFPUやDSP命令にあわせて64bit化されている。分岐は3cycleで処理可能となっている。

単に実行ユニットを増やすのみならず、実効効率の向上にも気を配っている(Photo09)。Loadユニットで読み込んだデータはそのまま実行ユニットに廻す形でLatency 0での処理が可能とされるし、Load→AGU動作ですら1cycleのペナルティで実行可能としている。

Photo09:ALU pipeline arrangementは要するに依存関係の解消であるが、In-orderだから原理的にそう複雑な解消はできない。それもあって"cheap support"という言い方になっているとも言える(Dual issueのおかげで低コストで解消が出来るの意味にも掛けた、Dual-meaningである)

同じことはFloating Pointにも実装されている。Cortex-M7のMACユニットは基本的にCortex-M4と同じIntegerの32bit MAC演算であるが、Cortex-M7のFPUはそもそもALUとMUL/DIV/SQRTユニットが別々のPipeになっている(Photo10)。この2つのPipeを組み合わせることで、(Latencyはともかく)Throughputを1MAC/cycleまで高められるようになっているのが大きな特徴だ(Photo11)。

Photo10:注意書きにも在るとおり、Dual Precisionの場合は任意の箇所でPipeがStollする。これはLoadが32bit×2になっている事のペナルティであろう

Photo11:要するにFMULの出力をそのまま受け取ってFADDが動作する仕組みが用意されており、これを使うことでLatencyこそ8cycleになるものの、1cycleあたり1つのMAC演算が可能になるわけだ

次が分岐ユニット周り。通常MCUだと分岐予測の精度はそれほど高くなくても問題ないが、Fetchから数えると7stageもの長大なパイプラインだし、動作周波数も最大800MHzとかを想定しているから、これは真面目に分岐予測を行わないとMiss Predictionのペナルティが大きくなりすぎる。そこで64エントリのBTBを搭載して効率化に努めている(Photo12)。

Photo12:流石にCortex-Aクラスの複数分岐予測まで搭載するとコストが高くなると判断したようで、BTBのみである。とはいえ、Fetchが2d段、Predecodeが1段と結構な段数になっているのは、高速化への対応であろう

メモリアクセス周りも色々工夫されている。外部I/FがAHBベースからAXI4に切り替わったため、メモリアクセス要求を同時に複数出すことが可能になっているが、これを支えるために結構多くのBufferが実装されている。面白いのは特にデータ側であろう。Linefill Bufferはともかくとして、Store BufferでData mergeとforwardingを行っているのは、Data Cacheが無い場合に備えてのことであろうと思われる。それとは別にWrite bufferが用意されているあたりは、いかにCortex-M7がData Throughputに気を配って設計されているかを示しているようだ。その一方で、DataのPrefetchは一切行わない、という割り切り方も清清しい感じだ。

Photo13:AXI4 I/FのData側は、Readが6 outstanding、Writeが39 outstandingという極端な構成になっている。もちろんReadよりWriteが遅いからoutstandingを多めにする事は理解できるのだが、ここまで多数のoutstandingをサポートする理由を知りたいところだ

次がTCM周りである(Photo14)。以前のTCM周りの図ではもう少しシンプルにまとめられていたが、実際はこちらも結構複雑な構造であった。以前のレポートに書いたとおりTCMそのものはSSRAM(Synchronous SRAM)の形でメーカー実装となるが、これに対してAHBポートからDMA転送を直接掛けられるようになっている。ただしAHBは32bit幅なので、2回に分けて転送が行われる形だ。このあたり、TCMの内容を積極的に入れ替えるというよりは、なるべくTCMの中身をいじらない様に使うのが性能改善には効果的なのかもしれない。

Photo14:パイプラインの一部(Instruction Fetch)もRouting Crossbarに接続されているというのが面白いし、そのCrossbarがフル構成というのもMCUとは思えない重厚さである