Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

FPGAでベンチマークしたときに苦労した話@fpgax#12

1,216 views

Published on

NVIDIA GPUとXilinx FPGAの両環境で、モンテカルロ法による円周率計算のベンチマークを実施しました。その際のちょっとした苦労話と経験から得たノウハウをシェアします。

Published in: Technology
  • Be the first to comment

  • Be the first to like this

FPGAでベンチマークしたときに苦労した話@fpgax#12

  1. 1. FPGAでベンチマークしたとき に苦労した話 @fpgax#12 2019/11/12 安藤 潤
  2. 2. 自己紹介 ● 名前 ○ 安藤 潤 ● 略歴 ○ 国内ASICベンダーで11年ほど画像処理IP開発 ■ アルゴ~Cモデル~RTL設計~検証~FPGA評価~ES評価 ○ ザイリンクスで1年ほど技術
  3. 3. Xilinx Alveo 昨年、量産向けFPGAアクセラレータカードを発表 ベンチマークしなくては! SDAccelがあるからHLSでサクッといけそう(楽観 / 無知)
  4. 4. CPUやGPUに勝つには? CPU GPU FPGA 動作周波数 3GHz 1.5GHz 300MHz メモリ帯域 ~数百GB/s ~数百GB/s ~数百GB/s 並列度 ~数十 ~数千 任意 アーキテクチャ ノイマン型コンピュータ 命令セットアーキテクチャ DSA (ドメイン特化 アーキテクチャ) ● FPGAに向いている計算 ○ DRAMアクセス<計算量 ■ メモリ帯域がボトルネックにならないこと ○ データフローで表現できる計算 ■ 計算(タスク)を並列化できる ■ データが流れてさえいれば演算器の稼働率が上がるデザイン
  5. 5. モンテカルロ法による円周率計算 ● 乱数で平面にランダムな点(𝒙,𝒚)を打ち、 四分円の内側に入った数をカウントし 円周率を計算 ● 乱数生成スピードでベンチマーク!
  6. 6. メルセンヌツイスタ ● ハードウェア実装に適していそう 内部状態更新 statet+1[623] = update(statet[0], statet[1], statet[397]) statet+1[0..622] = statet[1..623] 乱数出力 outt+1 = tempering(statet+1[623])
  7. 7. FPGA実装 ● やることはふたつ ○ ハードウェアをHLSで記述 ○ ホストアプリはOpenCL Runtime APIを使って記述 ● 他の仕事はすべてSDAccelが面倒見てくれる、楽ちん!
  8. 8. GPU実装 ● GPU(GeForce GTX 1080 Ti) ○ CUDA Toolkit v10.0.130 ○ cuRAND ○ MTGP32 (Mersenne Twister for Graphic Processors)
  9. 9. ベンチマーク結果 ● なんとか勝てた… でももっとできる子のはず!! 性能 3x 性能/W 15x
  10. 10. 並列度の向上 ● U200のデバイスは3つのダイ(SLR)で構成される ○ が、1つしか使っていなかった… ○ 256並列のカーネルがひとつ ○ リンカの引数でカーネルを複製して複数のSLRへ分配! xocc -l … ¥ --nk mcpi:5 ¥ 複製 --slr mcpi_1:SLR0 ¥ SLR割付 --slr mcpi_2:SLR0 ¥ --slr mcpi_3:SLR1 ¥ --slr mcpi_4:SLR2 ¥ --slr mcpi_5:SLR2
  11. 11. 周波数の向上 ● 当初は185MHz ● メルセンヌツイスタ実装方法を変更 ○ 変更前:32bit x 624の内部状態をFFで保持 → 配線混雑 ○ 変更後:BRAMで実装 ● パイプライン構造を変更 ○ 変更前:パイプラインが大きく遠くまで制御信号が広がる ○ 変更後:複数の小さなパイプラインをつなぐ構造へ ● HLSならアーキテクチャ探索が簡単!
  12. 12. 大事そうなことなのでもう少し詳しく ● 良くない😫:大きなパイプラインがひとつ ○ ひとつのfor文に処理を詰め込む ■ ソフトウェア的な発想だと自然 ○ 制御信号が遠くまで広がる ■ fanout、配線遅延、クロックリージョンまたぎ ○ SLRに納まりが悪そう パイプライン 制御信号 for (int i=0; i<N; i++) { auto x = mem_in[i]; auto y = func_a(x); auto z = func_b(y); auto w = func_c(z); mem_out[i] = w; }
  13. 13. 大事そうなことなのでもう少し詳しく ● 良さそう😀:小さなパイプラインをストリームでつなぐ ○ for文を分割 ○ ストリーム(FIFO)により配置の自由度が向上 #pragma HLS DATAFLOW hls::stream<DATATYPE> x, y, z, w; #pragma HLS stream variable=x depth=2 #pragma HLS stream variable=y depth=2 #pragma HLS stream variable=z depth=2 #pragma HLS stream variable=w depth=2 mem_read(mem_in, x); func_a(x, y); func_b(y, z); func_c(z, w); mem_write(w, mem_out); 出来上がるハードウェアを 思い浮かべながらC++で記述!
  14. 14. 改善結果 (改善前:256並列、185MHz、47Gs/s) ● 並列度 ○ 64並列のカーネルを10個 = 640並列 ● 周波数 ○ 375MHzに改善 4個 2個 4個 性能 [Gs/s] 電力 [W] 性能比 性能比/W GTX 1080 Ti 19.51 240 1.0 1.0 Alveo U200 222.95 73 11.4 37.5 最終ベンチマーク結果 一秒間に2230億個の乱数生成… エクストリーム感
  15. 15. まとめ ● パフォーマンスを引き出すには ○ FPGAのことを少しは知っていた方がいい ○ ツールがインプリしやすいハードウェアを書く ○ HLSツールと対話しお気持ちを理解 ● FPGAの敷居が低くなった! ○ C++でハードとアプリを書くだけ ○ Vitisライブラリも出たし ○ 盛り上がるといいな ○ AWS F1ならすぐに試せます!是非!

×