5.1K Views
March 29, 23
スライド概要
フィックスターズならではの「FPGA」に関する高速化手法、効率的な開発ノウハウ、苦労話などについてお話しいたします。
<講演内容>
1.EasyNet を使った Vitis による 100 Gbps TCP Offloading
以前のセミナーで、Vitis で FPGA ネットワーク通信を行う方法 (第2回) や、Vitis AI と FPGA ネットワークを組み合わせた推論システムの作成方法(第10回) 等を紹介してきました。
一方で、これらのセミナーで実行していた通信は UDP のため、データの整合性は取れないなど不自由な点がありました。
EasyNet は、 オープンソースの Vitis から利用可能な TCP スタックです。
EasyNet では TCP Engine を FPGA 上にオフロードしているため、FPGA 内で高速な TCP パケット処理を実行可能です。
本セミナーでは、EasyNet と接続するアプリケーションの作り方を解説し、実際に Vitis Libraries のアプリケーションを接続したサンプルを作った例を示します。
2.Lightning Talk!
・open-nicの高速化
・当社技術ブログ 記事: https://proc-cpuinfo.fixstars.com/
・フィックスターズグループ/セミナー一覧: https://www.fixstars.com/ja/seminar
・フィックスターズのFPGAシステム開発: https://www.fixstars.com/ja/services/fpga
フィックスターズは、コンピュータの性能を最大限に引き出すソフトウェア開発のスペシャリストです。車載、産業機器、金融、医療など、幅広い分野での開発経験があります。また、ディープラーニングや機械学習などの最先端技術にも力を入れています。 並列化や最適化技術を駆使して、マルチコアCPU、GPU、FPGA、量子アニーリングマシンなど、さまざまなハードウェアでソフトウェアを高速化するサービスを提供しています。さらに、長年の経験から培ったハードウェアの知識と最適化ノウハウを活かし、高精度で高性能なアルゴリズムの開発も行っています。 ・開催セミナー一覧:https://www.fixstars.com/ja/seminar ・技術ブログ :https://proc-cpuinfo.fixstars.com/
実践的!FPGA開発セミナー vol.20 2023/03/29 18:00~ Copyright© Fixstars Group
EasyNet を使った Vitis による 100 Gbps TCP Offloading Copyright© Fixstars Group
Who I am Yuki MATSUDA 写真 松田 裕貴 ソリューション第四事業部 リードエンジニア Copyright© Fixstars Group
自己紹介 ● 松田裕貴 ○ 2016 年 4 月に Fixstars に入社 ○ ハードウェア開発をメインに、ソフトウェア開発なども担当 ○ ■ FPGA による画像処理・ネットワーク処理 ■ CPU / GPU 上の処理の高速化 RTL は極力書きたくない勢 Copyright© Fixstars Group
本日のセミナーについて ● これまでのセミナーでは、 Vitis を使った UDP アプリケーションの作り方等を紹介してきました ● ○ 第2回: Vitis で FPGA ネットワーク通信を手軽に試すテクニック ○ 第10回: Vitis-AI 2.0 + Alveo で自前のカーネル + DPU で動かしてみた 今回のセミナーでは TCP を使ったアプリを作ってみます ○ TCP Offload Engine を Vitis から使うためのプロジェクトである EasyNet を用いて、FPGA 上に TCP Server を実装してみる ○ EasyNet と Vitis Libraries の gzip を組み合わせて、 gzip server を構築してみる Copyright© Fixstars Group
目次 ● Introduction ● EasyNet を使ってみる ● EasyNet と Vitis Libraries の gzip を繋いでみる ● まとめ Copyright© Fixstars Group
TCP Offload Engine (TOE) とは ● TCP のパケット処理機能をハードウェア上にオフロードしたもの ● TOE に (最低限) 必要な機能 ○ コネクション確立 ■ ○ ○ Server の場合 Port Listen, Client の場合 Connect など パケットの順序制御・到達保護 ■ sequence 番号の付与・ack 送信 ■ checksum validation アプリケーションとの通信 ■ connect, listen, close といったコネクション管理 API の提供 ■ send, recv といったデータ通信 API の提供 Copyright© Fixstars Group
Xilinx FPGA 向けの TOE ● Xilinx FPGA 向けだと、以下のようなものが存在する ○ パートナー提供 ■ https://japan.xilinx.com/products/intellectual-property.html から toe で検索すると色々出てくる ○ オープンソース (HLS製、どちらも中身はほぼ同じ) ■ https://github.com/fpgasystems/fpga-network-stack ● ■ BSD 3-Clause License https://github.com/hpcn-uam/100G-fpga-network-stack-core/ ● BSD 3-Clause License ● Xilinx 公式の Vitis Network Example でも使用されている Copyright© Fixstars Group
fpga-network-stack ● https://github.com/fpgasystems/fpga-network-stack ● TOE 以外にも、TCP/IP 通信を実現するための機能が含まれている ● ○ Ethernet Header の parse/deparse ○ ARP による mac address の解決 (ARP Server) ○ ping による疎通確認 (ICMP Server) ○ UOE (UDP Offload Engine) 色々 IP が提供されているが、これを FPGA 上で動かすには Ethernet MAC, network stack, user function 等を繋ぐ必要がある ○ これが非常に面倒... Copyright© Fixstars Group
EasyNet ● ● FPL 2021 で提案された FPGA + TOE の評価環境 ○ https://ieeexplore.ieee.org/document/9556439 ○ source: https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP オープンソースの network stack を Vitis 経由で簡単に利用できるようにしたもの ● 他にも MPI-like communication primitive とかも追加 (今回は未使用) Copyright© Fixstars Group
Vitis になるとどうして開発が楽になるのか? ● 通常の FPGA 開発だと、ユーザは design top から全てを作る ○ ● Vitis による開発だとユーザはユーザロジックのみを作成すればよい (左図) ○ ● ピン配置、top module, etc. I/O 部分等はシェルとして事前に作成されている (ただしボードは固定) EasyNet の場合、シェルがネットワーク部分まで拡張したような形 (右図) ○ TCP を使うアプリケーションだけ FPGA に実装すればよい FPGA Shell xdma DDR FPGA Dynamic Region Shell User Logic Copyright© Fixstars Group Dynamic Region xdma Ether mac DDR NW stack EasyNet の提供するシェル User Logic
参考: FPGA 開発における内部接続の比較 (主観) RTL ● System Verilog 等で IP の接続を書く ● 記述量が多い ● generate 文とかは便利 ● design top から作る IP Integrator (右上図) ● GUI で IP を繋ぐので簡単 ● Intel の場合 Platform Designer相当 ● N 個回路を 並べるとかが少し辛い ● design top から作る Vitis ● テキストで論理的な IP の 接続を書く ● Intel の場合、 OneAPI, OpenCL など相当 ● ユーザロジックだけ作れば シェルと自動で繋がれる RTL IP Integrator Vitis 簡単さ × 〇 〇 柔軟性 〇 △ × 実装の範囲 回路全体 回路全体 ユーザロジックのみ 内部の動作 - RTL code を出力 IP Integrator の接続を出力 Copyright© Fixstars Group
目次 ● Introduction ● EasyNet を使ってみる ● EasyNet と Vitis Libraries の gzip を繋いでみる ● まとめ Copyright© Fixstars Group
EasyNet を動かしてみる ● ● EasyNet にはデフォルトでいくつかのユーザーカーネルが用意されている ○ iperf2 client/server ○ send kernel ○ recv kernel ○ gather kernel ○ all reduce kernel とりあえず iperf2 server を試してみる https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP Copyright© Fixstars Group
チュートリアルデザイン (iperf) を動かしてみる ● README 記載の通りにビルドをすると下図のようなデザインができる 接続定義ファイル Copyright© Fixstars Group
チュートリアルデザイン (iperf) を動かしてみる (cont.) ● ビットストリーム書き込み後、下図の Host 1 から iperf2 を実行する ○ 1回目で合成失敗などもなく、普通に動いた ○ i7-9700 環境で MTU=9000 時に 89.2 Gbps => 十分な性能 ■ MTU=1500 時は 21.5 Gbps ● Xeon Gold 6234 でスレッド数が多ければ 100 Gbps 近く出るらしい Host 1 NIC Copyright© Fixstars Group 100G cable Host 2 Alveo U250
目次 ● Introduction ● EasyNet を使ってみる ● EasyNet と Vitis Libraries の gzip を繋いでみる ● まとめ Copyright© Fixstars Group
EasyNet のインターフェース ● EasyNet の IF は左図。よく分からないので C コード (右図) で解説 https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP Copyright© Fixstars Group
Listen 処理 TOE から port 指定の Listen 要求 => Resp (ok, ng) が返る ① ② https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP Copyright© Fixstars Group
Accept 処理 Accept (Client の接続通知) に該当する操作はなし。内部的にSession ID が作られる https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP Copyright© Fixstars Group
Recv 処理 パケットがTOE に到着後、Notification が来る -> Read Request を送る -> Data が来る 1 パケット単位 (1500 Byte くらい) で届くのが CPU との違い ① ② ③ https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP Copyright© Fixstars Group
Send 処理 データの送信リクエストを送る -> ok か ng かのレスポンスが返る -> データを送る ① ③ ② https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP Copyright© Fixstars Group
Send 処理 データの送信リクエストを送る -> ok か ng かのレスポンスが返る -> データを送る 意味さえ分かれば割と簡単なインターフェース ① ③ ② https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP Copyright© Fixstars Group
GZip との接続 ● Vitis Libraries の xilGzipComp を使用して gzip 圧縮を行う ● 通常の AXIS Input と TUSER 付きの AXIS Output を持つ IP https://xilinx.github.io/Vitis_Libraries/data_compression/2022.1/source/L2/api_reference.html#xilgzipcomp Copyright© Fixstars Group
xilGzipComp の使い方 ● input: 圧縮したいデータを普通に AXIS で入れる ○ ● 末尾にtlast, 末尾以外のtkeep = ALL-1 output: ○ 圧縮後のデータが普通に AXIS で出てくる ○ AXIS の末尾のワードに圧縮後の length が出てくる input output Copyright© Fixstars Group
余談: xilGzipComp 単体の性能 ● xilGzipComp だけのプロジェクトを作って性能を計ってみた ○ データセット: http://www.mattmahoney.net/dc/textdata.html よりダウンロードできる wikipedia のダンプ ■ ○ 100MB, 1GB 比較対象: i5-4460 CPU, gzip command (デフォルトオプション) ● 特に上限サイズもなさそうで、性能も十分速い 1 GB 100 MB 圧縮サイズ 圧縮時間 CPU 35 MB 4.605 sec FPGA 41 MB 0.765 sec 圧縮サイズ 圧縮時間 CPU 309 MB 40.200 sec FPGA 365 MB 5.140 sec Copyright© Fixstars Group
EasyNet と gzip の接続 ● 下図のような形で簡単に接続できた (括弧内はコード行数) ○ Reader (186): Listen 開始、データ受信 ○ App Packetize (50): TCP 単位の TLAST をペイロード全体の TLAST に書き換える ■ 最初のパケットの先頭に全体の長さを入れて判別 ○ xilGzipComp: Vitis Libraries そのまま ○ Tcp Packetize (124): 圧縮後パケットを MTU 単位で分割する ○ Sender (99): データ送信 User Logic EasyNet Reader App Packetize xilGzip Comp Copyright© Fixstars Group Tcp Packetize Sender EasyNet
動かしてみた ● 圧縮後サイズが 1 パケット長未満のデータまでは動いた ○ ● Tcp Packetize のロジックが固まっていて、より長いデータは動かず... 反省点 ○ Vitis を使っているため実装は簡単だったが、 合成に 8時間かかってしまったため間に合わず ○ やっぱり FPGA で大変なのは合成時間... Copyright© Fixstars Group
Tips: Vitis (Alveo) での ILA の使い方 ● Vitis だとコンパイルオプションで ila を簡単に追加可能 ○ ● --dk chipscope:app_packetize_1:M_AXIS 普通に Vivado で FPGA に繋ぐだけだと ila が見えなかったので やり方を記載 ○ 基本的には https://docs.xilinx.com/r/en-US/ug1393-vitis-application-acceleration/Automated-S etup-for-Hardware-Debug の内容を実施すればよい Copyright© Fixstars Group
Tips: Vitis (Alveo) での ILA の使い方 (cont.) ● Alveo を搭載したマシンで次のコマンドを実行して hw_server を立ち上げる ○ ● debug_hw --xvc_pcie /dev/xfpga/xvc_pub.XX --hw_server 合成したマシンで次のコマンドで ltx を指定して vivado を立ち上げ ○ debug_hw --vivado --host <host_name> --ltx_file ./_x/link/vivado/vpl/prj/prj.runs/impl_1/debug_nets.ltx ● こうすると、HW Manager の画面が自動的に立ち上がり、 ila でのデバッグが可能 Copyright© Fixstars Group
まとめ ● EasyNet を使って TOE のシェルと gzip 回路を結合してみた ● 結果 合成時間が想定外に長かったため、全体は動かず... ○ ● 所感 ○ ○ お手軽に TOE を FPGA で触れるのはすごく良い ■ Vitis を使っているので実装はかなり簡単 ■ Vivado の GUI を使わなくて良いのが気軽で良い ■ このように色々な I/O を Vitis で触れるようになると楽でいいなーという感じ 結局合成時間が開発時間以上にかかるので、大きなものを作るとこっちがボトルネック ■ TOE までシェルに入れてユーザーロジックのみ DFX で合成できれば良いのかも Copyright© Fixstars Group
予備スライド ● xilGzipComp のリソース使用量 Copyright© Fixstars Group
Lightning Talk! Copyright© Fixstars Group
open-nicの高速化 Copyright© Fixstars Group
Who I am Takashi UCHIDA 内田 崇 ソリューション第四事業部 エンジニア Copyright© Fixstars Group
open-nicとは? ● AMD Xilinxから出ているFPGA designおよびdriver (https://github.com/Xilinx/open-nic) ● open source (Apache License 2.0) ● 内部ロジックをカスタムで追加可能 (今回は未実施) Copyright© Fixstars Group
open-nic の FPGA design 概要 ● HOST - FPGA 間の通信は PCIe 経由で QDMA で行われる ● QSFP の制御は CMAC IP が使用されて いる ● ユーザーロジックを追加できる領域は 2 箇所 (左図の灰色部) ● CMAC のポート数や QDMA の physical function の実装数などをパラメータ設 定可能 FPGA design 全体図 (githubのREADMEから抜粋) 引用元:https://github.com/Xilinx/open-nic-shell Copyright© Fixstars Group
性能確認環境 ● iperf で throughput を測定した ● 並列数を 8 で実行 (確保される queue が 8 本だったため) ● open-nic 側を server / client の各々で実行 ● 今回は「高速化 = throughput を上げる」の意味で使用 HOST 1 (Ubuntu 20.04.4 LTS) HOST 2 (Ubuntu 22.04.1 LTS) Alveo U250 (192.168.10.1) ConnectX-5 (192.168.10.2) 100Gbps DACケーブル Copyright© Fixstars Group
open-nic の性能確認確認 throughput [Gbps] open-nic (@client) open-nic (@server) 21.6 4.12 ● open-nic を iperf の server として実行した場合の性能が低い ● Receive 側の方が負荷が大きく、性能が下がりやすいのは一般的 ● Mellanox NIC(ConnectX-5) でも RSS (Recieve Side Scaling) などの対策が 取られている Copyright© Fixstars Group
iperf 実行時の CPU 使用率 ● open-nic を動作させている HOST の CPU (i5) の性能があま り高くなく resource を使いきっ ている ● open-nic 側の Host の性能を上 げて確認したほうが良いが、今回 はこのまま確認を継続した open-nic 側 ConnectX-5 側 Copyright© Fixstars Group
open-nic の RSS の動作確認
●
open-nic は RSS (Recieve Side Scaling) を サポートしている
●
仕組みは以下の通り
1.
driver install 時に driver から FPGA の register に qid を順に書き込む
2.
FPGA 側で Toeplitz で hash 値を計算し、結果を address として register から qid を
読み出す
/* inform shell about the function map */
val = (FIELD_SET(QDMA_FUNC_QCONF_QBASE_MASK, qbase) |
FIELD_SET(QDMA_FUNC_QCONF_NUMQ_MASK, qmax));
onic_write_reg(hw, QDMA_FUNC_OFFSET_QCONF(func_id), val);
/* initialize indirection table */
for (i = 0; i < 128; ++i) {
u32 val = (i % qmax) & 0x0000FFFF;
u32 offset = QDMA_FUNC_OFFSET_INDIR_TABLE(func_id, i);
onic_write_reg(hw, offset, val);
}
open-nic-driver code 抜粋
Copyright© Fixstars Group
open-nic の RSS の動作確認結果 ● ● ● 対向の Mellanox NIC から open-nic に 1000 回 ping を投げた結果を以下に示す 各 queue に概ね均等に割り振られている 割り付けられている core が偏っているのは driver で特にコントロールしていないからだと思われる ○ 今回実験している HOST が 4 core なのでその影響の可能性は十分考えられる $ cat /proc/interrupts CPU0 CPU1 CPU2 CPU3 34: 128 0 0 0 PCI-MSI 524288-edge 35: 114 0 0 0 PCI-MSI 524289-edge 36: 0 136 0 0 PCI-MSI 524290-edge 37: 0 0 0 142 PCI-MSI 524291-edge 38: 117 0 0 0 PCI-MSI 524292-edge 39: 0 124 0 0 PCI-MSI 524293-edge 40: 0 0 127 0 PCI-MSI 524294-edge 41: 0 0 0 143 PCI-MSI 524295-edge 42: 0 0 0 0 PCI-MSI 524296-edge 43: 0 0 0 0 PCI-MSI 524297-edge onic1s0f0-0 onic1s0f0-1 onic1s0f0-2 onic1s0f0-3 onic1s0f0-4 onic1s0f0-5 onic1s0f0-6 onic1s0f0-7 onic-user onic-error Copyright© Fixstars Group データ用 MSI-X 用
FPGA のボトルネックを確認する (open-nic @client) ● ● cmac への入力で ready が落とされている 入力の valid の頻度からするとあまり影響はないと考えられる Copyright© Fixstars Group
FPGA のボトルネックを確認する (open-nic @server) ● ● QDMA IP への入力 stream で ready が落ちている IP の処理があまり早くない可能性も 0 ではないが、HOST の処理が遅いためと思われる Copyright© Fixstars Group
open-nic-driver の修正 (MTU 設定値を上げる) ● FPGA 側のボトルネックはなさそう ● open-nic-driver を変更して throughput の向上を試みる ● 始めに MTU を上げる ○ default だと open-nic-driver は MTU を設定できるようにはなってい ないので、driver のコードを修正する必要がある Copyright© Fixstars Group
MTU 設定のための修正 1 ● netdev 構造体の max_mtu の値を 設定する ○ default 値は 1500 になっている $ git diff onic_main.c diff --git a/onic_main.c b/onic_main.c index b0eb3b1..bb70614 100644 --- a/onic_main.c +++ b/onic_main.c @@ -217,6 +217,8 @@ static int onic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } priv->pdev = pdev; priv->netdev = netdev; + priv->netdev->max_mtu = 9000; + spin_lock_init(&priv->tx_lock); spin_lock_init(&priv->rx_lock); Copyright© Fixstars Group
MTU 設定のための修正 2
●
ip command などで MTU 設定時に呼び出される関数内で引数で MTU 値を更新する
○
open-nic の default だと以下のように関数だけ準備されているので追加する
$ git diff onic_netdev.c
diff --git a/onic_netdev.c b/onic_netdev.c
index 7449092..0da634d 100644
--- a/onic_netdev.c
+++ b/onic_netdev.c
@@ -764,6 +764,7 @@ int onic_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
int onic_change_mtu(struct net_device *dev, int mtu)
{
netdev_info(dev, "Requested MTU = %d", mtu);
+
dev->mtu = mtu;
return 0;
}
Copyright© Fixstars Group
MTU 設定のための修正 3 ● FPGAの合成を option を以下のように指定して実行 vivado -mode batch -source build.tcl -tclargs -board au250 -max_pkt_len 9600 ● ここまで実行しても、 MTU は 4K までしか動作しなかった ○ 理由は driver 内で受信 queue の initialize 時に (packet size に関係なく) page size (4K) 分確保しているた め ○ 単純に 確保 size の数値を増やしてみたが効果がなかった ○ 上記のため iperf で MSS を 4000 にして性能を比較した Copyright© Fixstars Group
MSS = 4000 での iperf 測定結果 ● MSS open-nic (@client) open-nic (@server) 1500 21.6 4.12 4000 30.4 9.29 MSS = 1500 と比較して iperf の性能が両方向ともに向上することが確認 できた Copyright© Fixstars Group
open-nic-driver の改善 (QUEUE の数を増やせるか?) ● QUEUE の数は何段階か経て driver 内で最適化されるが、実質的には以下の 関数で制限されている ● kernel の関数をたどると、最終的には hardware の register を読んで決定 しているようで、software 的な変更は簡単ではなさそうだった vectors = pci_alloc_irq_vectors(priv->pdev, non_q_vectors + 1, vectors, PCI_IRQ_MSIX); Copyright© Fixstars Group
open-nic-dpdk ● open-nic が用意しているもう一つの driver ● 一般的に dpdk を使用すると kernel module の driver と比較してoverehead がなくなり、 buffer の size も拡大できそう ○ MTU の制約もなくなりそうだし、単純に速く動作すると期待できる 引用元:https://www.ntt-tx.co.jp/column/dpdk_blog/190610/ Copyright© Fixstars Group
open-nic-dpdk 結果 (動作まで至らず) ● open-nic-dpdk の github の手順通りに進めたが、Section 8 の bind が動作せず ● コードを追っていくと、lspci で得た Device が期待と異なっていてエラーになっていた ○ lspci で得られた結果は以下の通りだが、コードで期待してるのは実行時に引き渡す引 数 (vfio-pci) ○ なぜか qdma_pf (Xilinx の qdma driver)が default で load されてしまい、いろいろ 試したが解決に至らなかった $ lspci -vmmks 01:00.0 Slot: 01:00.0 Class: Memory controller Vendor: Xilinx Corporation Device: Device 903f SVendor: Xilinx Corporation SDevice: Device 0007 Module: qdma_pf open-nic-dpdk: https://github.com/Xilinx/open-nic-dpdk Copyright© Fixstars Group
まとめ ● open-nic-driver を MTU を設定できるように変更したところ多少の性能向上 (最大 30.04 Gbps) が得られた ● open-nic-dpdk での改善を期待したが、今回は動作まで至らなかった Copyright© Fixstars Group
Thank you! お問い合わせ窓口 : [email protected] Copyright © Fixstars Group