Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実践的!FPGA開発セミナーvol.20 / FPGA_seminar_20_fixstars...

実践的!FPGA開発セミナーvol.20 / FPGA_seminar_20_fixstars_corporation_20230329

2023年3月29日に開催した、「実践的!FPGA開発セミナーvol.20」の当日資料です。

More Decks by 株式会社フィックスターズ

Other Decks in Programming

Transcript

  1. Copyright© Fixstars Group Who I am 写真 Yuki MATSUDA 松田

    裕貴 ソリューション第四事業部  リードエンジニア
  2. Copyright© Fixstars Group 自己紹介 • 松田裕貴 ◦ 2016 年 4

    月に Fixstars に入社 ◦ ハードウェア開発をメインに、ソフトウェア開発なども担当 ▪ FPGA による画像処理・ネットワーク処理 ▪ CPU / GPU 上の処理の高速化 ◦ RTL は極力書きたくない勢
  3. 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 を構築してみる
  4. Copyright© Fixstars Group 目次 • Introduction • EasyNet を使ってみる •

    EasyNet と Vitis Libraries の gzip を繋いでみる • まとめ
  5. 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 の提供
  6. 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 でも使用されている
  7. 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 等を繋ぐ必要がある ◦ これが非常に面倒...
  8. 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 とかも追加 (今回は未使用)
  9. Copyright© Fixstars Group Vitis になるとどうして開発が楽になるのか? • 通常の FPGA 開発だと、ユーザは design

    top から全てを作る ◦ ピン配置、top module, etc. • Vitis による開発だとユーザはユーザロジックのみを作成すればよい (左図) ◦ I/O 部分等はシェルとして事前に作成されている (ただしボードは固定) • EasyNet の場合、シェルがネットワーク部分まで拡張したような形 (右図) ◦ TCP を使うアプリケーションだけ FPGA に実装すればよい FPGA Shell xdma DDR Dynamic Region User Logic FPGA Shell xdma DDR Dynamic Region User Logic Ether mac NW stack EasyNet の提供するシェル
  10. Copyright© Fixstars Group 参考: FPGA 開発における内部接続の比較 (主観) RTL IP Integrator

    Vitis 簡単さ × 〇 〇 柔軟性 〇 △ × 実装の範囲 回路全体 回路全体 ユーザロジックのみ 内部の動作 - RTL code を出力 IP Integrator の接続を出力 RTL • System Verilog 等で IP の接続を書く • 記述量が多い • generate 文とかは便利 • design top から作る IP Integrator (右上図) • GUI で IP を繋ぐので簡単 • Intel の場合 Platform Designer相当 • N 個回路を 並べるとかが少し辛い • design top から作る Vitis • テキストで論理的な IP の 接続を書く • Intel の場合、 OneAPI, OpenCL など相当 • ユーザロジックだけ作れば シェルと自動で繋がれる
  11. Copyright© Fixstars Group 目次 • Introduction • EasyNet を使ってみる •

    EasyNet と Vitis Libraries の gzip を繋いでみる • まとめ
  12. 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
  13. 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 Host 2 Alveo U250 100G cable
  14. Copyright© Fixstars Group 目次 • Introduction • EasyNet を使ってみる •

    EasyNet と Vitis Libraries の gzip を繋いでみる • まとめ
  15. Copyright© Fixstars Group EasyNet のインターフェース • EasyNet の IF は左図。よく分からないので

    C コード (右図) で解説 https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP
  16. Copyright© Fixstars Group Recv 処理 https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP パケットがTOE に到着後、Notification が来る ->

    Read Request を送る -> Data が来る 1 パケット単位 (1500 Byte くらい) で届くのが CPU との違い ① ② ③
  17. Copyright© Fixstars Group Send 処理 https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP データの送信リクエストを送る -> ok か

    ng かのレスポンスが返る -> データを送る ① ② ③ 意味さえ分かれば割と簡単なインターフェース
  18. 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
  19. Copyright© Fixstars Group xilGzipComp の使い方 • input: 圧縮したいデータを普通に AXIS で入れる

    ◦ 末尾にtlast, 末尾以外のtkeep = ALL-1 • output: ◦ 圧縮後のデータが普通に AXIS で出てくる ◦ AXIS の末尾のワードに圧縮後の length が出てくる input output
  20. Copyright© Fixstars Group 余談: xilGzipComp 単体の性能 • xilGzipComp だけのプロジェクトを作って性能を計ってみた ◦

    データセット: http://www.mattmahoney.net/dc/textdata.html よりダウンロードできる wikipedia のダンプ ▪ 100MB, 1GB ◦ 比較対象: i5-4460 CPU, gzip command (デフォルトオプション) • 特に上限サイズもなさそうで、性能も十分速い 圧縮サイズ 圧縮時間 CPU 35 MB 4.605 sec FPGA 41 MB 0.765 sec 圧縮サイズ 圧縮時間 CPU 309 MB 40.200 sec FPGA 365 MB 5.140 sec 100 MB 1 GB
  21. 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 Tcp Packetize EasyNet Sender
  22. Copyright© Fixstars Group 動かしてみた • 圧縮後サイズが 1 パケット長未満のデータまでは動いた ◦ Tcp

    Packetize のロジックが固まっていて、より長いデータは動かず... • 反省点 ◦ Vitis を使っているため実装は簡単だったが、 合成に 8時間かかってしまったため間に合わず ◦ やっぱり FPGA で大変なのは合成時間...
  23. 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 の内容を実施すればよい
  24. 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 でのデバッグが可能
  25. Copyright© Fixstars Group まとめ • EasyNet を使って TOE のシェルと gzip

    回路を結合してみた • 結果 ◦ 合成時間が想定外に長かったため、全体は動かず... • 所感 ◦ お手軽に TOE を FPGA で触れるのはすごく良い ▪ Vitis を使っているので実装はかなり簡単 ▪ Vivado の GUI を使わなくて良いのが気軽で良い ▪ このように色々な I/O を Vitis で触れるようになると楽でいいなーという感じ ◦ 結局合成時間が開発時間以上にかかるので、大きなものを作るとこっちがボトルネック ▪ TOE までシェルに入れてユーザーロジックのみ DFX で合成できれば良いのかも
  26. Copyright© Fixstars Group Who I am Takashi UCHIDA 内田 崇

    ソリューション第四事業部  エンジニア
  27. Copyright© Fixstars Group open-nicとは? • AMD Xilinxから出ているFPGA designおよびdriver (https://github.com/Xilinx/open-nic) •

    open source (Apache License 2.0) • 内部ロジックをカスタムで追加可能 (今回は未実施)
  28. 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
  29. Copyright© Fixstars Group 性能確認環境 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ケーブル • iperf で throughput を測定した • 並列数を 8 で実行 (確保される queue が 8 本だったため) • open-nic 側を server / client の各々で実行 • 今回は「高速化 = throughput を上げる」の意味で使用
  30. Copyright© Fixstars Group open-nic の性能確認確認 open-nic (@client) open-nic (@server) throughput

    [Gbps] 21.6 4.12 • open-nic を iperf の server として実行した場合の性能が低い • Receive 側の方が負荷が大きく、性能が下がりやすいのは一般的 • Mellanox NIC(ConnectX-5) でも RSS (Recieve Side Scaling) などの対策が 取られている
  31. Copyright© Fixstars Group iperf 実行時の CPU 使用率 • open-nic を動作させている

    HOST の CPU (i5) の性能があま り高くなく resource を使いきっ ている • open-nic 側の Host の性能を上 げて確認したほうが良いが、今回 はこのまま確認を継続した open-nic 側 ConnectX-5 側
  32. 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 抜粋
  33. 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 onic1s0f0-0 35: 114 0 0 0 PCI-MSI 524289-edge onic1s0f0-1 36: 0 136 0 0 PCI-MSI 524290-edge onic1s0f0-2 37: 0 0 0 142 PCI-MSI 524291-edge onic1s0f0-3 38: 117 0 0 0 PCI-MSI 524292-edge onic1s0f0-4 39: 0 124 0 0 PCI-MSI 524293-edge onic1s0f0-5 40: 0 0 127 0 PCI-MSI 524294-edge onic1s0f0-6 41: 0 0 0 143 PCI-MSI 524295-edge onic1s0f0-7 42: 0 0 0 0 PCI-MSI 524296-edge onic-user 43: 0 0 0 0 PCI-MSI 524297-edge onic-error データ用 MSI-X 用
  34. Copyright© Fixstars Group FPGA のボトルネックを確認する (open-nic @client) • cmac への入力で

    ready が落とされている • 入力の valid の頻度からするとあまり影響はないと考えられる
  35. Copyright© Fixstars Group FPGA のボトルネックを確認する (open-nic @server) • QDMA IP

    への入力 stream で ready が落ちている • IP の処理があまり早くない可能性も 0 ではないが、HOST の処理が遅いためと思われる
  36. Copyright© Fixstars Group open-nic-driver の修正 (MTU 設定値を上げる) • FPGA 側のボトルネックはなさそう

    • open-nic-driver を変更して throughput の向上を試みる • 始めに MTU を上げる ◦ default だと open-nic-driver は MTU を設定できるようにはなってい ないので、driver のコードを修正する必要がある
  37. 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);
  38. 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; }
  39. Copyright© Fixstars Group MTU 設定のための修正 3 • FPGAの合成を option を以下のように指定して実行

    • ここまで実行しても、 MTU は 4K までしか動作しなかった ◦ 理由は driver 内で受信 queue の initialize 時に (packet size に関係なく) page size (4K) 分確保しているた め ◦ 単純に 確保 size の数値を増やしてみたが効果がなかった ◦ 上記のため iperf で MSS を 4000 にして性能を比較した vivado -mode batch -source build.tcl -tclargs -board au250 -max_pkt_len 9600
  40. Copyright© Fixstars Group MSS = 4000 での iperf 測定結果 •

    MSS = 1500 と比較して iperf の性能が両方向ともに向上することが確認 できた MSS open-nic (@client) open-nic (@server) 1500 21.6 4.12 4000 30.4 9.29
  41. 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);
  42. 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/
  43. 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
  44. Copyright© Fixstars Group まとめ • open-nic-driver を MTU を設定できるように変更したところ多少の性能向上 (最大

    30.04 Gbps) が得られた • open-nic-dpdk での改善を期待したが、今回は動作まで至らなかった