はじめに
FPGAに限らずCPUやGPUなどすべての計算機に言えることなのですが、ハードマクロの演算リソースは使ってなくてもそこに居座り続ける(要するに無駄)という問題があります。
筆者は普段主に ZynqMP を使っておりますので、APUやRPUやOCM、PL内部のLUTやDSPやBRAM、そのほかにも USB や Ether や DDR4のコントローラ、など様々なハードマクロが初めから配置されており、これらは使わなくてもトランジスタリソースを消費してそこに居座り続けることになります。
ある程度は、品番選択によって無駄のスリム化はできますが限界はあります。
なのでこれらハードマクロとどう向かい合えばいいのだろうというのを今日は考えてみます。
多少非効率でもハードマクロを使うのはお得
ハードマクロはその計算専用に作られた回路ですので、多くの場合PLでLUTを使って同じ回路を構成するより圧倒的に高速かつ低消費電力です。
例えば、16bit の乗算がしたい場合、27x18 のDSP を使うのはもったいなからと言ってDSPが余ってるのにLUTで乗算回路を組んだりなんてことは通常しません。明らかに27x18 のDSPを多少の無駄は承知で使った方が電力も速度も良貨しますし、合成器も自動でDSPに割り当てます。
DSPやBRAMの場合はある程度合成器が自動で割り当ててくれますが、APUやRPUとなるとプログラマが明示的にシステム設計しないと割り当てを変えることは難しいです。
ハードマクロは数にも限りがあるし、できることも決まっているので、どこに何をやらせればいいの? というのは重要な問題な気がします。
CPU/GPUに至ってはもっとすごい話で、例えば整数演算しかない大量のデータを処理しているときなど、お高いCPU/GPUに搭載されたリッチな倍精度実数のSIMD演算器は大量のトランジスタ面積を占めたままお休みしております。INT4などに量子化されたニューラルネットなどがCPUではなくFPGAで極めて効率がいいのはこういう事情なのかと思います。
例えば浮動小数点演算
最近は HLS の普及もあり PL で浮動小数点演算を行うことも増えてきたように思います。ところでZynqMPの場合APU(Cortex-A53)にNEON、RPU(Cortex-R5)にVFPを抱いており、ハードマクロの浮動小数点演算器ががっつりいるので、こちらが使えるなら使った方がお得に思います。周波数もCPUは高速ですので、並列化困難で応答性を上げたければ周波数頼りになるような処理にも適していると思います。
そうはいっても、
- PL⇔PS の同期や通信が大変
- 将来 PS のないFPGAに移植したいとき困る
とか、諸事情はあるかとは思いますが、多少の無駄を加味しても十分元が取れるケースはありそうに思えます。
全体を考えた最初のシステム設計が大事
SoC上でやらせたい処理を考えるとき、アプリケーションの処理や、解きたい問題のアルゴリズム全体を考え、どこをどこに割り当てると効率的に計算できるのかのシステム設計を行うのはとても重要な作業に思います。
のような比較的ありきたりな手順で設計は進むかとは思いますが、私は必要に応じて2まで戻って反復的に設計を進めることが重要に思います。特に設計フェーズで利用するSoCのどこにどういう資源があるのかしっかりと把握したうえで、2と3 の反復を十分やってシステム最適化しておくことが、全体性能を上げてくれるように思います。
しばし 4と5 あたりの反復が増えがちな気がしますが、実装してみてデータフローそのものを変えた方がよさそうなボトルネックが見つかったら迷わず2まで戻るべきかとは思います(まあ、スケジュールが許さず強行するケースは多いのでしょうけど)。
おわりに
SoC の中を見渡すと結構いろんなところにいろんな演算リソースがハードマクロとして存在しているように思います。
設計初期の段階からそれらに目を配り、活用できないか考えてみるのは、案外思いもしなかったアーキテクチャでの目的達成につながるかもしれません。
今後、Versal ACAP とかになるともっといろんなハードマクロが入ってきそうですし、視野の広い設計を楽しめるとよいなと思います。