計算機アーキテクチャ特論Chapter.6.6~6.9 6311636 篠原辰哉
6.6 HARDWARE GENERATION NOTES 命令レベルのプラグマ 命令・ブロックレベルの最適化はCソースコードの段 階で以下のプラグマを用いて行われる ・CO PIPELINE ・CO UNROLL ・CO SET stageDelay
6.6 HARDWARE GENERATION NOTES CO PIPELINEプラグマ 命令のパイプライン化は、次のような宣言が必要 for(i=0;i<10;i++){ #pragma CO PIPELINE sum+=i<<1; } この時、PIPELINEプラグマはループの先頭になけれ ばいけなく、又入れ子のループを含んではいけない
6.6 HARDWARE GENERATION NOTES CO UNROLLプラグマ ループのアンロールは次のような宣言が必要 for(tap=0;tap<TAPS;tap++){ #pragma CO UNROLL accum+=fribuffer[tap]+coef[tap]; } PIPELINEプラグマ同様ループの先頭になければい けない
6.6 HARDWARE GENERATION NOTES CO UNROLLプラグマ ループのアンロールはループの回数だけハードウェ ア上に重複して実装されることになる。 従って、ハードウェアサイズを考慮し、比較的繰り返し の少ないループに使うのが重要。 また、ハードウェア上で並行に実装できないような相 互依存の計算を含んではいけない。
6.6 HARDWARE GENERATION NOTES CO SET stageDelayプラグマ このプラグマは1ステージに組み合わせゲートでかか る遅延の最大値を指定する。 1ステージ中の宣言は1クロックで実装されるので、 Stage Delayを制御して1クロックに行われる処理を 分割して動作周波数を向上できることもある。
6.7 MAKING EFFICIENT USE OF THE OPTIMIZERS Impulse Cの処理を書くとき、Cコードがハードウェア 生成時にコンパイラやオプティマイザがどのように並 列化を行うか基本的な理解が必要。 これを理解すれば、実行速度と回路サイズ両方の点 において最適なコードが書ける。 このセクションでは、Impulse Cオプティマイザの動作 を一般的に説明し、ハードウェア生成のためのCを書 くためのいくつかの制約を説明する。
6.7 MAKING EFFICIENT USE OF THE OPTIMIZERS Stage Masterオプティマイザ Impulse Cのオプティマイザ(Stage Master)はコンパ イラによって生成されたCコードの基本ブロックに動作 して、命令ステージ数を最小にするよう命令をスケジ ューリングする。 次のような場所は必ずステージが遷移する If判定やループの条件制御 既に現在のステージで使われているメモリや配列 へのアクセス
6.7 MAKING EFFICIENT USE OF THE OPTIMIZERS Stage Masterオプティマイザ 例えば for(i=0;i<10;i++) sum+=i<<1; これをパイプライン化すると for(i=0;i<10;i++){ #pragma CO PIPELINE } 遅延 10*(delay(adder)+delay(shifter)) 遅延 10*max(delay(adder),delay(shifter))
6.7 MAKING EFFICIENT USE OF THE OPTIMIZERS メモリアクセスの影響 オプティマイザは同じバンクのメモリにアクセスするス テージを並列化できないので、並列処理を最大限活 かすためにはデータの独立性が重要。 そのため、大きな配列の一部をローカルストレージに 移動するといったことが必要になる。
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES Impulse CはANSI Cと互換性があるが、ハードウェ アを記述するとき、汎用のCコードにいくつかの制約 がある。
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES 関数呼び出しの非サポート Impulse Cのプロセスはコンパイル時に作られスタテ ィックなので、通常の方法ではハードウェアにコンパイ ルされたImpulse Cプロセスは他の関数やプロセスを 呼ぶことはできない。 #pragma CO PRIMITIVEで可能になった?
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES 整数演算 +, -, *, ++は1サイクルの計算としてサポートされる。 /を用いた除算演算は1ビット毎に1サイクル必要とす る複数サイクル演算。
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES シフト演算 シフト演算のオペランドは定数値のみ 例えば、次のループは iFlags = 0; for(i=0;i<8;i++){ if(afCubeVal[i] <= FTARGETVALUE) iFlags |=1<<I; }
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES シフト演算 iFlags = 0; bit=1; for(i=0;i<8;i++){ if(afCubeVal[i] <= FTARGETVALUE) iFlags |=bit; bit=bit<<1; } このように書きなおさなければいけない。
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES データ型の制限 Impulse Cコンパイラは構造体や共用体のような複雑 なデータ型をサポートしない。 また、これを書いている時点では、浮動小数点型もサ ポートされていないが、後のリリースでサポートされる だろう。
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES ポインタの制限 Impulse Cでのポインタの利用はコンパイル時点で 解決できる特定のメモリ位置への参照でなければな らなく、次のような状況に限られる
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES ポインタの制限 1.<pointer>=&<array element> 例:p=&(a[4]); 2.<pointer>++ 例:p++; 3.<pointer>=<pointer>+<integer expression> 例:p=p+2;
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES ポインタの制限 また、ポインタは複数の配列を指してはいけない。 次は許可される p=&(a[2]); … p=&(a[3]); が、次のような割り当ては許可されない p=&(b[3]);
6.8 LANGUAGE CONSTRAINTS FOR HARDWARE PROCESSES 多次元配列へのポインタの利用 入れ子のループを使用するよりも、次のようにポイン タを利用した方が効率的である p=&(a[0][0]); for(i=0;i<4*5;i++){ …//Access the array elements using p p++; }
6.9 SUMMARY このチャプタでは、FPGAハードウェアがImpulse Cコ ンパイラによってどのように作られるのかを見てきた。 以降のチャプタでは、ハードウェア生成と最適化に関 する重要なトピックスについて検討していく。
おわり