OpenCL などの新しいシステムが作成され、グラフィックスプロセッサでより多くのコードを実行できるようになりました。これは、システムで可能な限り多くの電力を利用できるため、理にかなっています。
ただし、これらすべての新しいシステムでは、GPUはあらゆる点でCPUよりも優れているようです。 GPUは並列計算を実行できるため、マルチコアGPUは実際にはマルチコアCPUよりもはるかに優れているように見えます。一度に多くの計算を行うことができ、速度が本当に向上します。シリアル処理が並列処理よりも優れていて、高速で、効率的である特定のケースはまだありますか?
ただし、これらすべての新しいシステムでは、あらゆる点でGPUがCPUよりも優れているように見えます。
これは根本的な誤解です。現在のGPUコアは、現在のトップラインCPUと比較してまだ制限されています。 NVIDIAのFermiアーキテクチャは、現在利用可能な最も強力なGPUだと思います。整数演算用の32ビットレジスタのみがあり、分岐予測と投機的実行の機能は現在の一般的なIntelプロセッサよりも少ないです。 Intel i7チップは3つのレベルのキャッシュを提供します。Fermiコアには2つしかありません。Fermiの各キャッシュは、i7の対応するキャッシュよりも小さくなっています。 GPUコア間のプロセス間通信はかなり制限されており、その制限に対応するために計算を構造化する必要があります(コアはブロックにまとめられ、ブロック内のコア間の通信は比較的高速ですが、ブロック間の通信は低速です)。
現在のGPUの大きな制限は、すべてのコアで同じコードを実行する必要があることです。 CPUのコアとは異なり、1つのGPUコアにメールクライアントを実行するように指示し、別のコアにWebサーバーを実行するように指示することはできません。 GPUに行列を反転する関数を与えると、すべてのコアがさまざまなデータビットでその関数を実行します。
GPUのプロセッサは、孤立した世界に住んでいます。ディスプレイを制御できますが、ディスク、ネットワーク、キーボードにはアクセスできません。
GPUシステムへのアクセスには、かなりのオーバーヘッドコストがあります。 GPUには独自のメモリがあるため、計算はGPUカードのメモリ量に制限されます。 GPUメモリとメインメモリの間でデータを転送するには、比較的コストがかかります。実用的には、これは、セットアップとティアダウンのコストが計算に必要な時間を圧迫するため、CPUからGPUに少数の短い計算を渡すことに利点がないことを意味します。
結論として、GPUは、並列で計算できる長い計算のコピーが(数百または数千など)多数ある場合に役立ちます。これが一般的な一般的なタスクは、科学計算、ビデオエンコーディング、およびイメージレンダリングです。テキストエディターのようなアプリケーションの場合、GPUが役立つ唯一の機能は、画面上にタイプをレンダリングすることです。
GPUは、CPUのようにジェネラリストプロセッサではありません。彼らは、1つの非常に具体的なこと(同じコードを大量のデータに適用すること)に特化しており、CPUよりもはるかに優れています。しかし、ほとんどのアプリケーションの大部分は、同じコードを大量のデータに適用することではありません。これは、イベントループに関するものです。入力を待機し、入力を読み取り、それに作用し、さらに入力を待機します。これはかなりシリアルなプロセスであり、GPUは「シリアル」に夢中です。
処理する必要がある大量のデータがあり、各アイテムを他のアイテムとは無関係に並行して処理できる場合は、先に進んでGPUに送信します。しかし、これをすべてを圧迫しなければならない「新しいパラダイム」とは考えないでください。
この質問には「最適化」というタグが付いているので、1つとして扱うようにしてください。テストとプロファイリングにより最適化が必要であり、タスクの性質上GPU最適化を適用できることが判明した場合は、GPU最適化を適用します。それ以外の場合は、時期尚早または不適切な最適化となり、修正よりも多くの問題が発生するため、気にしないでください。
単純な答えは、GPUは、非常に多数のアイテムのそれぞれに対してかなり小さくて単純な計算を実行する必要がある場合に最適に機能するということです。この方法で多くのことを達成するには、各アイテムの計算が他のアイテムの計算から独立している必要があります。あるアイテムと別のアイテムの間に(通常は)依存関係がある場合、GPUでそのコードを実行することから多くを得る前に、通常、何らかの方法でそれを壊す必要があります。依存関係をまったく壊すことができない場合、または壊すのに多くの作業が必要な場合、コードはCPUでより高速に実行される可能性があります。
ほとんどの現在のCPUは、現在のGPUがまったくサポートしようとしないかなりの種類の操作もサポートしています(たとえば、マルチタスクのメモリ保護)。
少し異なる方向から見ると、CPUは(主に)プログラマーにとって合理的に便利であるように設計されており、ハードウェアの人々はその便利なモデルを維持するハードウェアを作成するために最善を尽くしましたプログラマーですが、それでも可能な限り迅速に実行されます。
GPUは逆の方向から物事を生み出します。GPUは主にハードウェア設計者にとって便利になるように設計されており、OpenCLなどはハードウェアの制約を考慮して、可能な限り合理的なプログラミングモデルを提供しようとしています。
GPUで実行するコードを作成すると、通常、CPUで同じことを行うよりも多くの時間と労力(コストがかかる)がかかります。そのため、次のいずれかの場合に、そうすることが主に理にかなっています。
それぞれに明らかな可能性があります-hugeアプリケーションの数が明らかにどちらにも近いわけではありません。 (たとえば)CRUDアプリケーションがGPUですぐに実行されるのを見ると、かなり驚かれます(もしそうなら、誰かがその正確な目標を念頭に置いて、必ずしも最適なものに近づいているわけではないので、おそらくそれは起こります。費用便益比)。
多くの(私が「ほとんど」と言いたくなります)アプリケーションの場合、一般的なCPUは十分に高速であり、プログラミングの利便性(新機能の開発が容易になるなど)は現実ですmuch実行速度よりも重要です。
一度に多くの計算を行うことができ、速度が本当に向上します。
速度を向上させますか?だから何?昨年までは、必要なときに1回または2回しか思い出せませんでした。ほとんどの場合、ロジックの変更または修正、別のデータソースの調整、ユーザーインタラクションの改善などを求められました。これらのケースに興味を持った唯一のspeed顧客は、作成の速度でしたおつり。 「新機能は1か月以内にリリースしてください。2週間以内にリリースしてください。」.
私を誤解しないでください-コーダーとして、私はCPUティックを徹底的に絞ることを楽しんでいます。それは、この芸術が一般に需要が高いわけではないということだけです。
シリアル処理が並列処理よりも優れていて、より高速で、効率的である特定のケースはまだありますか?
たくさんのケースがあると思います。シリアル処理はパラレル処理よりも単純であるため、速度が重要な要件ではないすべてのケースで効率的です。シリアル処理により、複雑なロジックとユーザーインターフェイスの実装が容易になり、指定とテスト、保守と変更が容易になります。
原則として、シリアル処理により、プログラマーの意図をより明確に表現し、コードを簡単に読み取ることができます。私はそれが最も貴重で希少なリソース、つまりプログラマーの頭脳を節約すると言えるでしょう。
CPUはさらに多用途です。たとえば、GPUは単精度ではCPUより効率的ですが、倍精度では効率的ではありません。 CPUにはGPUよりもはるかに多くのライブラリがあります。
単純なルールは、あなたがしていることを線形代数からの構成に関して表現でき、時間が重要である場合は、GPUでそれを行い、そうでない場合はCPUを使用します。
GPUは多数のCPUとは異なり、パフォーマンス特性が大きく異なります。
生の数値処理が必要な場合は、GPUが適しています。ただし、これらのALUはすべて、フロー(分岐)回路の制御専用のトランジスタが少ないことを意味します。したがって、多くの複雑な制御フロー、多くの条件などを必要とするものを記述する必要がある場合、CPUはより高速になります。