はじめに
別記事 「はじめに」 を参照してください。
この記事では「Argsort IP」 で紹介した ArgSort_AXI IP を Kv260 に実装した結果を紹介します。
この記事で説明する ArgSort-Kv260 はGitHub にて公開しています。
ArgSort-Kv260 のデザイン
デザインブロック
ArgSort-Kv260 は次図のようなデザインになっています。
Fig.1 ArgSort-Kv260 のデザインブロック
ArgSort_AXI のバージョンは 1.2 です。前々回説明した「ArgSort IP」で説明した IP のバージョンは 1.3 ですが、「ArgSort-Ultra96」 と同じ環境にするために1.2を使用しています。
ArgSort_AXI の STM_AXI は [ZynqMP-ACP-Adapter] を通して PS 部の S_AXI_ACP_FPD に接続しています。[ZynqMP-ACP-Adapter] と ACP に関する詳細な説明は次の記事を参照してください。
ArgSort_AXI、 ZynqMP-ACP-Adapter、AXI Interconnect のクロックは Clock Wizard によって 220MHz または 250MHz を生成されたものを使っています。Clock Wizard には PS部の pl_clk0 が生成した100MHz のクロックが入力されます。
ArgSort_AXI のパラメータの設定値
ArgSort_AXI の主なパラメーターは次のように設定しています。これらのパラメーターのうち、MRG_WAYS、MRG_WORDS、STM_FEEDBACK の値を振ってそれ毎にビルドしたリソース量と実行時間を計測しました。
Table.1 ArgSort_AXI の主なパラメータの設定値
Parameter | Value | |
Categoly | Name | |
CORE | WORD_BITS | 32 |
INDEX_BITS | 32 | |
COMP_SIGN | FALSE | |
SORT_ORDER | 0 | |
MRG_WAYS | [16,32] (可変) | |
MRG_WORDS | [1,2](可変) | |
STM_FEEDBACK | [0,1,2] (可変) | |
STM_AXI | STM_AXI_ADDR_WIDTH | 64 |
STM_AXI_DATA_WIDTH | 128 | |
MRG_AXI | MRG_AXI_ADDR_WIDTH | 64 |
MRG_AXI_DATA_WIDTH | 128 |
結果
使用リソース
次表に MRG_WAYS、MRG_WORDS、STM_FEEDBACK を振ったそれぞれのデザインを Kv260 に実装した時のリソースの使用状況を示します。なお、MRG_WASY が64 以上は Kv260 で使われているデバイスには入りきりませんでした。また、MRG_WAYS が 32 かつ MRG_WORD が 2の場合、動作周波数が250MHz ではタイミング違反が発生したため、220MHz に落としています。
Table.2 Utilization
Design | Resources | Freq [MHz] |
|||||||
Name | MRG WAYS |
MRG WORDS |
STM FB |
CLB | BLOCK RAM | DSPs | |||
LUTs | Register | RAMB36 | URAM | ||||||
argsort_16_1_0 | 16 | 1 | 0 | 42507 | 27176 | 38 | 0 | 0 | 250 |
argsort_16_1_1 | 16 | 1 | 1 | 42714 | 27843 | 38 | 0 | 0 | 250 |
argsort_16_1_2 | 16 | 1 | 2 | 42859 | 27014 | 54 | 0 | 0 | 250 |
argsort_16_2_0 | 16 | 2 | 0 | 59239 | 55627 | 38 | 0 | 0 | 250 |
argsort_16_2_1 | 16 | 2 | 1 | 60491 | 56881 | 38 | 0 | 0 | 250 |
argsort_16_2_2 | 16 | 2 | 2 | 58363 | 54870 | 70 | 0 | 0 | 250 |
argsort_32_1_0 | 32 | 1 | 0 | 66648 | 46134 | 70 | 0 | 15 | 250 |
argsort_32_1_1 | 32 | 1 | 1 | 69430 | 47579 | 70 | 0 | 15 | 250 |
argsort_32_1_2 | 32 | 1 | 2 | 68064 | 46136 | 70 | 32 | 15 | 250 |
argsort_32_2_0 | 32 | 2 | 0 | 106793 | 103907 | 70 | 0 | 0 | 220 |
argsort_32_2_1 | 32 | 2 | 1 | 109295 | 106776 | 70 | 0 | 0 | 220 |
argsort_32_2_2 | 32 | 2 | 2 | 103651 | 103225 | 70 | 64 | 0 | 220 |
xck26-sfvc784-2LV-c resouce available | 117120 | 234240 | 144 | 64 | 1248 |
Kv260 で使われているデバイスが持っている LUT の数のうち、使用した LUT の数を次図に示します。
Fig.2 Utlization(LUTs %)
性能
次表にMRG_WAYS、MRG_WORDS、STM_FEEDBACK を振ったそれぞれのデザインを Kv260 で実行した時にかかった時間とスループットを示します。
ソートするワード数は、5,000ワードから 1,000,000ワードまでを 5000 ワード毎にかかった時間を計測していますが、そのうち下の表には 10,000ワード、100,000ワード、1,000,000 ワードの時の時間を示しています。スループットは、5,000ワードから 1,000,000ワードまでを 5000 ワード毎に計測したスループット(ソートするワード数/かかった時間)の平均値を示しています。
参考までに最下行に ZynqMP の CPU(arm64) で numpy ライブラリの argsort() でソートした時間とスループットを示しています。
Table.3 Performance
Design | Sort time [msec] | Throughput Average [Mwords/sec] |
|||||
Name | MRG WAYS |
MRG WORDS |
STM FB |
10K [words] |
100K [words] |
1M [words] |
|
argsort_16_1_0 | 16 | 1 | 0 | 0.445 | 3.277 | 34.805 | 28.59 |
argsort_16_1_1 | 16 | 1 | 1 | 0.347 | 2.364 | 22.136 | 43.87 |
argsort_16_1_2 | 16 | 1 | 2 | 0.353 | 2.270 | 21.287 | 45.67 |
argsort_16_2_0 | 16 | 2 | 0 | 0.328 | 2.004 | 24.568 | 40.87 |
argsort_16_2_1 | 16 | 2 | 1 | 0.274 | 1.214 | 17.030 | 59.95 |
argsort_16_2_2 | 16 | 2 | 2 | 0.292 | 1.092 | 15.289 | 66.27 |
argsort_32_1_0 | 32 | 1 | 0 | 0.338 | 2.393 | 24.882 | 39.59 |
argsort_32_1_1 | 32 | 1 | 1 | 0.297 | 1.898 | 17.478 | 54.79 |
argsort_32_1_2 | 32 | 1 | 2 | 0.566 | 2.285 | 19.921 | 47.65 |
argsort_32_2_0 | 32 | 2 | 0 | 0.280 | 1.489 | 19.003 | 53.62 |
argsort_32_2_1 | 32 | 2 | 1 | 0.239 | 1.184 | 13.765 | 72.11 |
argsort_32_2_2 | 32 | 2 | 2 | 0.619 | 1.526 | 15.389 | 63.20 |
ZynqMP(arm64) numpy.argsort() | 1.551 | 26.107 | 840.246 | 2.11 |
次図にスループットの平均値をグラフで示します。
Fig.3 Throughput Average [Mwords/sec]
テストの手順
テスト環境
- ハードウェア: Xilinx Kria Kv260 Vision AI Starter Kit
- ソフトウェア: ZynqMP-FPGA-Linux v2021.1.1 (Linux Kernel 5.10 + Debian 11)
インストール
Kv260 の準備
Kv260 に ZynqMP-FPGA-Linux または ZynqMP-FPGA-Ubuntu20.04 をインストールします。インストール方法は次のURLを参照してください。
- https://github.com/ikwzm/ZynqMP-FPGA-Linux/blob/v2021.1.1/doc/install/kv260.md
- https://github.com/ikwzm/ZynqMP-FPGA-Ubuntu20.04/blob/v2021.1-desktop-1/doc/install/kv260-desktop.md
- 『UltraZed/Ultra96/Ultra96-V2/KV260 向け Debian GNU/Linux (v2021.1版) ブートイメージの提供』@Qiita
ArgSort-Kv260 のダウンロード
次のように Kv260 に ArgSort-Kv260 をダウンロードします。
fpga@debian-fpga:~/$ git clone --branch 1.2.1 git://github.com/ikwzm/ArgSort-Kv260.git
fpga@debian-fpga:~/$ cd ArgSort-Kv260
FPGA ビットストリームとデバイスツリーのインストール
次のようにテストの対象となるデザインのビットストリームファイルとデバイスツリーを Kv260 にインストールします。デバイスツリーのインストールには Device Tree Overlay を使用しています。インストールするための Rakefile を用意しているので、rake コマンドを実行してインストールします。環境変数 TARGET にはデザイン名を指定します。
fpga@debian-fpga:~/ArgSort-Kv260$ sudo TARGET=argsort_32_2_1 rake install
./dtbocfg.rb --install argsort --dts argsort_32_2_1_5.10.dts
<stdin>:27.16-32.20: Warning (unit_address_vs_reg): /fragment@2/__overlay__/uio_argsort: node has a reg or ranges property, but no unit name
<stdin>:18.13-52.5: Warning (avoid_unnecessary_addr_size): /fragment@2: unnecessary #address-cells/#size-cells without "ranges" or child "reg" property
[ 3617.061703] fpga_manager fpga0: writing argsort_32_2_1.bin to Xilinx ZynqMP FPGA Manager
[ 3617.538577] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-full/firmware-name
[ 3617.561601] u-dma-buf udmabuf-argsort-in: driver version = 3.2.4
[ 3617.567613] u-dma-buf udmabuf-argsort-in: major number = 243
[ 3617.573445] u-dma-buf udmabuf-argsort-in: minor number = 0
[ 3617.579099] u-dma-buf udmabuf-argsort-in: phys address = 0x0000000070100000
[ 3617.586234] u-dma-buf udmabuf-argsort-in: buffer size = 33554432
[ 3617.592503] u-dma-buf amba_pl@0:udmabuf_argsort_in: driver installed.
[ 3617.608308] u-dma-buf udmabuf-argsort-out: driver version = 3.2.4
[ 3617.614407] u-dma-buf udmabuf-argsort-out: major number = 243
[ 3617.620323] u-dma-buf udmabuf-argsort-out: minor number = 1
[ 3617.626064] u-dma-buf udmabuf-argsort-out: phys address = 0x0000000072100000
[ 3617.633277] u-dma-buf udmabuf-argsort-out: buffer size = 33554432
[ 3617.639636] u-dma-buf amba_pl@0:udmabuf_argsort_out: driver installed.
[ 3617.682789] u-dma-buf udmabuf-argsort-tmp: driver version = 3.2.4
[ 3617.688883] u-dma-buf udmabuf-argsort-tmp: major number = 243
[ 3617.694800] u-dma-buf udmabuf-argsort-tmp: minor number = 2
[ 3617.700542] u-dma-buf udmabuf-argsort-tmp: phys address = 0x0000000074100000
[ 3617.707761] u-dma-buf udmabuf-argsort-tmp: buffer size = 134217728
[ 3617.714202] u-dma-buf amba_pl@0:udmabuf_argsort_tmp: driver installed.
テストの実行
サンプルデータの生成
ソートするデータのサンプルを用意します。サンプルデータを生成する Python スクリプト generage_sample.py を用意しています。生成するデータの大きさを指定してサンプルデータを生成します。このスクリプトを直接実行するか、rake コマンドから実行します。
fpga@debian-fpga:~/ArgSort-Kv260$ rake sample_0001000000.npy
python3 generate_sample.py --size 1000000 --sample sample_0001000000.npy
generate_sample: sample_file : sample_0001000000.npy
generate_sample: size : 1000000
generate_sample: time : 46.06 [msec]
期待値データの生成
サンプルデータを Python の numpy.argsort() を使ってソートしたデータを用意します。これは ArgSort-Kv260 によってソートした結果データと比較して正常にソートされたかをチェックするのに使います。期待値データを生成する Python のスクリプト generate_expect.py を用意しています。このスクリプトを直接実行するか、rake コマンドから実行します。ついでに期待値データを生成する時間を計測してログに残しておきます。
fpga@debian-fpga:~/ArgSort-Kv260$ rake expect_0001000000.npy
python3 generate_expect.py --sample sample_0001000000.npy --expect expect_0001000000.npy --log expect.log
generate_expect: sample_file : sample_0001000000.npy
generate_expect: expect_file : expect_0001000000.npy
generate_expect: size : 1000000
generate_expect: average_time : 954.065 # [msec]
generate_expect: throughput : 1.048 # [mwords/sec]
ArgSort-Kv260 を実行
ArgSort-Kv260 を実行してサンプルデータをソートします。ソートされた結果のデータを保存し、ソートにかかった時間を計測してログに残します。ArgSort-Kv260 を実行する Python スクリプト argsort_test.py を用意しています。また、ArgSort-Kv260 がソートした結果と numpy.argsort() がソートして期待値とを比較します。比較する Python スクリプト check_result.py を用意しています。これらのスクリプトを直接実行するか、rake コマンドから実行します。
fpga@debian-fpga:~/ArgSort-Kv260$ rake test_1000000
python3 argsort_test.py --sample sample_0001000000.npy --result result_0001000000.npy -n 10 -d 2 --log argsort_32_2_1.log
argsort_test : Version : 1.2
argsort_test : Ways : 32
argsort_test : Words : 2
argsort_test : Feedback : 1
argsort_test : WordBits : 32
argsort_test : IndexBits : 32
argsort_test : Sort Order : 0
argsort_test : Sign Compare : 0
argsort_test : Max Size : 268435455
argsort_test : Debug Enable : 1
argsort_test : sample_file : sample_0001000000.npy
argsort_test : size : 1000000
argsort_test : debug_mode : 2
argsort_test : loops : 10
argsort_test : time : 13.890 # [msec]
argsort_test : time : 13.813 # [msec]
argsort_test : time : 13.809 # [msec]
argsort_test : time : 13.822 # [msec]
argsort_test : time : 13.821 # [msec]
argsort_test : time : 13.823 # [msec]
argsort_test : time : 13.795 # [msec]
argsort_test : time : 13.813 # [msec]
argsort_test : time : 13.613 # [msec]
argsort_test : time : 13.820 # [msec]
argsort_test : result_file : result_0001000000.npy
argsort_test : average_time : 13.802 # [msec]
argsort_test : throughput : 72.453 # [mwords/sec]
argsort_test : Debug_Time(0): 11.903 # [msec]
argsort_test : Debug_Time(1): 7.053 # [msec]
argsort_test : Debug_Time(2): 2.534 # [msec]
argsort_test : Debug_Time(3): 2.316 # [msec]
python3 check_result.py --sample sample_0001000000.npy --result result_0001000000.npy --expect expect_0001000000.npy
check_result: sample file : sample_0001000000.npy
check_result: expect file : expect_0001000000.npy
check_result: result file : result_0001000000.npy
check_result: OK
アンインストール
デバイスツリーのアンインストール
テストが終わったらデバイスツリーをアンインストールします。別のデザインをインストールして実行するためには必ず現在のデザインをアンインストールしておく必要があります。アンインストールにもインストールと同様に Device Tree Overlay を使います。インストールと同様に rake コマンドを使ってアンインストールします。
fpga@debian-fpga:~/ArgSort-Kv260$ sudo rake uninstall
./dtbocfg.rb --remove argsort
[ 877.205843] u-dma-buf amba_pl@0:udmabuf_argsort_tmp: driver removed.
[ 877.217907] u-dma-buf amba_pl@0:udmabuf_argsort_out: driver removed.
[ 877.229861] u-dma-buf amba_pl@0:udmabuf_argsort_in: driver removed.
デザインのビルド
ビルド環境
- 開発ツール: Xilinx Vivado 2021.2
- IP: ArgSort_AXI IP 1.2、ZynqMP-ACP-Adapter IP v0.4
ArgSort-Kv260 のダウンロード
次のようにビルド用コンピューターに ArgSort-Kv260 をダウンロードします。
shell$ git clone --branch 1.2.1 --recursive git://github.com/ikwzm/ArgSort-Ultra96.git
shell$ cd ArgSort-Ultra96
ビルド用スクリプトファイル
各デザイン毎にスクリプトファイルを用意しています。 argsort_16_2_2 を例にすると次のようになります。
- argsort_16_2_2/
- create_project.tcl
- design_1.bif
- design_1_bd_2020.1.tcl
- design_1_bd_2020.2.tcl
- design_1_pin.xdc
- implementation.tcl
ビルド環境の設定
Xilinx Vivado 2021.2 が動作する環境を設定します。
shell$ source /opt/Xilinx/Vivado/2021.2/settings64.sh
プロジェクトの生成
プロジェクトを生成するためには、スクリプトが格納されているディレクトリに移動して vivado で create_project.tcl を実行します。以下の例では vivado のコマンドラインから実行しています。
shell$ cd argsort_16_2_2
shell$ vivado -mode batch -source create_project.tcl
論理合成と配置配線
プロジェクトの論理合成と配置配線をしてビットストリームファイルを生成するためには implementation.tcl を使用します。
shell$ vivado -mode batch -source implementation.tcl
生成されたビットストリームファイルは project.runs/impl_1/design_1_wrapper.bit です。なお、このスクリプトでビットストリームファイルを生成した場合は、使用リソースやタイミングチェックなどのレポートファイル project.rpt が生成されます。
バイナリ—ファイルの生成
ビットストリームファイルから PL はダウンロードするためのバイナリ—ファイルを生成するためには、bootgen コマンドと design_1.bif を使います。
shell$ bootgen -image design_1.bif -arch zynqmp -w -o ../argsort_16_2_2.bin
shell$ cd ..
shell$ gzip argsort_16_2_2.bin
所感
バス帯域について
ArgSort で使用しているマージソーターコアは「マルチワード マージソート ノード」で説明したように1クロックあたりに出力できるワード数を複数ワードにすることができます。ArgSort_AXI IP 1.2 ではこのパラメータの値は MRG_WORDS で指定します。
本来ならこのパラメータを1から2に変更することで性能が倍になるはずです。しかし 「ArgSort-Ultra96」 では残念ながら次の表のようにそれほどの性能の差はみられませんでした。これは Ultra96-V2 のシステムメモリである DDR-SDRAM は32bit(4Byte)×2(DDR分)×533MHz で 4.264GByte/sec しかなかったために起こったものでした。
Table.4 Ultra96-V2 におけるMRG_WORDSの違いによる性能の比較
Design | Throughput Average [Mwords/sec] |
MRG_WORDS 1-> 2 Up [%] |
|||
Name | MRG WAYS |
MRG WORDS |
STM FB |
||
argsort_16_1_0 | 16 | 1 | 0 | 18.75 | 28.69 % Up |
argsort_16_2_0 | 2 | 24.13 | |||
argsort_16_1_1 | 16 | 1 | 1 | 29.51 | 14.84 % Up |
argsort_16_2_1 | 2 | 33.89 | |||
argsort_16_1_2 | 16 | 1 | 2 | 36.04 | 11.02 % Up |
argsort_16_2_2 | 2 | 40.01 |
Kv260 のシステムメモリである DDR-SDRAM は64bit(8Byte)×2(DDR分)×533MHz で 8.528GByte/sec と Ultra96-V2 の倍あります。そのため、次の表のようにUltra96-V2 の性能差に比較して差が開いています。
Table.5 Kv260 におけるMRG_WORDSの違いによる性能の比較
Design | Throughput Average [Mwords/sec] |
MRG_WORDS 1-> 2 Up [%] |
|||
Name | MRG WAYS |
MRG WORDS |
STM FB |
||
argsort_16_1_0 | 16 | 1 | 0 | 28.59 | 42.95 % Up |
argsort_16_2_0 | 2 | 40.87 | |||
argsort_16_1_1 | 16 | 1 | 1 | 43.87 | 27.28 % Up |
argsort_16_2_1 | 2 | 59.95 | |||
argsort_16_1_2 | 16 | 1 | 2 | 45.67 | 45.11 % Up |
argsort_16_2_2 | 2 | 66.27 | |||
argsort_32_1_0 | 32 | 1 | 0 | 39.59 | 35.44 % Up |
argsort_32_2_0 | 2 | 53.62 | |||
argsort_32_1_1 | 32 | 1 | 1 | 54.79 | 31.61 % Up |
argsort_32_2_1 | 2 | 72.11 | |||
argsort_32_1_2 | 32 | 1 | 2 | 47.65 | 32.63 % Up |
argsort_32_2_2 | 2 | 63.20 |
参照
- 目次: 「はじめに」
- 前回: 「ArgSort-Ultra96」
- https://github.com/ikwzm/ArgSort-Kv260
- https://github.com/ikwzm/Merge_Sorter
- https://github.com/ikwzm/ZynqMP-FPGA-Linux
- https://github.com/ikwzm/ZynqMP-FPGA-Ubuntu20.04
- 『ZynqMP ACP と AXI をつなぐアダプタ』 @Qiita
- 『UltraZed/Ultra96/Ultra96-V2/KV260 向け Debian GNU/Linux (v2021.1版) ブートイメージの提供』@Qiita