1 ポイント 投稿者 GN⁺ 5 시간 전 | 1件のコメント | WhatsAppで共有
  • nbd-vramは、LinuxでNVIDIA GPUのアイドル状態のVRAMを高優先度のスワップ領域として使えるようにする小さなデーモン
  • はんだ付けメモリでアップグレードが難しく、内蔵AMD/ATI GPUが画面出力を担うハイブリッドグラフィックスノートPCで、遊休状態のNVIDIA VRAMをメモリ圧迫の緩和に活用
  • テスト環境は AMD/ATI + RTX 3070 Laptop、RAM 16GB、VRAM 8GB、NVIDIA driver 580.159.03、kernel 6.17、Pop!_OS で、VRAM 7GBをスワップとして割り当て、zram・SSDスワップまで含めて約46GBのアドレス指定可能メモリを構成
  • 動作順序は、まずRAMが埋まり、次にVRAMがPCIe経由であふれたページを吸収し、その後zramがCPUで圧縮し、最後にSSDを使う構成
  • デーモンはCUDA driver APIでVRAMを割り当て、Unix socket上の**NBD(Network Block Device)**プロトコルでブロックデバイスを提供し、カーネル内蔵のnbdドライバが/dev/nbdXとして公開して通常のスワップデバイスのように使う
  • データパスは kernel swap subsystem → /dev/nbdX → nbd kernel driver → Unix socket → nbd-vram daemon → cuMemcpyHtoD/DtoH → GPU VRAM と続く
  • 別途カーネルモジュールやNVIDIAカーネルシンボルが不要なため、カーネル・ドライバ更新後も再ビルドなしで維持できる
  • NVIDIA P2P API方式は consumer GeForce GPU で nvidia_p2p_get_pages_persistentEINVAL を返し、BAR1直接 ioremap_wc 方式も約16MiBのディスプレイフレームバッファ以外の領域読み取りが0を返して失敗
  • CUDAコピー経路である cuMemcpyHtoDcuMemcpyDtoH は特別な権限なしでCUDA GPU上で動作するため、NBDアクセスがP2P・BAR1の制約を回避
  • 要件は、CUDA対応NVIDIA GPU、libcuda.so.1 があるNVIDIAドライバ、Linux kernel 3.0+ の nbd モジュール、nbd-clientgccmake で、CUDA toolkit は不要
  • インストール後は vram-swap-nbd systemd サービスが起動時に自動実行され、/etc/systemd/system/vram-swap-nbd.serviceVRAM_SETUP_SIZE_MBVRAM_SWAP_PRIORITY で使用するVRAM上限とスワップ優先度を調整
  • デーモンは要求されたVRAMサイズをまず試し、GPUメモリが不足している場合は512MiB単位で減らして割り当てるため、VRAM_SETUP_SIZE_MB は必須サイズではなく上限として動作
  • 電源認識管理を有効にすると、AC電源が外れたときやバッテリー残量がしきい値以下のときにサービスが自動停止し、電源が復旧すると再起動し、手動の systemctl stop は上書きしない
  • RTX 3070 Laptop ベンチマークでは、シーケンシャルスループットと持続的ランダムI/OはNVMeのほうが速いが、4K読み取り 1 request/sec のレイテンシはVRAMが平均335usで、NVMeの9.05msより27倍高速
  • MITライセンスで提供され、リポジトリにはスモークテスト用 test-nbd.sh、全パーティション検査用 test-fill.sh、スループット・IOPS・レイテンシのベンチマークスクリプトも含まれる

1件のコメント

 
GN⁺ 5 시간 전
Hacker Newsのコメント
  • CUDA経由でファイルストレージやマウントのように扱うとオーバーヘッドが大きいので、BAR を使えばスループットや IOPS を確実に改善できそう

  • はんだ付けメモリでアップグレードの余地がないノートPC向けという説明なら、高価な RAM からさらに高価な RAM へなぜスワップするのかという即座の疑問には答えになっている
    用途は限定的に見えるが、SSD にスワップされる状況では遊んでいる 8GB の VRAM を使うのは、必要なときには良いアイデア

    • もう1つの理由として、VRAM はあっても常に使うわけではない場合がある
      たとえばゲーム用に GPU を買ったなら、ゲームしていないときにデスクトップ描画で 16GB VRAM は不要なのだから、別用途に使ってもよいのではと思う
      ただしゲームを起動するときに、スワップとして使っていた VRAM をシステムが解放できるという前提が必要で、実際に可能なのかは気になる
    • VRAM を通常の RAM のように実際に使えるのか? たとえば 16GB の RAM モジュールがあり GPU に 16GB VRAM があるとして、システム上で 32GB RAM と表示されるようにできるのか、その影響はどうなるのか気になる
    • 昔はこういうものを RAM ディスク と呼んでいて、Atari ST はものすごく速くなった
      80年代半ばから90年代半ばまで英国で一般的だった Amstrad PCW では最大 512kB の RAM が使え、そのかなり大きな部分を RAM ディスクにできた
      Turbo Pascal のコンパイルもとても速くなった :-)
  • アイデアは良いが、ここでは何か大きく間違っている気がする
    RTX 3070 Laptop でシーケンシャルスループットが約 1.3 GB/s とのことだが、この RTX 3070 チップは PCIe 4.0 x16 なので 64GB/s 出るはずで、8GB GDDR6 自体は 448GB/s ある
    NVMe ドライブへスワップするほうが2倍は速いだろうが、レイテンシはより高いはず

    • PCIe 4.0 x16 は片方向 32 GB/s であり、この実装方式は高性能が必要なときに選ぶやり方ではない
      ベンチマークも ZRAM を使って回しているが、ZRAM はスワップへ書く前にページを圧縮する。その性能オーバーヘッドが正確にどれほどかは分からないが、かなり大きい可能性がある
      まずユーザー空間プログラムが、遅いことで知られる nbd ドライバ越しにぶら下がっており、GPU へ転送する前にユーザー空間のバウンスバッファも使っている。カーネルがページをスワップしなければならない場合、まずユーザー空間に公開されたバッファへコピーし、その後ユーザー空間プログラムが再び起きて CUDA 操作を発行し、そのページをデバイスメモリへコピーしなければならない
      nbd は高いキュー深度や隣接アクセスのマージもあまりうまく扱えない。カーネルがマージなしで 4K ページのスワップを大量に発行すると、4 GB/s を処理するだけでも毎秒少なくとも100万回のカーネル/ユーザー空間コンテキストスイッチが必要になる。64 GB/s などなおさらだ。これは NBD 部分だけを見た話で、NVIDIA ドライバの複雑さは含んでいない
      PCIe は大量のデータを運べるが、総帯域に近づけるには長いページリストを持つ DMA エンジン を使う必要がある。PCIe で 4K ページごとに転送を設定していたのでは、バスを完全に飽和させることはできない
      NVMe へのスワップ経路は非常によく最適化されている。スワッパーはページリストを NVMe ドライバへ直接提出でき、コントローラが RAM から直接 DMA で取り込むので、CPU 側のコピーやコンテキストスイッチは一切ない
      ublk ドライバへ移せばユーザー空間のバウンスバッファを避けられるかもしれず、複数の書き込みキューで CUDA コピーを並列に設定することもできるので、改善の余地はある
    • NVMe へスワップすると NAND の PE サイクル も消費し、時間とともに摩耗する
      RAM や VRAM は使っても劣化しない
  • 開発マシンに 32GB RAM と、AI モデルを動かしていないときは大半が遊んでいる 32GB VRAM があるので、このアイデアはそこまで悪くない

    • これは pcmasterrace 的な、上半身だけ大きくて脚がひょろひょろな体つきみたいな感じだ
  • バックプレッシャー をどう扱うのか気になる。VRAM がスワップ領域として使われている間に VRAM 割り当て要求が来たらどうなるのか?
    X11 ではバッファが事前確保されるのでまだましだが、Wayland では割り当てがずっと動的なので、VRAM が足りなくなるとデスクトップ全体が簡単に死にうる
    Hyprland+llama-server+KVM でコンピュータを切り替えているとき、VRAM を解放できずにこうしたクラッシュを何度か経験した

  • ユーザーレベルで スワップデバイス を作るのは、昔から古典的な解決不能問題の1つだった
    デーモンがページをスワップインしようとしているが、そのページをスワップインするにはデーモン自身のページを先にスワップインしなければならない場合はどうするのか?
    少なくともマイクロカーネルが絶対に動かない理由として、こうした議論があった。ここでの解法が何なのかはよく分からない

    • デーモンが自分のページを把握できるほど賢くて、そのページがスワップアウトされないよう防げばよい
      Linux カーネルも自分のテキストページがスワップアウトされないようにしているのだから、解法はすでにあり、マイクロカーネル設計にも適用できない理由は分からない
    • 一般原則として、ページングに関わるもの自体はページングされてはならない ということ
      そのデーモン全体のメモリを固定しておけば、この問題は些細なものになる
  • 昔 Linux の MTD/phram ドライバで似たようなことをやった記憶がある: https://wiki.archlinux.org/title/Swap_on_video_RAM
    ただ、今でも関係があるのかは分からない。DRM とどう相互作用するのか、VRAM の一部を予約する処理をどうやるのかが分からないからだ。xorg.conf で制限を提案する方式は、今ではかなり時代遅れかもしれない
    そのページには OpenCL 上に実装した FUSE ファイルシステムもある: https://github.com/Overv/vramfs
    こちらのほうが互換性は高いかもしれない

    • 昔 mtd 経由で 8MB のビデオメモリ をマップして使っていて、そのおかげで、あの… X11 ドライバ群をビルドするのに役立った
      懐かしい
  • Windows でも数年前に似たようなものを見たことがある
    NVIDIA カードの VRAM で RAM ドライブを作れるようにする実験的な概念実証ドライバで、シーケンシャルアクセスは予想どおり速いが、ランダムアクセスはまだ改善の余地が大きかった
    GpuRamDrive は GPU RAM をバックエンドにした仮想ドライブを作る: https://github.com/prsyahmi/GpuRamDrive
    AMD 対応フォーク: https://github.com/brzz/GpuRamDrive/

  • 似ているが OpenCL API を使うので AMD でも動く
    ただし AMD ドライバはかなりバグが多いので、「動く」の定義は必要だ: https://libguestfs.org/nbdkit-vram-plugin.1.html

  • 32GB RAM 搭載の Apple Silicon Mac で、20GB がまだ未使用/“free” なのに、なぜスワップファイルを使ったり、さらには作成したりするのか分からない
    Linux の swapoff -a のような簡単なコマンドで スワップファイルを完全に無効化 できないのはなぜなのか?
    SSD の寿命をわざわざ縮めるのが目的でないなら、かなり愚かに見える
    GUI でスワップファイルを無効にするシステム設定があってほしいし、Apple が今のシステム設定/レイアウトの「段階」をようやく捨ててもよいと思う。何十年も続いた環境設定パネルと比べても、いまだに単語サラダのようだ
    #Apple #Feedback #swapfile

    • ページングシステムの原則は、主記憶が補助記憶のキャッシュ だということ
      「利用可能メモリ」という概念も、理想的には「別の目的のために素早く回収できるメモリ」に近い
      ある時点では、匿名メモリを主記憶に置き続けるより、キャッシュされたファイル内容にその場所を占めさせるほうが良いこともある