私の知る限り、プロセッサのマルチコア アーキテクチャはプログラムに影響を与えません。実際の命令の実行は、下位層で処理されます。
私の質問は、
マルチコア環境を使用している場合、使用可能なリソースをより効果的に利用するためにプログラミング手法を使用できますか? マルチコア環境でパフォーマンスを向上させるには、コードをどのように変更すればよいですか?
私の知る限り、プロセッサのマルチコア アーキテクチャはプログラムに影響を与えません。実際の命令の実行は、下位層で処理されます。
私の質問は、
マルチコア環境を使用している場合、使用可能なリソースをより効果的に利用するためにプログラミング手法を使用できますか? マルチコア環境でパフォーマンスを向上させるには、コードをどのように変更すればよいですか?
それは正しいです。並行性を採用しない限り、プログラムの実行速度は速くなりません (一部のプロセスが他のコアで実行されているため、コアが処理する他のプロセスが少なくなるという事実を除いて)。ただし、同時実行を使用する場合は、コアが多いほど実際の並列処理が向上します (コアが少ないと同時処理がインターリーブされますが、コアが多いとスレッド間で真の並列処理が得られます)。
プログラムを効率的に並列化することは、簡単な作業ではありません。プログラムを並行処理すると、実際には処理が遅くなる可能性があります。たとえば、スレッドの生成に多くの時間を費やし (スレッドの構築が非常に遅い)、非常に小さなチャンク サイズで作業を行う場合 (スレッド構築のオーバーヘッドが実際の作業を支配する)、または頻繁にデータを同期する場合 (これは、操作を連続して実行することを強制するだけでなく、その上に非常に高いオーバーヘッドも伴います)、または複数のスレッド間で同じキャッシュ ライン内のデータに頻繁に書き込む場合 (キャッシュ ライン全体が 1 つのスレッドで無効化される可能性があります)コアの)、並行プログラミングでパフォーマンスに深刻な悪影響を与える可能性があります。
また、N 個のコアを使用している場合でも、N 個のスピードアップが得られるわけではないことに注意することも重要です。これは、スピードアップの理論上の限界です。実際、2 コアでは 2 倍、4 コアでは約 3 倍、8 コアでは約 3.5 倍の速さなどです。これらのコアを活用できることは、並列スケーラビリティと呼ばれます。多くの場合、通信と同期のオーバーヘッドによって線形の高速化が妨げられますが、理想的には、通信と同期をできるだけ回避できれば、線形に近づくことができます。
StackOverflow で効率的な並列プログラムを作成する方法について、完全な答えを出すことはできません。これは実際、少なくとも 1 つ (おそらく複数) のコンピューター サイエンス コースの主題です。そのようなコースにサインアップするか、本を購入することをお勧めします。良い本を知っていればお勧めしたいのですが、私が取った並列アルゴリズムのコースにはそのコースの教科書がありませんでした。シリアル実装、マルチスレッド (通常のスレッド、スレッド プールなど) を使用した並列実装、およびメッセージ パッシング (Hadoop、Apache Spark、Cloud Dataflows など) を使用した並列実装を使用して、いくつかのプログラムを作成することにも興味があるかもしれません。 、非同期 RPC など) を実行し、並列実装の場合はコア数を変えてパフォーマンスを測定します。これは、私の並列アルゴリズム コースのコース作業の大部分であり、非常に洞察力に富んでいます。並列化を試みる可能性のある計算には、モンテカルロ法を使用した Pi の計算 (異なるスレッドで生成された乱数が独立している乱数ジェネレーターを作成できると仮定すると、自明に並列化可能です)、行列乗算の実行、行階層形式の計算が含まれます。非常に大きな数の N について、数値 1...N の 2 乗を合計する行列です。他のことも考えられると思います。
ここから始めるのが最適かどうかはわかりませんが、Intel Software Networkの記事フィードを購読していたところ、非常にシンプルな方法で提示された多くの興味深いものを見つけました。こののように、並列コンピューティングの基本的な概念に関するいくつかの非常に基本的な記事を見つけることができます。ここでは、残りの部分を変更せずに、アプリケーションの最も遅い部分の並列化を開始するための 1 つの可能なアプローチである openMP について簡単に説明します。(もちろん、それらの部分が並列処理を示している場合。) Intel Guide for Developing Multithreaded Applicationsも確認してください。または、記事セクションを参照してください。記事はそれほど多くありません。たくさんあるので、自分に合ったものをすぐに見つけることができます。また、Parallel Programming Talk と呼ばれるフォーラムと毎週のWeb キャストもあります。
はい、ソフトウェアを変更せずにシステムにコアを追加するだけでは、結果は得られません (ただし、オペレーティング システムは別々のコアで複数の同時プロセスをスケジュールできます)。
オペレーティング システムで複数のコアを利用するには、プロセスあたりのスレッド数を増やすか、同時に実行するプロセスの数を増やすか (または両方!) のいずれかを行う必要があります。
ただし、コアを有効に活用することは、別の色の獣です。スレッド/プロセス間の共有データ アクセスの同期に多くの時間を費やすと、スレッドが相互に待機するため、同時実行レベルが低下します。これはまた、アルゴリズムの並列バージョンはその逐次バージョンよりもはるかに複雑であるため、比較的簡単に並列化できる問題/計算があることも前提としています。
とはいえ、特に互いに独立した作業単位を持つ CPU バウンドの計算の場合、問題により多くのスレッドを投入するにつれて、直線的なスピードアップが見られる可能性が高くなります。シリアル セグメントと同期ブロックを追加すると、このスピードアップは減少する傾向があります。
物理ストレージへのアクセス (特に同じコントローラーまたは同じメディア上にある場合) もシリアルであるため、I/O 負荷の高い計算は通常、マルチスレッド環境で最悪の結果をもたらします。他のスレッドが解放され、ユーザーの操作や CPU ベースの操作を続行できるようになります。
並行プログラミング用に設計されたプログラミング言語の使用を検討することもできます。Erlang と Go が思い浮かびます。