ただし、整数のかけ算、割り算に関しては、さらに専用の実行ユニットがある。これは、他の多くのプロセッサでも同様の構造を持つことが多い。ARM系のプロセッサは、RISC系でSoCとして製造されることから、必ずしもプロセッサコアに潤沢にトランジスタを利用できるわけではない。複数のスマートフォンなどに搭載される数量を考えると、ダイサイズの増大は、コストに大きく影響する。このため、演算回路の複雑なかけ算は、専用の演算器で、単純な命令とは別ユニットで処理することが多い。

Branchは、分岐命令を処理する部分だ。分岐処理に関しては、分岐予測機構があって、確率の高い方向に命令を、分岐処理の完了をまたずに実行できる。ただ、ARMv7の命令には、前述のように演算結果に応じて、次の命令をスキップする機構があり、無条件分岐命令との組み合わせで、「条件分岐」を構成する。Kraitでは、条件指定があっても、演算命令自体は、通常の実行ユニットで行い、結果に応じて、プログラムカウンタをインクリメントする数(通常は1命令分のインクリメントが行われるが、次の命令をスキップする場合には、2命令分のインクリメントとなる)を変えているとのことだ。

RISC系の命令セットでは、メモリからのロード、メモリへのストアを行う命令を別にするのが普通だ。これにより、演算とメモリアクセスを1つの命令で行わないようにすることで、マイクろアーキテクチャを想定したプログラミング(たとえば、メモリからレジスタへのロードを前方に配置し、その後に他のレジスタを使う演算命令を実行して、メモリからのロードを待ってから演算を行うような命令の配置)を行うことができる。このために、メモリのロード、ストアを処理する専用の実行ユニットが必要になる。また、場合によっては、アクセスするメモリアドレスを決定するために演算処理が必要になることもある。これは、「アドレッシングモード」によっては、レジスタ内部の値を演算してアドレスとしていることがあるからだ。また、ARMv7には、スタックでの利用を想定した複数のレジスタに対する同時ロード、同時ストアの命令もある。伝統的な「プッシュ」、「ポップ」といったスタック操作の命令ではないのは、ARM系のプロセッサには、スタックとして使われることが想定されている汎用レジスタはあるものの、スタック専用レジスタがないからだ。

アーキテクチャによっては、ロードとストアのどちらでも行える「ロード/ストア」ユニットを持つ場合もあるが、Kraitでは、ロード用、ストア用のユニットは別になっており、ロードとストアは並行して処理できるものの、2つのロード、ストアを並行して行うことはできないようだ。ただ、前述のように、メモリアクセスの頻度によっては、ロード命令を先行させるという「最適化」もコンパイラなどで行うことは不可能ではなないため、それぞれ1つしかないことは、必ずしも他の実装に比べて不利というわけでもないだろう。

Kraitのパイプライン

パイプラインのステージについては、11段と表記する資料もある。これについて確認したところ、Kraitの整数側パイプラインのステージは、最短で11段、最高で13段だという。実際、Cortex-A15の資料(図02)などでも、15段という表記があるが、これも最短(1クロックで実行できる命令の場合)のステージ数だ。

図02。Cortex-A15のパイプライン、発行(ISSUE)前が12段、実行部分が最短で3段となっている

アウトオブオーダーで、Simple INT演算ポートによる実行が1クロック(1ステージ)とすると、最後のライトバック処理で1ステージ、命令発効で1ステージ、ここまでが最短で3ステージとなる(図03)。

図03。Kraitのパイプライン。命令のフェッチ、デコードなどに8段、発行、実行、書き戻しなどが3段で合計11段になるのだと思われる。図は筆者推定のもの

となると11ステージという数から、命令フェッチからデーコード、その他の発行処理の前までのステージは、8ステージということになる。この間に命令のフェッチやデコード、レジスタリネーミング処理といった処理が行われるとすると、この部分は、どの命令でも同じだと思われる。だとすれば、最大13ステージは、命令の実行ユニット側で最大3ステージ必要なもの存在するということになるだろう。実際、メモリのロードストアなどは、場合によっては1クロックでは完了しないし、複雑な演算なら3ステージあってもおかしくはないだろう。実際、Cortex-A15では、かけ算処理などに4ステージを割り当てている。