web-dev-qa-db-ja.com

「マルチコア」フレンドリーではないと主張するプログラム

このフレーズまたは類似のフレーズがときどきキックされ、一般的にはマルチコアプロセッサを最大限に活用するように設計されていないと主張するプログラムを指します。これは、特にビデオゲームプログラミングで一般的です。 (もちろん、多くのプログラムには並行性がなく、基本的なスクリプトなど、それを必要としません)。

どうすればいいの?多くのプログラム(特にゲーム)は本質的に並行性を使用しており、OSはCPUでのタスクスケジューリングを担当しているため、これらのプログラムは利用可能な複数のコアを本来利用していませんか?このコンテキストで「複数のコアを利用する」とはどういう意味ですか?これらの開発者は実際にOSタスクスケジューリングを禁止し、アフィニティまたは独自のスケジューリングを強制していますか? (主要な安定性の問題のように聞こえます)。

私はJava=プログラマーなので、抽象化やその他の理由でこれに対処する必要がなかったかもしれません。

17
SnakeDoc

優れた同時実行性を実現するには、アプリケーションにいくつかのスレッドを投げて最高のものを期待する以上のことが必要です。プログラムが 恥ずかしいほど並列 から純粋な順次に並行する方法には、さまざまな範囲があります。どのプログラムでも、 アムダールの法則 を使用して、問題またはアルゴリズムのスケーラビリティを表現できます。恥ずかしいほど並列アプリケーションのいくつかの資格は次のとおりです。

  • 共有状態なし、すべての関数は渡されたパラメーターにのみ依存します
  • 物理デバイス(グラフィックカード、ハードドライブなど)にアクセスできない

他の資格もありますが、これら2つだけで、特にゲームが複数のコアを利用することを考えるほど簡単ではない理由を理解できます。まず、レンダリングされる世界のモデルは、物理演算、動きの計算、人工知能の適用など、さまざまな関数として共有する必要があります。次に、このゲームモデルの各フレームをグラフィックカードで画面にレンダリングする必要があります。

公平を期すために、多くのゲームメーカーは、サードパーティが作成したゲームエンジンを使用しています。しばらく時間がかかりましたが、これらのサードパーティのゲームエンジンは以前よりもはるかに並列化されています。

効果的な並行処理に対処する上で、より大きなアーキテクチャ上の課題があります

並行性は、バックグラウンドでのタスクの実行から、並行性の完全なアーキテクチャサポートまで、さまざまな形式をとることができます。一部の言語では、 [〜#〜] erlang [〜#〜] などの非常に強力な同時実行機能が提供されますが、アプリケーションの構築方法について非常に異なる考え方をする必要があります。

すべてのプログラムが実際に完全なマルチコアサポートの複雑さを必要とするわけではありません。そのような例の1つは、税務ソフトウェア、またはフォーム主導のアプリケーションです。ほとんどの時間がユーザーが何かをするのを待つのに費やされている場合、マルチスレッドアプリケーションの複雑さはそれほど役に立ちません。

一部のアプリケーションは、Webアプリケーションなど、より厄介な並列ソリューションに適しています。この場合、プラットフォームは恥ずかしいほど並行して開始され、スレッドの競合を強制する必要はありません。

一番下の行:

複数のスレッド(つまり、コア)を利用しないことで、すべてのアプリケーションが実際に害を受けるわけではありません。それによって傷ついたものについては、計算は並列処理に適さない場合があり、それを調整するためのオーバーヘッドはアプリケーションをより脆弱にするでしょう。残念ながら、並列処理はまだうまくいくほど簡単ではありません。

28
Berin Loritsch

多くのプログラム(特にゲーム)は本質的に並行性を使用しますが、

いいえ、実際にはその逆です。ほとんどのアプリはシングルスレッドの考え方で記述されており、開発者は並行性をサポートするために必要な変更を行っていません。

C、C++、およびC#では、新しいスレッドやプロセスを開始するようにアプリケーションに明示的に指示する必要があります。

スレッドのスケジューリングに集中しすぎて、潜在的なスレッド内のデータ処理に十分ではないと思います。スレッドやプロセス間でデータを共有するには、何らかの同期が必要です。複数のスレッドを使用するようにアプリケーションを変更したが、同期を適切に行えなかった場合、コード内のバグを追跡するのが非常に困難になる可能性があります。

私が取り組んだマルチスレッドアプリケーションの場合、ディスパッチについて心配することはなく、データの同期についてのみ心配しました。ディスパッチについて心配する必要があったのは、誤ったデータ同期のために競合状態を追跡していたときだけでした。

一般に、アプリケーションが複数のコアを使用できないと言っている場合、データ操作を保護するための同期が整っていないことを意味します。

35
user53019

これは、複数のコアに関するものではなく、複数のスレッドに関するものです。 OSはスレッドを好きなコアで実行するようにスケジュールすることができ、このスケジュールはスケジュールされているプログラムに対して透過的です。ただし、多くのプログラムは複数のスレッドを使用して書かれていないため、一度に1つのコアでのみ実行できます。

なぜシングルスレッドのプログラムを書くのですか?それらは書きやすく、デバッグが容易です。あることが次々に起こります(複数のことが一度に起こり、互いに干渉し合う可能性があるのではなく)。または、プログラムがマルチコアマシンをターゲットにしていない可能性があります(古いゲームの場合のように)。場合によっては、コンテキスト切り替えとスレッド間の通信によるオーバーヘッドが並列実行によって得られる速度を上回ると、マルチスレッドプログラムの実行速度がシングルスレッドバージョンよりも遅くなる場合があります(プログラムの一部が並列化できない場合があります)。

13
amon

これは完全な答えではありません。それは注意書きです。

ある日、並行プログラミングコースの学生に並列クイックソートを見せようと思いました。クイックソートはうまく並列化すべきだと私は思った。 2つのスレッドを使用しました。シングルコアコンピューターで実行しました。結果は次のとおりです。

  • シングルスレッドバージョンの場合は14秒。
  • 2スレッドバージョンの場合は15秒。

これは私が期待していたことです。

次に、新しいデュアルコアマシンで試してみました。

  • シングルスレッドバージョンの場合は11秒。
  • 2スレッドバージョンの場合は20秒。

2つのスレッドが残りのタスクのキューを共有しました。キューオブジェクトのフィールドが、1つのコアのキャッシュと他のコアのキャッシュの間を行き来していたようです。

7