SlideShare a Scribd company logo
SDx 2016.3のプラグマによる
ハードウェアと性能
marseeこと小野 雅晃
ソフトウェアとハードウェアの
インターフェース
● Vivado HLSは明示的にハードウェアのインター
フェースをINTERFACE指示子で定義
● SDSoCはソフトウェアなので、指示子は本来無い
のだが、インターフェースを指示子で指定する
● SDSoCの指示子とハードウェアとの関係、性能と
の関係を調べた
– SDSoCは内部でVivado HLSを使っているが、Vivado
HLSで性能が良かったコードはSDSoCでも性能が良い
のか?
今回やったこと
● SDx(SDSoC) 2016.3を使用
●
お馴染みのラプラシアンフィルタを使用した
● ハードウェア化ラプラシアンフィルタ関数 vs ソフトウェ
ア・ラプラシアンフィルタ関数の速度比較
– 比較用ソフトウェア・ラプラシアンフィルタ関数は固定
– ハードウェア化ラプラシアンフィルタ関数のデータ転送の指
定用プラグマを変更
● ハードウェアの違い(Vivado、Vivado HLS)
●
性能の違い
– ハードウェア化ラプラシアンフィルタ関数の記述を変更
●
性能の違い
●
最高性能の組み合わせの条件は?
今回使用したデータ転送にかかわる
プラグマ
● #pragma SDS data zero_copy(cam_fb[0:ALL_PIXEL_VALUE])
● #pragma SDS data zero_copy(lap_fb[0:ALL_PIXEL_VALUE])
● #pragma SDS data copy(cam_fb[0:ALL_PIXEL_VALUE])
● #pragma SDS data copy(lap_fb[0:ALL_PIXEL_VALUE])
● #pragma SDS data access_pattern(cam_fb:RANDOM, lap_fb:RANDOM)
● #pragma SDS data access_pattern(cam_fb:SEQUENTIAL, lap_fb:SEQUENTIAL)
● #pragma SDS data sys_port(cam_fb:AFI, lap_fb:AFI)
● int lap_filter_axim(int cam_fb[ALL_PIXEL_VALUE], int
lap_fb[ALL_PIXEL_VALUE])
● {
– ハードウェア関数の引数が配列(要素数をどこかで明示しておかないとエラー)
– 配列がメモリの領域を示している
プラグマによる外部メモリとの
転送方法(copy, zero_copy)
● #pragma SDS data copy(<ポート名>…)
– データはブロックRAMに一時コピーされる?
– 呼び出し側関数からはmalloc()で取得したメモリの先頭アド
レスを配列のアドレスとして渡される
– スキャッタ・ギャザー用DMA
● 4kバイトごとにアドレスが不連続の可能性
● #pragma SDS data zero_copy(<ポート名>…)
– データはDDRから転送��れたそのままを使用
– 呼び出し側関数からはsds_alloc()で取得した連続領域のメ
モリを配列のアドレスとして渡される
– シンプルDMAでもOK
プラグマによる外部メモリとの
転送方法(data access_pattern)
● #pragma SDS data access_pattern(cam_fb:RANDOM,
lap_fb:RANDOM)
– RANDOM ー RAMインターフェースが生成される
– デフォルトのアクセスパターン
● #pragma SDS data access_pattern(cam_fb:SEQUENTIAL,
lap_fb:SEQUENTIAL)
– SEQUNTIAL ー ストリーミング・インターフェースが生成される
– 配列のエレメントの順番は守る必要がある(ストリーミングだから)
● zero_copyプラグマが無い引数にのみ適用できる
使用するPSのポートの指定
(data sys_port)
● #pragma SDS data sys_port(cam_fb:AFI,
lap_fb:AFI)
– portはACP、AFI(HP)、MIGのいずれか
– sds_alloc_non_cacheable()かsds_register_dmabuf()で
メモリをアロケートした場合はAFI(HP)ポートを使ったほう
が良い
– SDSoCでは自動的にデータ・ムーバーが適切なポートに
接続する
– ラプラシアンフィルタではデフォルトではACPポートが使わ
れる(malloc(), sds_alloc()使用)
第1段階のラプラシアンフィルタ
● 性能の低いラプラシアンフィルタ
– 1ピクセルずつRead
– ラプラシアンフィルタ処理
– 1ピクセルずつWrite
● プラグマ
– 無し(copy, data access_pattern(RANDOM))
– data access_pattern(SEQUENTIAL)
– zero_copy(sds_alloc())
● 最初にプラグマ無しをやってみよう
Vivado IPインテグレータ(プラグマ無し)
Vivado HLSプロジェクト
(プラグマ無し)
● ハードウェア化する関数のファイルがVivado HLSのソースファイ
ルになっている
● SDSoCがVivado HLSの指示子を追加している
Vivado IPI(SEQUENTIAL)
Vivado HLS(SEQUENTIAL)
Vivado IPI(zero_copy)
Vivado HLS(zero_copy)
プラグマによるVivado HLSが生成す
るインターフェース
● 無し(copy, data access_pattern(RANDOM))
– ブロックRAMインターフェース
● data access_pattern(SEQUENTIAL)
– ストリーミング・インターフェース(FIFO)
● zero_copy
– AXI4 Masterインターフェース
第1段階のラプラシアンフィルタの
リソース使用量
プラグマ無し SEQUENTIAL ZERO_COPY
LUT 46 46 21
LUTRAM 13 12 7
FF 35 35 15
BRAM 53 33 18
DSP 20 13 16
BUFG 3 3 3
(注:単位は
パーセンテー
ジ)
画像の大きさは
100x75 ピクセル
第1段階のラプラシアンフィルタの
リソース使用量(グラフ)
LUT LUTRAM FF BRAM DSP BUFG
0
10
20
30
40
50
60
プラグマ無し
SEQUENTIAL
ZERO_COPY
性能比較
● プラグマ無しとSEQUENTIALのハードウエア実行
時間は不安定。やるたびに変わる(SDSoC勉強会
でmalloc()を使っているためとの指摘あり)
● この状態では性能比較は無理だった
プラグマ無し SEQUENTIAL ZERO_COPY
ハードウェア
実行時間
4.32 ~ 10.6 5.8 ~ 10.7 0.943
ソフトウェア
実行時間
0.922 0.906 0.824
単位は ms 画像の大きさは
100x75 ピクセル
FPGAの部屋のブログの関連記事
● http://marsee101.blog19.fc2.com/blog-entry-36
82.html
● http://marsee101.blog19.fc2.com/blog-entry-36
84.html
● http://marsee101.blog19.fc2.com/blog-entry-36
85.html
● http://marsee101.blog19.fc2.com/blog-entry-36
87.html
memcpy()を使用した第2段階の
Cソースコード
● memcpy()を使ったのCソースコード(PIPELINEも)
● Vivado HLSのプラグマだけでSDSoCで動作
– ハードウェア化関数の引数のvolatileを外した
– INTERFACE指示子のbundleオプションを外した
– malloc()をsds_alloc()に変更、free()も変更
● つまりSDSoCのzero_copyと等価
● ハードウエアの実行時間55.7ms、ソフトウェアの実行
時間 51.7ms、SW/HW 0.928≒ 倍(800x600ピクセル)
● http://marsee101.blog19.fc2.com/blog-entry-3688.h
tml
性能向上を図った第3段階の
Cソースコード
● array_partition、3x3レジスタ実装
● 前段階と同様の措置(volatile, bundle, sds_alloc)
● SDSoCのzero_copyと等価
● ハードウエアの実行時間14.9ms、ソフトウェアの実
行時間 51.8ms、SW/HW 3.48≒ 倍(800x600ピク
セル)
● http://marsee101.blog19.fc2.com/blog-entry-36
89.html
Vivado HLSのAXI4-Streamのコード
● Vivado HLSのAXI4-Streamのコードは果たして動く
のか?
● @ryosさんの記事を参考にSDSoC 2016.3でサイド
チャネル付きAXI4-Streamを実装しようとしたが失敗
●
でも、今までもストリームにしてきた
● data access_pattern(SEQUENTIAL)のプラグマを付
けて、シーケンシャルに実行するコードだったらOKで
は?(AXI4-Streamではないけど)
● AXI4-Streamのコードでやってみたらどうなんだろう?
AXI4-Stream向きのコード1
● AXI4-Streamのコードを使用した
– サイドチャネルを使っているので、それを外した
● SDSoCで使うので、Xilinxのビデオ用IPのことは考えない
– 入力のストリームと出力のストリームにはif文がない
– data access_pattern(SEQUENTIAL)プラグマ
●
結果
– ソフトウェアの実行時間は、約 47.7 ms
– ハードウエアの実行時間は、約 5.54 ms
– SW実行時間/HW実行時間≒8.61倍
● 驚異的。。。ハードウエアの実行時間はReadもWriteも重なり合ったフル
バーストしないと実現できない
● なぜならば、800ピクセルx600行x10 ns(クロック周期)= 4.8 ms
– 1ピクセルは1クロックで転送(1ピクセルはint型、クロック周波数は100MHz)
● http://marsee101.blog19.fc2.com/blog-entry-3690.html
AXI4-Stream向きのコード2
● AXI4-Stream向きのコード1と同様
● ただし、data access_pattern(SEQUENTIAL)プラグマの代
わりにdata zero_copyプラグマ
● つまり、Vivado HLSでのメモリ・アクセスをAXI4 Masterに
●
結果
– ソフトウェアの実行時間は、約 47.7 ms
– ハードウエアの実行時間は、約 6.04 ms
– SW実行時間/HW実行時間≒7.90倍
● AXI4-Stream向きのコード1よりも少し遅くなっている
が、ReadとWriteが重なり合ってDMAされているはず
● http://marsee101.blog19.fc2.com/blog-entry-3691.html
Vivado HLSで最速コードを確かめる
● 最速の結果が出たSDSoCのコードをVivado HLSで
INTERFACE m_axi指示子を入れて確かめた(つま
り、AXI4 Master )
● 確かに16バーストのReadとWriteが重なり合ったDMA(見
事なものだった。。。)
● if文無しでReadし、if文無しでWriteすれば最高性能(来たま
まの順番でフィルタして出力)
● http://marsee101.blog19.fc2.com/blog-entry-3692.html
● http://marsee101.blog19.fc2.com/blog-entry-3694.html
● http://marsee101.blog19.fc2.com/blog-entry-3695.html
ACPポートとAFI(HP)ポートの性能差
● AXI4-Stream向きのコードではACPポートを使用してDMA
● それではHPポートを使ったらもっと性能が出るのではないだろ
うか?
● #pragma SDS data sys_port(cam_fb:AFI, lap_fb:AFI)
– やってみたところ遅くなった
●
結果
– ソフトウェアの実行時間は、約 47.4 ms
– ハードウエアの実行時間は、約 16.0 ms
– SW実行時間/HW実行時間≒2.96倍
– ACPポートよりもHPポートを使用したほうが遅くなった
– キャッシュのコヒーレンシを保つため?なぜ?
● http://marsee101.blog19.fc2.com/blog-entry-3690.html
まとめ
● SDSoCでプラグマやCソースコードの違いによる
ハードウェアの違いや性能を検証した
● シンプルなCソースコードが最速だということが分
かった
● ACPポートをDMAに使用するよりもHPポートのほ
うが速度的に遅かった

More Related Content

SDSoC勉強会_170128_スライド「SDx 2016.3のプラグマによるハードウェアと性能」