Ryuz's tech blog

FPGAなどの技術ブログ

なぜGPUはリアルタイム処理に向かないのか

はじめに

久しく CUDA プログラミングもしていないなと思いつつ、久々に Wiki で RTX5090 などのスペック眺めてたら、凄いことになっているなと思ったので自分への備忘録も兼ねて記事にしておきます。

あと、あくまで当サイトがメインとするFPGAと比べて、GPUがリアルタイム処理に向かないというお話で、FPGAがGPUよりリアルタイムに強いと言われる話を裏返して考えてみようというものです。 用途によってリアルタイムの定義も変わってきますし、GPUがデータセンターなどでの大量のデータプロセッシングで十分な応答性で高いパフォーマンスを出しているのもその通りです。

先日書いた「続・FPGAに対する誤解」や「なぜGPUは高性能なのか」を少し補完するものにもなるかと思います。

最近の NVIDIA RTX のスペック

RTX4090 と RTX5090 のざっくりと重要な数字だけ拾って換算してみました。

下記のような感じでしょうか。

RTX 4090 RTX 5090
SM数 128 170
CUDAコア数 16,384 21,760
レジスタ数 8,388,608 11,141,120
最大スレッド数 262,144 348,160

1 つの SM に最大で 2048個のアクティブスレッド(64 WARP)を収容することができるようです。 またこの世代では 1 つの SM に 128個の物理コアが入っているようです。

GPGPUではその性能を最大限に出すためには、物理コア数以上にコア数以上のスレッドを割り当てる必要があります。 これは、実際のコアの実行でメモリアクセス待ちなどのタイミングで、別WARPを実行してパイプラインを埋めることで性能を出す仕組みになっているためです。

また、GPGPU ではスレッドの数に合わせて大量のレジスタは持っているものの、インストラクションデコーダは1つであり、基本的には「同じ演算を大量に並列で行う」ことを前提にしています。

従って最新のGPGPUで性能を出そうとすると、348,160スレッド などで並列演算できるだけのデータを用意する必要があります。

GPGU がリアルタイム演算が苦手な理由

ここがそのまま GPGPU がリアルタイム演算が苦手な本質的な部分に繋がります。

例えば SSD や YOLO などの画像認識では 512x512 などの画像サイズを処理しますが、512x512=262,144ピクセル でやっと RTX4090 の 262,144スレッドが埋まります。なんと RTX 5090 だとこの程度の画像だと、ピクセル数よりもスレッド収納数の方が多いことになります。

そうすると、この規模の信号処理だと、1フレーム分以上データをメモリに溜めて(バッファリングして)から計算を開始しないとパイプラインが埋まらない などといった事が平気で起こり始めてしまいます。

ここで注意点はスループット(処理性能)とレイテンシ(遅延)は異なるという事です。GPUの全演算器がフル稼働して高スループットで大量のデータを処理していたからと言ってレイテンシが小さくなるかと言うとそんなことはありません。 並列処理を行う為に一度メモリへのバッファリングした分はそのまま信号遅延(レイテンシ)になります。60fps のカメラを使うと、露光に 16.6ms、読み込んでメモリに溜めるので 16.6ms かかるので、33.3ms 経ってからやっと計算を始める という事になります。

ここから計算と出力があるので、すぐに 50~100ミリ秒ぐらいの遅れが起こるのですが、こちらの動画 を見るまでもなく、用途によってはこれは致命的です(製造分野とかドローンみたいなものとかの画像処理だともっと早く計算したいケースがあります)。

しばし、遅延の解消は非常に大きなユーザー体験の向上をもたらすのですが、この事実はあまり一般に知られていないため、ユーザーは知らない間に遅延のある状態を当たり前として慣らされてしまっている面があったりもします。

FPGA との比較

大雑把に比較すると

  • 並列演算に必要なデータ数が揃うまで溜めて、一気に並列演算するのがGPU
  • データが届いた端から順にパイプライン並列で演算していくのがFPGA

と言うような言い方ができます。

当然一度、データをメモリに溜めている分、遅延とコストが増加するのが GPU です。

そして残念ながらレイテンシに関しては 今後並列度が向上すればするほど悪化する可能性がある というアーキテクチャ上の特性を持っていると言えると思います。

ただしデバッグも含めたプログラミングの難易度は圧倒的に GPU が楽ですし、遅延以外の項目でも長所/短所がお互いにあるのは過去にいろいろ書いてきた通りです。

おわりに

久しぶりに GPU のスペックをちゃんと見てみて、コアの増えっぷりに改めて驚きました。普段 16nm プロセスとかの FPGA でのほほんと遊んでる身からすると、最先端半導体プロセス恐るべし です。

GPUの発祥であるゲーム用途で、プログラミングシェーダーが出始めたころには、「ピクセルの数だけ並列化できるから、実質無限に並列化が捗る」ぐらいの勢いだったのですが、そろそろ「ピクセル数じゃ足りなくなる日が来るんじゃないか?」という予感さえしてしまいました。

いずれにせよ、GPUで性能を出そうとすれば、データを溜めれるだけ溜めて、なるべく大きなバッチで大量のスレッドを回す という方向に全力で振るべきなので、今後、コア数が増えて並列度が上がれば上がるほど、遅延(レイテンシ)と言う観点では不利になっていく可能性があるかと思います(特に産業用途とかのエッジ環境では)。ますます FPGA などとの住みわけも広がっていくのではないかと感じました。

もちろん、GPUでもデータを小分けにしてパイプライン化するなど、遅延を減らす工夫はいろいろできるのですが、それをやりだすとプログラミングの難易度が FPGA と同じになってしまいますし、本質的なところであくまで「並列処理で性能を上げる」事しかできないのが SIMT の宿命かと思います。

今後の進化の中で、GPUの特性が、ますますGPUらしく出てきたときに、他のアーキテクチャとの住みわけが再度議論されてきても面白いかなと思った次第です。

当サイトがFPGAを駆使して、ミリ秒遅延であれこれ画像処理しているのは、そういったお話に繋がってくるわけです。