ソフトウェアプログラミングでは、CPUとGPUの両方の負荷を100%にすることは可能ですか?


43

これは、私がゲーマーとして面白いと思った主題に関する一般的な質問です:CPU / GPUのボトルネックとプログラミング。間違っていなければ、CPUとGPUの両方が計算を行うことを理解するようになりましたが、アーキテクチャの違いにより、ある計算では他の計算よりも優れていることがわかりました。たとえば、クラッキングハッシュまたは暗号通貨マイニングは、CPUよりもGPUの方が効率的であると思われます。

だから私は疑問に思った:CPUが50%(例えば)である間、100%の負荷でGPUを持っていることは避けられない?

または、より正確に:最初に1つが100%の負荷である場合、GPUによって通常行われるいくつかの計算はCPUによって行われ、両方とも100%の負荷に達することができますか?

私はこの主題について少し検索しましたが、かなり手ぶらで戻ってきました。これがこのサブセクションに位置し、あなたが私に与えるかもしれないどんな文書や講義にも開かれていると思います!


53
CPUとGPUの両方でNO-OPsの無限ループを同時に実行することは簡単にできます。これにより、両方の負荷が100%になります。
ヨルグW

17
@Jörgのポイントに続いて、CPU%で測定される唯一のことは、他のプロセッサーの待機に費やされない時間の割合です。100%は、プログラムが効率的な場合は良いことであり、プログラムが非効率的な場合は悪いことです。多くの場合、CPU%がパフォーマンスの指標であるかのように人々が注目します-そうではありません。
マイクダンラベイ

22
元のCrysisはこれをうまく行いました。
CubicleSoft

5
@MikeDunlavey良い点を挙げてください。車の場合、RPMでパフォーマンスを測定するのではなく、速度を測定します。
キャプテンマン

1
@JörgWMittag:CPUかもしれません。しかし、OSとGPUには、無限ループに対処するための問題解決機能が停止しています。つまり、シェーダーが妥当な時間内に完了しない場合、シェーダーは終了し、GPUがリセットされます。
ニコルボーラス

回答:


62

理論的にはそうですが、実際にはそれだけの価値はほとんどありません。

CPUとGPUはどちらもチューリング完全であるため、一方で計算できるアルゴリズムはもう一方でも計算できます。問題は、どれだけ速くてどれだけ便利かということです。

GPUは、大規模なデータセットの多くのデータポイントで同じ単純な計算を行うのに優れていますが、CPUは、分岐が多いより複雑なアルゴリズムの方が優れています。ほとんどの問題で、CPU実装とGPU実装のパフォーマンスの差は非常に大きくなります。つまり、停止しているときに一方を使用して他方から作業を行うことは、パフォーマンスの顕著な向上に実際にはつながりません。

ただし、このために支払わなければならない代償は、すべてを2回プログラムする必要があるということです。1回はCPU用、もう1回はGPU用です。切り替えと同期のロジックも実装する必要があるため、これは2倍以上の作業です。そのロジックは、その動作が現在の負荷に依存するため、テストが非常に困難です。このスタントからバグを再現することは非常に不明瞭で不可能であることを期待してください。


1
あなたが言及したCPUとGPU実装間の性能差は巨大で、ほとんどの問題で、私は実際には非常にパフォーマンスのギャップが行くどの程度に興味があります。これに関する数字や記事はありますか(たとえば、テクスチャ3Dレンダリングの例について)。あなたの答えと時間をありがとう!
MadWard

2
CPUとGPU間の同期にはパフォーマンスコストがあることを追加することができます。そのため、通常は2つの間の転送数を最小限に抑える必要があります。また、GPUスレッドはロックステップで動作するため、「CPUが既に動作していた要素で実行しない」ためのブランチを単純に追加しても何も買えません。
イーサン

3
@gardenheadユニバースはサイズが有限で、情報密度が有限であるため、無制限の再帰をサポートするものはありません。システムの「チューリング完全性」とは、一般に、このような制約を取り除いた場合に可能なことの議論です。
Random832

3
現代のGPUが技術的には少なくとも80年代のPCとチューリングの完全性に近いことは疑いの余地がありません...しかし、GPUで一般的なアルゴリズムを実行しようとすると、通常はシーケンシャルプロセッサに縮退します。 80年代のPCよりも高速であるため、GPUのチューリング完全性は、実際にはBrainfuckのチューリング完全性ほど有用ではありません。
16年

7
@leftaroundabout現代のGPUは、CPUとして完全にチューリング完全です。チューリングの完全性は、1)パフォーマンス2)ソースの可読性とは関係ありません。80年代のCPUはTCに近いものでしたが、TCであったかそうでなかったかのどちらかです(後者のオプションはナンセンスです)。
マーガレットブルーム

36

ゲームプログラミングとは関係ありません。科学コードの中には、GPUとCPUの両方を使用できるものもあります。

たとえばOpenCLまたはCUDAを使用するなど、注意深い-苦痛なプログラミングを使用すると、GPUとCPUの両方を100%近くにロードできます。GPU(いわゆる「カーネル」コード)とCPU、およびいくつかの退屈なグルーコード(特にコンパイルされたカーネルコードをGPUに送信するため)に異なるコードを記述する必要があるでしょう。

ただし、コードは複雑になります。特にGPUとCPU間のデータ転送にはコストがかかるため、実行している特定のハードウェアに合わせて調整する必要があります。

異種コンピューティングの詳細をご覧ください。

GCCの最新バージョンでサポートされているOpenACCも参照してください(例:2016年6月のGCC 6


1
そうです、私のタグとタイトルは誤解を招きやすく、ゲームを削除し、パフォーマンス/最適化を追加しました。ゲーム専用というわけではありませんでしたが、そこに気がつきました。ハードウェア固有のものも必要だと思いました。回答とリンクをありがとう!
MadWard

3
これは、ほとんど2つのアルゴリズムになります。私は一度試してみました:GPUの場合は一度に全体のイメージを、CPUの場合は一度に複数のイメージ(大きなキャッシュを乱用するため)。特に維持することは確かに苦痛です。
PTwr

11

スーパーコンピューティングの観点からは、CPU / GPUの負荷をパーセンテージで考えるのではなく、手元の問題で必要な操作の数を決定し、それをシステムのピークパフォーマンスと比較することをお勧めします。

CPU使用率が100%になっても、必ずしもシステムのすべてのパフォーマンスが得られるわけではありません。CPUは、多くの場合、同時に複数の異なること、たとえば分割と追加を実行できます。除算を早期に開始できる場合、追加と重複する可能性があります。ほとんどの場合、デスクトップCPUには、このような重複の恩恵を受けるためにステートメントを並べ替える順不同ユニットがあります。または、次のプログラムがある場合:

if (expr1)
    expr2;
else
    expr3;

再配列CPUは、3つの式を同時に計算し、そのうちの1つの結果を破棄しようとします。これにより、全体的に高速になります。プログラムに何らかのブロッカーがあり、並べ替えができない場合、CPUで使用するレーンは少なくなりますが、おそらく100%を示します。

次に、ベクトル演算であるCPUにSIMD機能があります。通常は同時に4つまたは8つの操作しか実行できないという意味で、GPGPU-lightに似ていますが、GPUは32または64のように動作します。

偽共有のようなものは、通常、Linuxのカーネル負荷として現れる同期コストが高くなる可能性があります。CPUは完全に使用されていますが、有効なスループットはあまりありません。

IBM Blue Gene / Qマシンでプログラミングを行いました。多くの階層レベル(旧式のBlue Gene / Lの概略図)があるため、効率的にプログラミングするのは困難です。パフォーマンスを引き出すには、SIMDおよびSMT(Intelはこのハイパースレッディングと呼んでいます)までの完全な階層を使用する必要があります。

そして、ネットワークはしばしばあなたを制限します。したがって、ネットワークを介して通信するのではなく、複数のCPUで同時に物事を計算する方が(ウォールクロック)時間で高速であることがわかります。これにより、CPUの負荷が増加し、プログラムの実行が高速になります。しかし、実際のプログラムのスループットは、生の数値から思われるほど良くありません。

GPUをミックスに追加すると、パフォーマンス全体を得るためにこのすべてを調整することがさらに難しくなります。これは、数か月以内にラティスQCD修士論文で始めることの1つになります。


1

Mozilla Researchで開発されているServoブラウザーエンジン、特にWebレンダー(ビデオ)をチェックすることに興味があるかもしれません。

タスクをCPUからGPUに動的にシフトすることは非実用的かもしれませんが、他の回答(特に@ Philip's)で述べられているように、典型的なワークロードでのCPU / GPUの負荷を事前に調査し、いくつかのタスクを一般的に負荷の少ないものに切り替えることが実用的です1。

Webレンダーの場合、斬新な点は、ブラウザがレンダリング作業のほとんどをCPUで実行することです(つまり、CPUは、表示するオブジェクト、カットする場所などを計算するために使用されます)。GPUは通常、優れています。ただし、すべてのユースケースを実装するのが簡単なわけではありません(部分カリング、シャドウ、...、テキスト)。

Web Renderの初期バージョンは、パフォーマンスの向上に非常に成功しましたが、テキストレンダリングの問題に対処しようとしませんでした(他にもいくつかの制限がありました)。Mozilla Researchは現在、制限を少なくし、特にテキストレンダリングをサポートすることを目的とした2番目のバージョンに取り組んでいます。

もちろん、目標はレンダリングプロセスを可能な限りGPUにオフロードし、CPUがJavascriptを実行し、DOMを更新し、他のすべてのタスクを自由に行えるようにすることです。

したがって、あなたの提案ほど極端ではありませんが、CPUとGPUの両方を念頭に置いて計算戦略を設計する方向に進みます。


0

ゲームに重点を置いて(投稿で具体的に言及しているため)、負荷を分散する方法がいくつかあります。1つの例は「スキニング」、つまりモデルのアニメーションです。レンダリングするフレームごとに、アニメーションの各フレームの変換行列を生成し、モデルの頂点に適用して、必要なポーズに変換する必要があります。また、スムーズな動きを得るにはフレームを補間する必要があります、アニメーションを元のQuake(ジャーキー)のように見せたい場合を除きます。

この状況では、CPUで実行して結果をGPUにアップロードしてレンダリングするか、GPUで計算とレンダリングを実行できます。最近はGPU(「ハードウェアスキニング」として知られています)で行われていると思います:何千回も実行する必要がある比較的単純な計算があり、結果から各頂点を同時に計算できるので、そうするのは理にかなっています頂点Aの頂点Bの結果には影響しません。

ただし、理論的には、GPUとCPUの過負荷状態に応じて、CPUまたはGPUで動的に切り替えることができます。

ただし、すべての計算でこれを行う主な障害は、CPUとGPUの長所と短所が異なることです。超並列ジョブはGPUで実行する方が適切ですが、分岐を伴う集中的な線形タスクはCPUで実行する方が適切です。深刻なパフォーマンスの低下なしに、両方で実際に実行できるジョブはわずかでした。

全体的に、GPUプログラミング(少なくともOpenGLおよびDirectX 11以前)の主な問題は、GPUがシェーダーコードを解釈する方法をほとんど制御できないことです。シェーダー内での分岐は、計算間の依存関係を誤って作成した場合、GPUがピクセルを1つずつレンダリングし始め、実際のレンダリングされるデータが同一で​​あっても瞬時に60fpsから10fpsに変わる可能性があるため、危険です。


0

実際の例の1つは、CPUとGPUを同時に完全にロードできるオープンソースのLuxRenderレンダリングエンジンです。さらに、複数のGPUを同時に読み込むことができ、複数のコンピューターに分散することもできます。

LuxRenderはOpenCLを使用してこれを容易にしますが、OpenCLを使用しないビルドも存在します。

LuxRenderが使用するアルゴリズムは高度に並列化できるため、これは実用的です。LuxRenderが使用する最も一般的なアルゴリズムは、多くの個々のライトパスを互いに独立して計算できるパストレースです。GPUコンピューティングの理想的な状況であり、コンピューティングノード間の複雑な同期を必要としません。ただし、GPUの制限(メモリの量が少なく、一部の複雑なレンダリング機能がサポートされていないこと、および一部のアーティストが一般的に利用できないこと)により、CPUサポートが依然として不可欠です。


この画像を表示するポイントは何ですか、質問にどのように関連していますか?
-gnat

1
ええ、結構です。削除します。私はそれがどんな種類のソフトウェアであるかを簡単に実証すると思っていました。しかし、おそらくそれは本当に気を散らすだけです。(さまざまな種類のレンダリングエンジンがあります。これは、フォトリアリスティックな静止画を対象としています。)
PythonNut

0

はい、それは確かに可能です。

CPUが実行できる計算、GPUも実行できる計算、およびその逆。

しかし、それは珍しいです:

  • エンジニアリングの複雑さ CPUとGPU(CUDAなど)で同じコードを実行することは可能ですが、プロセッサーの能力とパフォーマンス特性は異なります。1つはMIMDです。もう1つはSIMDです。一方で速いのは、他方では遅い(分岐など)ので、パフォーマンスを最大化するために別のコードを書く必要があります。

  • コスト効率の高い GPUは、CPUよりもはるかに強力です。GPUの全体的な考え方は、CPUが同じコストで実行できるよりもはるかに高速に、安価で低速であるがより多くのプロセッサを使用して計算を実行することです。GPUは、コスト面で1〜2桁効率的です。

アルゴリズムをGPUで実行できるようにした場合、それらを最適化し、必要な数だけ追加する方が合理的です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.