1 ポイント 投稿者 GN⁺ 2025-02-10 | 1件のコメント | WhatsAppで共有

紹介

  • この記事では、GPUにおける分岐に関する誤った通念を正したい。
  • いくつかの教育系Webサイトが誤った情報を広めているため、それを修正したい。

問題

  • GPUコードで条件付き実行を実装する三項演算子を使うコード例を示す。
  • 一部の人はこれを算術演算に置き換える「最適化」を提案するが、これは誤解に基づいている。
  • 三項演算子は条件付き移動を行い、これは単純なビット演算で実装される。
  • 実際の分岐はGPUコードで発生するが、小さなレジスタ移動には使われない。

誤った最適化の問題点

  • 提案された最適化は、実際には元のコードより遅く実行される。
  • step() 関数は三項演算子で実装されており、不要な乗算と加算を追加で実行する。
  • 元のコードでは、値が条件に応じて直接移動される。

機械語コードの分析

  • AMDおよびMicrosoftコンパイラの機械語コードを通じて、GPUが分岐を行っていないことを確認できる。
  • 比較演算とビットマスクを使って条件付き移動を実行する。

結論

  • step() 関数を使った最適化の提案は誤情報であり、これを正す必要がある。

  • 誤情報は20年以上広まっており、修正する必要がある。

  • Inigo Quilez - 1994年からコンピュータグラフィックスを学習中。

1件のコメント

 
GN⁺ 2025-02-10
Hacker Newsの意見
  • TFAの結論が正しいことは確信しているが、より良い版だけでなく両方の版のコード生成が示されれば、主張はさらに強まるはず

    • 「最適化された」版が実際には元の版よりはるかに遅く実行されることを示すために生成された機械コードは見せているが、悪い版のほうがより悪いことまでは証明していない
  • どのような場合に if が本当に分岐を強制するのかを知る良い方法があればいいのにと思う

    • 人々がより高コストな mix / lerp を使う理由は、わずかなオーバーヘッドがあるかもしれなくても、分岐を作ることを恐れているからだ
    • v = x > y ? a : b; が実際にうまく機能するのはよいが、if が時には分岐で時にはそうでない構文であることが気がかりだ
  • この記事も関連している: GPUでの分岐の書き方に関する誤った助言を正す

    • 以前は分岐を避ける最適化が有効だったが、今ではそうすべきではない
    • プロセッサとコンパイラは変化するので、複数の変種を用意し、実行時に最も速いものを選ぶのがよい
  • コンパイラが「最適化された」版が同一であることをなぜ認識できないのか不思議だ

    • step() を理解し、step() = 0.0step() == 1.0 の場合を別々に最適化できるはずだ
  • この問題には引っかかったことがある。Claude / ChatGPT もこれを最適化として提案するが、性能低下を招く

    • Inigo に感謝
  • OpenGL 関数が GPU の基本機能を呼び出すのではなく、エミュレーションされているかどうかをどうやって知ればよいのか気になる

  • コードを書く際、条件分岐が発生しないという確信を持つには経験が必要だ

    • 条件の後にどれだけの演算があると分岐を引き起こすのか、またコンパイラがどの演算を省略できるのかを知るのは難しい
    • 性能テストスイートを使って偶発的な性能低下を確認すべきか悩む
  • mix 関数のバリアントがベクトルに対してどのように動作するかを説明している