マルチコアと同時実行 - 言語、ライブラリ、開発テクニック [終了]
-
02-07-2019 - |
質問
CPU アーキテクチャの状況は変化しており、マルチコアはソフトウェアの開発方法を変えるトレンドです。私は C、C++、Java でマルチスレッド開発を行い、さまざまな IPC メカニズムを使用してマルチプロセス開発を行ってきました。スレッドを使用する従来のアプローチでは、開発者が高度な同時実行性をサポートするハードウェアを利用するのは簡単ではないようです。
同時アプリケーションを作成する際の従来の課題を軽減するのに役立つ言語、ライブラリ、および開発テクニックを知っていますか?私は明らかにデッドロックや競合状態などの問題を考えています。設計手法、ライブラリ、ツールなど。また、利用可能なリソースを実際に活用し、確実に利用できるようにする機能も興味深いものです。安全で堅牢なスレッド アプリケーションを作成するだけでは、利用可能なすべてのコアが確実に使用されるわけではありません。
私がこれまでに見たものは次のとおりです。
- アーラン:プロセスベース、メッセージパッシング IPC、同時実行の「アクターモデル」
- ドラマティス:Ruby および Python 用のアクター モデル ライブラリ
- スカラ座:同時実行サポートが追加された JVM 用の関数型プログラミング言語
- クロージュア:アクター ライブラリを備えた JVM 用の関数型プログラミング言語
- シロアリ:Erlang のプロセス アプローチと Scheme へのメッセージ受け渡しのポート
他に何を知っていますか、何が効果的で、何が興味深いと思いますか?
解決
私は 2 つのパラダイムシフトを提案します。
ソフトウェアトランザクションメモリ
という概念を見てみるのもいいかもしれません ソフトウェアトランザクションメモリ (STM)。アイデアは、使用することです オプティミスティック同時実行:他の操作と並行して実行される操作は、分離されたトランザクションでジョブを完了しようとします。ある時点で、このトランザクションが動作しているデータを無効にする別のトランザクションがコミットされた場合、トランザクションの作業は破棄され、トランザクションが再度実行されます。
このアイデアの最初の広く知られた実装 (概念実証で最初の実装ではないにしても) は Haskell の実装だと思います。 Haskell のトランザクション メモリに関する論文とプレゼンテーション. 。他にも多くの実装がリストされています。 ウィキペディアの STM 記事.
イベントループとプロミス
並行性を処理する別の非常に異なる方法が [E プログラミング言語](http://en.wikipedia.org/wiki/E_(プログラミング言語%29).
同時実行性の処理方法や言語設計の他の部分は、アクター モデルに大きく基づいていることに注意してください。
他のヒント
Java について言及しましたが、スレッドについてのみ言及しています。Java の同時実行ライブラリを調べたことがありますか?Java 5 以降にバンドルされています。
これは、ThreadPools、CopyOnWriteCollections などを含む非常に優れたライブラリです。次のドキュメントを確認してください。 Java チュートリアル. 。または、お好みであれば、 Java ドキュメント.
使ったことがある 処理 パイソン用。の API を模倣します。 ねじ切り モジュールなので非常に使いやすいです。
たまたま使ってしまったら map/imap
またはジェネレーター/リスト内包表記、コードを変換して使用する processing
は簡単です:
def do_something(x):
return x**(x*x)
results = [do_something(n) for n in range(10000)]
と並列化できます
import processing
pool = processing.Pool(processing.cpuCount())
results = pool.map(do_something, range(10000))
これにより、結果を計算するために必要なプロセッサがいくつでも使用されます。怠け者もいます(Pool.imap
) および非同期バリアント (Pool.map_async
).
を実装するキュークラスがあります Queue.Queue
, 、およびスレッドに似たワーカー。
落とし穴
processing
に基づいています fork()
, 、Windows上でエミュレートする必要があります。オブジェクトは以下を介して転送されます pickle
/unpickle
, したがって、これが機能することを確認する必要があります。すでにリソースを取得しているプロセスをフォークすることは、望んでいることではないかもしれません (データベース接続を考えてください) が、一般的には機能します。これは非常にうまく動作するため、Python 2.6 に高速で追加されました (cf. PEP-317).
インテルの ビルディングブロックのスレッド化 C++ については、私にとって非常に興味深いようです。生のスレッドよりもはるかに高いレベルの抽象化を提供します。オライリーは非常に 素敵な本 枯れ木のドキュメントが好きなら。以下も参照してください。 インテルのスレッディング ビルディング ブロックを使用した経験はありますか?.
私ならこう言います:
モデル:スレッド + 共有状態、アクター + メッセージ パッシング、トランザクション メモリ、マップ/リデュース?言語:Erlang、IO、Scala、Clojure、Reia Libraries:Retlang、Jetlang、Kilim、Cilk++、フォーク/ジョイン、MPI、Kamaelia、Terracotta
私はこのようなもの (Erlang、Scala、Java スレッド、アクター モデルなど) に関する同時実行リンクのブログを管理しており、1 日にいくつかのリンクを掲載しています。
私は 20 年近くにわたって Ada で同時プログラミングを行ってきました。
言語自体 (ライブラリに組み込まれたものではありません) は、スレッド化 (「タスク」)、複数のスケジューリング モデル、および複数の同期パラダイムをサポートしています。組み込みプリミティブを使用して独自の同期スキームを構築することもできます。
エイダのことを考えることができます 待ち合わせ 一種の手続き指向の同期機能として、 保護されたオブジェクト よりオブジェクト指向になっています。ランデブーは、古い CS の概念に似ています。 モニター, 、しかしはるかに強力です。保護オブジェクトは、OS ロック、セマフォ、イベントなどとまったく同じものを構築できる同期プリミティブを備えた特別なタイプです。ただし、これは十分に強力であるため、正確なニーズに応じて独自の種類の同期オブジェクトを発明して作成することもできます。
質問 将来のメニーコア プロセッサを活用するために、現在推奨する並列プログラミング モデルは何ですか? すでに質問されています。そこでも次のような答えを出しました。
カマエリア です Pythonフレームワーク 多くの通信プロセスを伴うアプリケーションを構築する場合。
こちらは Pycon 2009 のビデオです。まず、Kamaelia と Twisted Python および Parallel Python を比較し、その後、Kamaelia の実践的なデモンストレーションを行います。Kamialia - 同時実行が便利で楽しくなりました
カマエリアでは、以下からシステムを構築します 相互に通信する単純なコンポーネント. 。これにより、開発がスピードアップされ、メンテナンスが大幅に容易になるだけでなく、 自然な同時実行ソフトウェアを構築する. 。アクセスできるようにすることを目的としています どれでも 初心者を含む開発者。それも楽しくなります:)
どのようなシステムですか?ネットワーク サーバー、クライアント、デスクトップ アプリケーション、pygame ベースのゲーム、トランスコード システムとパイプライン、デジタル TV システム、スパム削除ツール、教育ツール、その他多数:)
Kamialia との簡単な同時実行 - パート 1 (59:08)
Kamialia との簡単な同時実行 - パート 2 (18:15)
私は注意深く見守っています .NET用の並列拡張機能 そして 並列LINQ.
私は知っています レイア - Erlang に基づいていますが、Python/Ruby に似た言語です。
この質問は、重複ではないにしても、密接に関連しています。 将来のメニーコア プロセッサを活用するために、現在推奨する並列プログラミング モデルは何ですか?
Java にもアクター ライブラリがあります。. 。そして、あなたはJを知っていましたか?avaは関数型言語ですか? ;)
スレッドを処理するので、C++ アプリケーションのどの部分を並行して実行するかだけを考慮する必要があります。
例えば。
#pragma omp parallel for
for (int i=0; i < SIZE; i++)
{
// do something with an element
}
上記のコードは、openmp ランタイムに使用するよう指示した数のスレッドで for ループを実行します。そのため、SIZE が 100 でクアッドコア ボックスがある場合、for ループは各コアで 25 個のアイテムを実行します。
さまざまな言語用の並列拡張機能が他にもいくつかありますが、私が最も興味があるのは、グラフィック カード上で実行される拡張機能です。それが本当の並列処理です:) (例: GPU++ そして リブシュ)
C++0x が提供します std::lock
複数のミューテックスを一緒にロックするための関数。これは、ロックの順序が乱れることによるデッドロックを軽減するのに役立ちます。また、C++0x スレッド ライブラリには Promise、Future、およびパッケージ化されたタスクがあり、これにより、スレッドはユーザー レベルのロックなしで別のスレッドで実行された操作の結果を待つことができます。
multiprocessing
は、別の回答で述べたように、マルチコア プログラミングを簡素化する Python ライブラリです。
Pythonで書かれたプログラム multiprocessing
作業をローカル コアではなくクラウド上で配布するように簡単に変更できます。 パイクラウド これを利用して、クラウド上で大規模なオンデマンドの処理能力を提供します。コードの 2 行を変更するだけです。
要点は次のとおりです。マルチコア用のライブラリを選択するとき、クラウド アプローチも意味があるかどうかを尋ねたくなるかもしれません。