次が「Clause」の話である。実の所「Clause Execution」という概念は結構昔からあるが、ハードウェアの実装という形では余り記憶がない。そもそもどういう概念か? という事でまず通常の命令実行手順を紹介したのがこちら(Photo20)。これに対してClause Executionでは、こんな形(Photo19)に複数の命令を固まり(Clause)にして、そのClauseの単位で実行を行う(Photo20)事でオーバーヘッドを削減しよう、というものだ。
Photo18:とりあえずアウト・オブ・オーダーとかの話は置いておきたい。イン・オーダーの場合、命令を実行するごとに次の命令をどうするか決めるという仕組みである。もちろんこれだと時間が掛かって仕方ないのでパイプラインでオーバーヘッドを遮蔽する訳だ |
Photo19:オーバーヘッドってなに? という具体例はこの後 |
この方式の実装例を見かけないのは、実は性能改善にはほとんど影響がないためだ。例えばPhoto20だとあたかも5つのClauseが同時に実行できるように見えるかも知れないが、実際はClause内の1個の命令処理の時間は変わらないし、5つのClauseを同時に実行するためには実行ユニットも5並列が必要になるから、全然意味が無い。そもそもオーバーヘッドの部分はパイプラインで遮蔽されているから、普通に実装する限りは性能はまったく同じである。では、何に効果があるか? といえば省電力である。オーバーヘッドがあるということはパイプラインであっても、そのオーバーヘッド分を処理するエネルギーは命令ごとに消費される。ところがClause単位で固まりにすれば、オーバーヘッドの総数が減るから、その分消費電力が削減できるという訳だ。
実際の例で見てみたい。ここでは
ADD R2, R0, R1 (R0+R1→R2)
ADD R4, R2, R3 (R2+R3→R4)
ADD R0, R4, R5 (R4+R5→R5)
という3つの加算を行うケースである。これを通常の方式で行ったのがPhoto21で、6回のレジスタファイル読み出しと3回の書き込みが発生する。ところが、この場合2回目と3回目の加算はそれぞれ1回目と2回目の結果を利用している。そこで中間領域(T:Temporal Register)を用意して、ここに演算結果を一時格納することで、レジスタファイルの読み出しは4回、書き込みは1回になる(Photo22)。これで性能が上がるわけではないが、消費電力は明確に削減できるし、利用するレジスタファイルの数も減るから最適化が容易になる。
ただ、Clauseベースにすると、スケジューリングに関しては別の配慮が必要になる。例えば1つ目のClauseでテクスチャを操作して、その結果を3つ目のClauseで使う(Photo23)なんてケースだ。この場合、テクスチャユニットの処理結果が確定するまで3つ目のClauseはホールドされるが、そこで間が空いてしまう場合、別のQuadのClauseが埋める形になる。考え方としてはDeterministic Multi-Threadingと同じ方式だ。なので、実際には複数のClauseが交互に実行されるような形になる(Photo25)。このClauseの実際のサンプルはこんな形(Photo26)である。あとはコンパイラがどれだけ上手くClauseを構成できるか、で効率が変わってくることになるだろう。
Photo23:別にテクスチャだけではなく、Load/Storeユニット待ちということもありえるだろう |
Photo24:ある意味スレッディングと同じなのだが、スレッディングよりももう少し大きなClause単位での管理、というのがポイントとなる |
Photo25:実際にはもっとQuadが多くなる訳で、恐らくRound Robin的な形で複数のQuadを廻すものと思われる |
Photo26:t0/t1がテンポラルレジスタとなる。いくつテンポラルレジスタを利用できるのかは現状明確では無い |
話をExecution Engineに戻すと、基本的には32bitのエンジンで、8/16bitも扱える仕組みになっている(Photo27)。また、Addと並行してSpecial Function Unitも搭載されている。これと組み合わされるレジスタファイルは、ある意味当然ではあるがQuad単位ではなくスレッド単位で用意されている(Photo29)。このExecution Engineと組み合わされる3種類のユニットも、それぞれMidgardから色々変更がなされているが、主眼はいかに省電力化するか、というあたりに置かれている(Photo30)。
Photo27:ここには無いが64bitのフロートも扱えるそうで、その場合は性能が1/2になるとの事。2サイクル使って処理を行うものと思われる |
Photo28:どうやってサイズを削減しているかというと、文面から見る限り一部の機能はハードウェアからコンパイラ側に移しているように思える |
これはメモリアクセスに関しても同じである。まずテクスチャに関しては、Midgardと同様のタイル型の格納方法を取るが、タイルの幅をより小さく分割することで最適化を図っているとする(Photo31)。またシェーダーではIndexベースのアクセスとすることで、必要とするメモリアクセスの帯域そのものを削減したとしている(Photo32)。
ちなみに冒頭でも述べたが、Mali-G71は完全なキャッシュコヒーレンシを実現している。このため、Mali-G71は最大4本のLinkでCCI-550と接続される形になる(Photo33)。このL2を含むMali-G71コア全体でもTrustZoneを当然サポートしている。
ということで、Mali-G71の詳細をご紹介した。全体としては、Cortex-A73と同じく性能を改善しつつも、省電力への配慮の方が非常に多い実装となっている。絶対性能もさることながら、性能/消費電力比を大幅に引き上げたのがMali-G71の特徴ということになるだろう。