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

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

実践的!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
    実践的!FPGA開発セミナー
    vol.20
    2023/03/29 18:00~

    View Slide

  2. Copyright© Fixstars Group
    EasyNet を使った Vitis による
    100 Gbps TCP Offloading

    View Slide

  3. Copyright© Fixstars Group
    Who I am
    写真
    Yuki
    MATSUDA
    松田 裕貴
    ソリューション第四事業部 
    リードエンジニア

    View Slide

  4. Copyright© Fixstars Group
    自己紹介
    ● 松田裕貴
    ○ 2016 年 4 月に Fixstars に入社
    ○ ハードウェア開発をメインに、ソフトウェア開発なども担当
    ■ FPGA による画像処理・ネットワーク処理
    ■ CPU / GPU 上の処理の高速化
    ○ RTL は極力書きたくない勢

    View Slide

  5. 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 を構築してみる

    View Slide

  6. Copyright© Fixstars Group
    目次
    ● Introduction
    ● EasyNet を使ってみる
    ● EasyNet と Vitis Libraries の gzip を繋いでみる
    ● まとめ

    View Slide

  7. 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 の提供

    View Slide

  8. 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 でも使用されている

    View Slide

  9. 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 等を繋ぐ必要がある
    ○ これが非常に面倒...

    View Slide

  10. 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 とかも追加 (今回は未使用)

    View Slide

  11. 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 の提供するシェル

    View Slide

  12. 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 など相当
    ● ユーザロジックだけ作れば
    シェルと自動で繋がれる

    View Slide

  13. Copyright© Fixstars Group
    目次
    ● Introduction
    ● EasyNet を使ってみる
    ● EasyNet と Vitis Libraries の gzip を繋いでみる
    ● まとめ

    View Slide

  14. 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

    View Slide

  15. Copyright© Fixstars Group
    チュートリアルデザイン (iperf) を動かしてみる
    ● README 記載の通りにビルドをすると下図のようなデザインができる
    接続定義ファイル

    View Slide

  16. 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

    View Slide

  17. Copyright© Fixstars Group
    目次
    ● Introduction
    ● EasyNet を使ってみる
    ● EasyNet と Vitis Libraries の gzip を繋いでみる
    ● まとめ

    View Slide

  18. Copyright© Fixstars Group
    EasyNet のインターフェース
    ● EasyNet の IF は左図。よく分からないので C コード (右図) で解説
    https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP

    View Slide

  19. Copyright© Fixstars Group
    Listen 処理
    https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP


    TOE から port 指定の Listen 要求 => Resp (ok, ng) が返る

    View Slide

  20. Copyright© Fixstars Group
    Accept 処理
    https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP
    Accept (Client の接続通知) に該当する操作はなし。内部的にSession ID が作られる

    View Slide

  21. Copyright© Fixstars Group
    Recv 処理
    https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP
    パケットがTOE に到着後、Notification が来る -> Read Request を送る -> Data が来る
    1 パケット単位 (1500 Byte くらい) で届くのが CPU との違い



    View Slide

  22. Copyright© Fixstars Group
    Send 処理
    https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP
    データの送信リクエストを送る -> ok か ng かのレスポンスが返る -> データを送る



    View Slide

  23. Copyright© Fixstars Group
    Send 処理
    https://github.com/fpgasystems/Vitis_with_100Gbps_TCP-IP
    データの送信リクエストを送る -> ok か ng かのレスポンスが返る -> データを送る



    意味さえ分かれば割と簡単なインターフェース

    View Slide

  24. 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

    View Slide

  25. Copyright© Fixstars Group
    xilGzipComp の使い方
    ● input: 圧縮したいデータを普通に AXIS で入れる
    ○ 末尾にtlast, 末尾以外のtkeep = ALL-1
    ● output:
    ○ 圧縮後のデータが普通に AXIS で出てくる
    ○ AXIS の末尾のワードに圧縮後の length が出てくる
    input
    output

    View Slide

  26. 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

    View Slide

  27. 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

    View Slide

  28. Copyright© Fixstars Group
    動かしてみた
    ● 圧縮後サイズが 1 パケット長未満のデータまでは動いた
    ○ Tcp Packetize のロジックが固まっていて、より長いデータは動かず...
    ● 反省点
    ○ Vitis を使っているため実装は簡単だったが、
    合成に 8時間かかってしまったため間に合わず
    ○ やっぱり FPGA で大変なのは合成時間...

    View Slide

  29. 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 の内容を実施すればよい

    View Slide

  30. 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 --ltx_file
    ./_x/link/vivado/vpl/prj/prj.runs/impl_1/debug_nets.ltx
    ● こうすると、HW Manager の画面が自動的に立ち上がり、
    ila でのデバッグが可能

    View Slide

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

    View Slide

  32. Copyright© Fixstars Group
    予備スライド
    ● xilGzipComp のリソース使用量

    View Slide

  33. Copyright© Fixstars Group
    Lightning Talk!

    View Slide

  34. Copyright© Fixstars Group
    open-nicの高速化

    View Slide

  35. Copyright© Fixstars Group
    Who I am
    Takashi
    UCHIDA
    内田 崇
    ソリューション第四事業部 
    エンジニア

    View Slide

  36. Copyright© Fixstars Group
    open-nicとは?
    ● AMD Xilinxから出ているFPGA designおよびdriver
    (https://github.com/Xilinx/open-nic)
    ● open source (Apache License 2.0)
    ● 内部ロジックをカスタムで追加可能 (今回は未実施)

    View Slide

  37. 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

    View Slide

  38. 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 を上げる」の意味で使用

    View Slide

  39. 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) などの対策が
    取られている

    View Slide

  40. Copyright© Fixstars Group
    iperf 実行時の CPU 使用率
    ● open-nic を動作させている
    HOST の CPU (i5) の性能があま
    り高くなく resource を使いきっ
    ている
    ● open-nic 側の Host の性能を上
    げて確認したほうが良いが、今回
    はこのまま確認を継続した
    open-nic 側
    ConnectX-5 側

    View Slide

  41. 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 抜粋

    View Slide

  42. 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 用

    View Slide

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

    View Slide

  44. Copyright© Fixstars Group
    FPGA のボトルネックを確認する (open-nic @server)
    ● QDMA IP への入力 stream で ready が落ちている
    ● IP の処理があまり早くない可能性も 0 ではないが、HOST の処理が遅いためと思われる

    View Slide

  45. Copyright© Fixstars Group
    open-nic-driver の修正 (MTU 設定値を上げる)
    ● FPGA 側のボトルネックはなさそう
    ● open-nic-driver を変更して throughput の向上を試みる
    ● 始めに MTU を上げる
    ○ default だと open-nic-driver は MTU を設定できるようにはなってい
    ないので、driver のコードを修正する必要がある

    View Slide

  46. 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);

    View Slide

  47. 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;
    }

    View Slide

  48. 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

    View Slide

  49. 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

    View Slide

  50. 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);

    View Slide

  51. 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/

    View Slide

  52. 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

    View Slide

  53. Copyright© Fixstars Group
    まとめ
    ● open-nic-driver を MTU を設定できるように変更したところ多少の性能向上
    (最大 30.04 Gbps) が得られた
    ● open-nic-dpdk での改善を期待したが、今回は動作まで至らなかった

    View Slide

  54. Copyright © Fixstars Group
    Thank you!
    お問い合わせ窓口 : [email protected]

    View Slide