やかんです。
今日はハードウェア設計論の授業で、高位合成について扱われました。メモっていきます。
※内容は僕のパブリックなメモでしかないです。
授業メモ
- 高位合成について
- FPGA
- 再構成可能なハードウェア
- データフローコンピューティング
- 再構成可能なハードウェア
- ASIC
- LSIの背系フロー
- システム設計
- 機能合成
- verilogとか
- 論理設計
- 高位合成は、機能合成を全自動化する試み?
- vivadoとかではできないが、研究の世界ではなんでも合成可能。
- LSIだけじゃなくて、FPGAと組み合わせるとすごいことが起きるらしい。
- 動作合成、高位合成、
- CのシミュレーションとRTLのシミュレーションは、行数がハードウェアの方が多いからめっちゃ時間かかる。
- verilogのシミュレーションはめっちゃ時間かかるから、Cでシミュレーションして設計してあとは高位合成で自動化したい、というモチベ。
- あと、verilogの場合はvivado使ったりCAD使ったりで金かかるし、ハードウェアエンジニアの給与もめっちゃ高いから金かかる。
- ハードウェアとCPUはハードウェアの方が早い。
- CPUはでコードして、ALU入れてメモリいじってみたいな感じで時間かかる。
- ハードウェアはそういうのぶっ飛ばして効率化できる。
- CPUの方が汎用性高かったり、ハードウェアは物理的な線の繋ぎ換えが必要だったりで嫌厭されてきたが、FPGAの登場でそれが覆されてきている。
- データフローコンピューティングはさらに機構が変わるらしい。
- ハードウェアはポートがめっちゃ高価らしい。
- コンパイラの授業があるのか。。
- ある演算を最速で実行するか、最小リソースで実行するか。
- バインディングアルゴリズム
- レジスタもバインドする。
- バインドは、論理を物理に置き換えること、あるいは対応させることのことだろう。
- レジスタ転送表
- 出力転送表
- 転送表が書けたら、あとは回路図っぽいものが描ける。
- マルチプレクサ(セレクタ)が状態のみによるのか、、とか。
- Cを与えて、資源的な制約(レジスタ何個とか)の条件を与えてRTLっぽくまとめさせて転送表に起こして回路っぽくする。
- 高位合成については最適解とかじゃない。目的関数がめっちゃたくさんあるから部分的に最適解を求めてもあまり嬉しくない。
- 研究としてはOK。
- あとは、サイクル数を指定することもある。
- なんでもGPUでやる場合もあるけど、FPGAを頑張ればGPUに勝てる。
- ハードウェアはリソースいくらでも詰める。
- ソフトウェアパイプライン
- 高位合成でパイプラインは難しい。
- キャリー変数を考える必要がある。
- キャリー変数は、イテレーション間で値を保持する必要のあるもの。
- 1回目に計算した値を2回目に使う、とか。
- ↑キャリー変数がない場合は(AIとか)GPUの方が良かったりする。がある場合はFPGA勝てる。AIの場合キャリー変数とかあまり登場しないけど、実際のプログラムにはよく登場する。
- キャリー変数があると、例えばA = A + Bとかだと、この計算サイクルが全て終わらないと正しいAの値を取得できない。
- 要はデータ依存てことだから、クロック周波数を上げてしまうとそりが追いつかなくてバグる可能性がある。
- パイプラインで速くしようとした場合はキャリー変数とデータ依存についてよく考える必要がある。
- パイプラインがどれだけ詰められるかが高位合成の鍵らしい。
- クロック周波数を落とせば、クロックを跨ぐ必要がないからレジスタは不要。高位合成の場合は周波数を適当な値に設定する必要があり、それは速さではない。これがCPUとハードウェアの違い。
- ripple carry adderは下位bitの出力はとても速い。だから、演算器自体の遅延自体が3nsで3個積んだとしても、総合で5nsくらいで終わってくれる。
- CPUにもsin cosはある。けど、パイプライン化されていない。100サイクルの順序回路で動きます、とか。アセンブラで動かしているらしい。
- 高位合成の場合はなんでもパイプライン化する。だから、sinもパイプラインで動かす。これが高位合成の強みだったりする。
- Appleはお金持ってるから、独自に命令セットをARMで持っている。だから性能良い。
- 2クロックに1回動く順序回路、とかよくわからないものでもパイプラインにすることができる。素直にパイプラインできないという場合でも、高位合成では可能。
- モジュロ
- 人間とかCPUは全部際高速化でやりたくなるから、それが最適解じゃなくて、っていう場合には高位合成が活躍できる。
- 金銭的なバランスを取ったり。
- ストールコントロール
- ストール制御
- 入力がemptyだったら、何を出力してどこを止めて、とかの制御がめちゃ難しいらしい。ストールの制御えぐい。
- 高位合成の場合は、高位合成開発者が良いアルゴリズムを頑張って考えてくれたのでそれを利用すれば良い。
- SONYとかも高位合成やってるらしい。
- 多重ループ
- CPUだと、for文のネストとかは書いてある通りに動く。
- 内側のループは高速化されるけど、外側まで考えると高速じゃないとか。
- ループはif と goto。プログラムカウンタをいじりまくるっていう手法。
- データフローコンピュータの場合は、外のループと内のループを同時にパイプライン化する。
- アンロールは高位合成ではあまり使えないらしい。
- アンネストは、完全ネストループでしか使えない。不定回のループの場合はできない。アンネストは、外側ループ5回、内側ループ10回の場合1つの50回のループにすること。
- 不定回の場合は、無限回回る1つのループを作って、条件分岐でループから抜けるようにする。
- CPUはここまで器用にできないらしい。if文あるとストール起きるし。データフローコンピュータの場合は、ifとかあってもセレクタ1つ挟まるだけ。制御を切り替えたりしない。
- CPUはifで制御を切り替える。データフローコンピュータは切り替えない。ただ回路の中にセレクタが入るだけ。
- func1でアレイ扱って、func2で同じアレイを扱う場合は、func1とfunc2の間にFIFOを挟めば良い。
- CPUはfunc1終えて、次にfunc2を実行。メモリアクセスもめっちゃ生じる(キャッシュは考慮してないけど)
- じゃあ、ランダムアクセスの場合は?
- GPUは、func1を爆速で終えて結果ためて、func2をまた爆速で実行。それぞれの関数を暴力的に速くする。時間的に並列化はしていない。
- データフローコンピューティングは時間的に並列。時間方向の並列化はやはりデータフローコンピューティングにしかできない、という理解が大事。
- この場合、GPUの方がFPGA並べるより安かったりする。
- 細かいことは個人で勉強したほうが速い。授業の役割的な話だよな。
- FIFOが間にあれば、ハードウェアは並列化できる。
- 高位合成をソフトウェアの感覚で多くの人が書くから、うまくいかない。データフローを考えてソフトウェア書いて、高位合成に回したい。
- データフロー方向に並列化しやすいようにプログラムを書く。
- 制御依存を無視して並列化可能
- CPUはPCを飛ばすことでifを実現。これは宿命的。。
- データフローはセレクタを入れるだけ。
- 制御を移す、という概念はないから、パイプライン化が簡単。
- if文の場合、演算機は1つでいいんだけど(どっちかしか実行されないから)場合によっては2つとか積んだりするらしい。
- スペキュレーション
- レジスタ増える。使うかどうかわからない値を貯める必要があるから。電力消費も増える。が、レイテンシはお得。
- 高位合成はパイプラインフラッシュしない。そもそもその概念自体ない。CPUは分岐予測が外れると地獄。ハードウェアはそうじゃない。
- GPUはリソースめっちゃあるから、分岐予測とかガン無視でとにかく全部計算する。
- early conditional execution
- x = func1()
- y = func2()
- if( condition ) x else y
- ↑こんな感じの時、先に条件を確認しておけば、xyの両方を計算する必要がない。
- そうでない場合は、xとyともに計算してしまう。
- ↑これを理論上は高位合成がやってくれる。
- ↑これを意識してソフトウェアかけると非常に良い。データフローを意識したプログラミング。ただハードウェアの場合は、だよねえ。CPUの場合はもう関係ない気すらするけど。
- プログラムカウンタで制御するって、結構制約が多いんだな。
- でも必要性があるから、PCのものもデータフローのものも存在している。
- スペキュレーションしないと演算機を積んでも速くならない。だからアウトオブオーダがCPUには必須らしい。
- でも、制御依存がある場合は限界を迎える。
- データフローコンピュータが制御依存に強いというのは、どっちも並列してとりあえず実行するからってこと???
- 余談で、生成AIはif文ない。だからGPUが活躍できる。画像処理はif文めっちゃあるらしい。
- ハードウェアにはチェイン効果というものがるらしく、同じ演算を並べると1つあたりの遅延が速くなるらしい。
- GPUは空間的並列化。データフローは時間的にも並列化。
- だからリアルタイムでずーっとデータが流れ続けるものについてはデータフローコンピュータが強い。ストリームデータ。そのため、ストリームデータじゃない場合はCPUとかの方が良かったりする。
- CPUは1クロックで2入力だけどハードウェアの場合は3入力がデフォルトらしい。。
- ハードウェア向け
- SW向け:キャッシュオリエンティッドコーデイング。キャッシュにんこってればOK。キャッシュに乗せて、キャッシュに乗ってるものをばーっと計算する。局所的なメモリアクセスがまとまるように書く。
- ハードウェア向け:ハードウェアはちょっとずつデータ計算して、次の計算に必要なデータが揃ったらすぐに計算。SWと全然違う。一通りキャッシュに乗せて、、とかじゃない。とにかく順々に実行していく。必要最小限しかデータ読まずとにかくすぐに出す。
- ↑SW的なコードも、高位合成できちゃう。で、それなりに動いちゃう。CPU向きか、ハードウェア向きかでコードは別々に存在する。
- CPUはSRAM高額すぎるからあまり使えない。
- ループと配列アクセスは工夫のしがいがある。一個ずつずらしていく、とかだと同じところを連続して読む必要が生じたりする。この場合はコーデイングで無駄を省くことができる。
- SLAM
http://www.dlab.t.u-tokyo.ac.jp/
そのほかメモ
- 結局、ネストしたfor文とか、複数のfor文とかがCPUでどう実行されるのかわかってない。
- CPUにおいては、キャッシュにSRAMが用いられる。
ということで、授業メモとしては以上とします。最後までお読みいただき、ありがとうございます。