複数のコアのプログラミングにどれだけの労力を費やすべきですか?


12

プロセッサは最近、ますます多くのコアを取得しています。

プログラマーは、この動作に適応し、複数のコアのプログラミングにより多くの労力を費やす必要がありますか?

これをどの程度まで最適化しますか?糸?親和性?ハードウェアの最適化?他に何か?

回答:


15

あなたがどんなに優れていても、コードを書いている言語やコンパイラを開発しているチームよりも、スレッドなどを管理するより良いスキームを思い付く可能性は低いでしょう。

アプリケーションをマルチスレッド化する必要がある場合は、必要なスレッドを作成し、コンパイラーとOSがジョブを処理できるようにします。

リソースを最大限に活用するには、これらのスレッドがどのように管理されているかを認識する必要があります。あまり多くのスレッドを作成しないことは、一例として思い浮かぶことの1つです。

また、スレッド管理にヒントを提供する(または特別な場合にそれをオーバーライドする)ことができるように、何が起こっているのかを知る必要があります(Lorenzoのコメントを参照)が、私はこれらがほとんどないだろうと思っていたでしょう。


3
ただし、コアから別のコアに継続的にジャンプするスレッドは、特に2つの異なる物理ダイが使用されているアーキテクチャでは、パフォーマンスのペナルティがあります(第1レベルおよび第2レベルのCPUキャッシュが失われるため)。マルチスレッドの集中コードでは、親和性は良いことです。
Wizard79

@Lorenzo-その場合、スレッドを単一のコアに結び付けることができるかどうかを確認する必要があります-これはおそらく特別なケースですが、興味深いものです。
ChrisF

1
OSがアクティブなスレッドをあるコアから別のコアにコンテキスト切り替えするのは、かなり奇妙な動きではないでしょうか?
JBRウィルキンソン

@JBRWilkinsonに同意します。スレッドアフィニティは私にとってOSの仕事のようです。
コリン

1
@JBRWilkinson Linux(およびほとんどのOS)では、スレッドは常にコア間をジャンプします。1つ目の理由は、コアよりも全体的に多くのスレッドがあるためです。そして、いくつかのスレッドが死んだ場合、バランスを取る必要があります。2番目の理由は、多くのスレッドがスリープしていることです。カーネルが目を覚ますと、あるコアが他のコアよりも負荷が大きいと考え、スレッドを移動する場合があります。多くの場合、CPUを占有するコンピューティングスレッドです。次に、カーネルが1つ戻るまで、2つのCPUホギングスレッドが同じコアで実行されます。大きなジョブを正確にnum-coresの部分に分割する場合、スレッドアフィニティを設定する必要があります。
ゴスウィンフォンブレダロー

5

私は.NETプログラマーです。.NETには、タスクと呼ばれるマルチスレッド用の高レベルの抽象化があることがわかっています。これにより、金属に対して適切なマルチスレッドを実行する方法について多くを知る必要がなくなります。他の現在の開発プラットフォームにも同様の抽象化があると思います。したがって、マルチスレッドで何かをするつもりなら、可能な限りそのレベルで作業するようにします。

ここで、特定のアプリケーションでマルチスレッドを気にする必要がありますか?その質問への答えは、あなたが書いているアプリケーションに大きく依存しています。数千(またはそれ以上)の独立した処理を行うアプリケーションを作成していて、この処理を並行して実行できる場合、ほぼ確実にマルチスレッドの利点が得られます。ただし、単純なデータ入力画面を作成している場合、マルチスレッド化はあまり役に立ちません。

少なくとも、UIで作業しているときはマルチスレッドに注意する必要があります。実行時間の長い操作をUIから起動し、その操作を行うためにUIスレッドをハイジャックしたために応答しなくなることは望ましくありません。バックグラウンドスレッドを起動し、少なくともユーザーに[キャンセル]ボタンを与えると、ユーザーが間違えた場合にそれが完了するのを待つ必要がなくなります。


5

Objective-CとMac OS XとiOSの土地では、フレームワーク(他の多くと同様)は、プロセッサコアのこれらの増加を活用し、それらを利用するための素晴らしいインターフェイスを開発者に提供するために書かれています。

Mac OS XおよびiOSの例は、Grand Centralの発送です。libcキューベースのマルチスレッド化を容易にするための追加機能があると思います。次に、CocoaおよびFoundationフレームワーク(特に)がGCDの上に記述され、開発者はディスパッチキューに簡単にアクセスでき、ボイラープレートコードはほとんどありません。

多くの言語とフレームワークには同様の概念があります。


5

難しいのは、CPU集中型アルゴリズムをスレッド化可能な実行チャンクに分割することです。

その後、特に2つの異なる物理ダイが使用されているアーキテクチャでは、コアから別のコアに継続的にジャンプするスレッドのパフォーマンスが低下します(第1レベルおよび第2レベルのCPUキャッシュが失われるため)。この場合、スレッドとコアの親和性は良いことです。


3

私たちは現在(2010年10月)、大きな移行期にあります。

今日、12コアのデスクトップを購入できました。
今日、448コアの処理カードを購入できます(NVidia Teslaを検索)。

私たちのプログラムが近い将来に動作するであろう途方もない並列環境を無視して、開発者がどれだけ作業できるかには限界があります。

オペレーティングシステム、ランタイム環境、およびプログラミングライブラリは、そのようなことしかできません。

将来的には、新しい.NET "Task Framework"のような抽象化を使用して、独立した処理のために処理を個別のチャンクに分割する必要があります。

キャッシュ管理やアフィニティなどの詳細は引き続き存在しますが、それらは超高性能アプリケーションのみのプロバンスになります。同じ開発者は、これらの詳細を10kコアマシン全体で手動で管理することを望みません。


3

まあ、それは本当にあなたが開発しているものに依存しています。あなたが開発しているものに応じて、答えは「取るに足りない」から「絶対に重要であり、チームの全員が並列実装を十分に理解して使用することを期待します」。

ほとんどの場合、ロック、スレッド、タスク、タスクプールをしっかりと理解して使用することは、並列処理が必要な場合の良い出発点となります。(lang / libによって異なります)

それに加えて、設計の違いを作成する必要があります-自明でないマルチプロセッシングの場合、多くの場合、いくつかの新しいプログラミングモデルまたは並列化戦略を学習する必要があります。その場合、学習する時間、十分な時間をかけて十分に理解し、既存のプログラムを更新する時間は、チームに1年(またはそれ以上)かかります。その時点に到達すると、今日のように問題/実装を認識したり、アプローチしたりしないことを(できれば!)(まだ移行していない場合)。

別の障害は、特定の実行のためにプログラムを効果的に最適化することです。プログラムを最適化するための時間があまり与えられていない場合、あなたは本当にそれから利益を得ることはできません。高レベル(または明白な)並列化は、ごくわずかな労力でプログラムの認識速度を向上させることができます。これは、今日多くのチームが行う限りです。「アプリの本当に明白な部分を並列化しました」ぶら下がっている果物を取り、単純な視差を使用する利点は、コアの数に比例しますか?多くの場合、2〜4個の論理コアがありますが、それを超えることはあまりありません。多くの場合、時間の投資を考えると、これは許容できる利益です。この並列モデルは、並列処理の優れた使用法を実装するための多くの人々の入門書です。

この単純な並列モデルを使用して学習することは、すべての複雑な並列シナリオで理想的ではありません。複雑な並列設計を効果的に適用するには、まったく異なる理解とアプローチが必要です。これらの単純なモデルは、しばしば切り離されているか、システムの他のコンポーネントと簡単に相互作用します。同様に、これらの自明なモデルの多くの実装は、効果的に複雑な並列システムにうまく拡張できません。悪い複雑な並列設計は、単純なモデルと同じくらい実行に時間がかかります。病気:シングルスレッドモデルの2倍の速度で実行されますが、実行中に8つの論理コアを使用します。最も一般的な例は、あまりにも多くのスレッドと高レベルの同期干渉の使用/作成です。一般に、これは並列スローダウンと呼ばれます。すべての並列問題を単純な問題として扱う場合、遭遇するのは非常に簡単です。

したがって、プログラムで効率的なマルチスレッドを実際に使用する必要があるとしましょう(今日の気候では少数派です):単純なモデルを効果的に使用して複雑なモデルを学習し、プログラムのフローと相互作用へのアプローチ方法を再学習する必要があります。複雑なモデルは、現在ハードウェアが存在し、最も支配的な改善が行われる場所であるため、プログラムが最終的に存在すべき場所です。

単純なモデルの実行は分岐のように想定でき、複雑なモデルは複雑な、ええと、エコシステムのように動作します。ドメイン(開発元)が使用する場合、一般的なロックやスレッド化などの単純なモデルの理解は、中間開発者に期待されるべきであるか、まもなく期待されると思います。複雑なモデルを理解することは、今日でも(ほとんどのドメインで)少し珍しいですが、需要は非常に急速に増加すると思います。開発者として、私たちのプログラムの多くがこれらのモデルをサポートする必要があり、これらの概念の理解と実装においてほとんどの使用はかなり遅れています。論理プロセッサ数はハードウェア改善の最も重要な分野の1つであるため、複雑なシステムを理解し、実装できる人々の需要は確実に増加します。

最後に、解決策は単なる「並列化の追加」であると考える人が大勢います。多くの場合、既存の実装を高速化することをお勧めします。多くの場合、はるかに簡単で簡単です。野生の多くのプログラムは最適化されていません。一部の人々は、最適化されていないバージョンが近いうちにハードウェアに食いつぶされるだろうという印象を受けました。パフォーマンスが重要な場合、既存のプログラムの設計やアルゴリズムを改善することも重要なスキルです。問題にコアを追加することは必ずしも最良または最も簡単な解決策ではありません。

現代のPCを対象とする場合、優れた並列システムを実装する必要がある私たちのほとんどは、マルチスレッド、ロック、並列ライブラリ、本を読むだけの価値、プログラムの作成とテストの経験(基本的には、プログラムを書くアプローチ)。


2

私たちはそうしていますが、計算の重いソフトウェアを書いているので、複数のコアから直接利益を得ています。

スケジューラがコア間でスレッドを頻繁に移動する場合があります。それが受け入れられない場合は、コアアフィニティで遊ぶことができます。


0

現状では、プロセッサの周波数は近い将来に増加することはありません。私たちは3 GHzマーク(オーバークロックなし)で立ち往生しています。確かに、多くのアプリケーションでは、非常に基本的なマルチスレッドを超える必要はありません。明らかに、ユーザーインターフェイスアプリケーションを構築している場合は、バックグラウンドスレッドで集中的な処理を行う必要があります。

リアルタイムである必要がある大量のデータを処理するアプリケーションを構築している場合、はい、おそらくマルチスレッドプログラミングを検討する必要があります。

マルチスレッドプログラミングの場合、パフォーマンスが低下することがわかります。時間をかけてプログラムを15%改善し、さらに1週間かけてさらに5%改善するだけです。

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