3段パイプライン

3段パイプライン

パイプライン処理(時間的並列処理)

パイプライン処理とは、一つの操作を複数の部分操作に分解し、それぞれが独立に、かつ同時に処理できるユニットを用意し、並行して動作させる並列処理のことを言います。

例えば命令をメモリから読み出して、演算を行って、演算結果を記憶装置(メモリまたはレジスタ)に格納するまでの一連の作業を次のような分担のユニットに分けます。

  • ①命令を読み出すユニット(フェッチ)
  • ②命令コードを解読・翻訳するユニット(デコード)
  • ③演算を実行するユニット(演算)
  • ④演算結果を記憶装置に格納するユニット(格納)

各々のユニットは他のユニットとは完全に独立して自分の仕事を行います。通常は1クロックで仕事を終えて、次のユニットに処理結果を送ります。他のユニットが何をどう処理していようがお構いなく、自分の仕事だけをひたすら1サイクルで行います。

上記の場合①~④の4段階でひとつの命令の処理が終わるので、4段パイプラインと呼びます。実際は1命令に4サイクル必要ですが、各々のユニットが並列処理を行い、④の処理は1サイクルごとに結果を出しますので、見かけ上1サイクルで1命令の処理が終るようになります。

メリットとデメリットを挙げると次のようになります。

  • < メリット >
  • ●同種の操作が連続的に行われる場合に好適(RISC向き)
  • ●ハードウェアが小さくなる
  • < デメリット >
  • ●簡単な操作には逆効果
  • ●並列度を極端に高くすることができない(パイプライン障害が起きると効率が落ちる)

Cortex-M3のパイプライン処理

Cortex-M3は3段パイプライン処理です。3段とは「フェッチ」「デコード」「演算(格納含)」です。下図にCortex-M3のパイプラインシーケンスの図を示します。

  • ●ステップ1:Flashから命令をフェッチ(F)
  • ●ステップ2:命令をデコード(解読・翻訳)(D)
  • ●ステップ3:演算して、結果の書き込み(E)

0x8FECのAND命令から0x8FF0のEOR命令までは、何の障害もなくパイプライン処理が行われ、1サイクルごとに演算結果が出てきますので、1命令1サイクルになります。

しかし、0x8000のBX r5命令のような条件分岐命令があると、演算結果によって、0x8002のSUB命令を続けて演算するのか、0x8FECのAND命令に分岐するのが決まるため、BX r5命令の結果を待たなければなりません。そのためパイプライン処理が中断します。この様にパイプライン処理が中断することをパイプライン障害と呼びます。分岐命令以外でも、リード・アフタ・ライトと言って「ある命令の結果が次の命令のオペランドとして使われる場合」でもパイプライン障害が起きます。

Cortex-M3では、この様なパイプライン障害が発生しても、被害を最小限に抑えるために、前もって分岐先を計算しておく機能を持っています。その機能を分岐投機と呼んでいます。下の例は2サイクルのロスになっています。

図1

Cortex-M3のパイプラインシーケンス