非同期プログラミングと並列プログラミングの違いを明確にする方法は?


138

多くのプラットフォームは、応答性を向上させる手段として非同期性と並列性を促進しています。私はその違いを大まかに理解していますが、自分自身や他の人の心の中で明確に表現するのは難しいと感じることがよくあります。

私は平凡なプログラマーであり、非同期とコールバックをかなり頻繁に使用しています。並列処理はエキゾチックです。

しかし、特に言語設計レベルでは、それらは簡単に融合しているように感じます。それらがどのように関連しているか(または関連していないか)の明確な説明と、それぞれが最もよく適用されるプログラムのクラスが気に入っています。


-私は、非同期および並列プログラミングの関係についてのブログ記事を書いた anat-async.blogspot.com/2018/08/...
アレクセイ・カイゴローダブ


6
並列処理とは、物事が同時に発生することです。非同期性とは、アクションの結果が続くのを待たなくてもよいときです。あなたはただ眠りにつくだけで、ある時点で結果が出てきて、ベルが鳴り、目が覚めてそこから続けます。非同期実行は、1つのスレッドでのみ完全に連続して実行できます。(それはほとんどjavascriptが行うことです)
Thanasis Ioannidis

回答:


87

非同期で何かを実行する場合は、それが非ブロッキングであることを意味します。それが完了するのを待たずに実行し、他の処理を続行します。並列処理とは、複数の処理を同時に並行して実行することを意味します。並列処理は、タスクを独立した作業に分割できる場合に適しています。

たとえば、3Dアニメーションのフレームをレンダリングします。アニメーションのレンダリングには長い時間がかかるため、アニメーション編集ソフトウェアからそのレンダリングを起動する場合は、非同期で実行されていることを確認して、UIがロックされず、他のことを続行できるようにします。現在、そのアニメーションの各フレームは、個別のタスクと見なすこともできます。複数のCPU /コアまたは使用可能な複数のマシンがある場合、複数のフレームを並行してレンダリングして、全体的なワークロードを高速化できます。


これが手に入るかどうか見てみましょう。異なるフレームをレンダリングする並列タスクは、複数のCPU /コアに分散する必要があります。これは、タスクの完了のタイミング、またはそのタスクが他の何かをブロックするかどうかには関係ありません。これは、一連のCPUが一緒に実行し、1つの超高速CPUで実行されているかのように結果を利用できることを意味します。正しい?

1
「アニメーションをレンダリングするには時間がかかるため、アニメーション編集ソフトウェア内からそのレンダリングを起動する場合は、必ず確認してください(...)」。何?

3Dアニメーションの場合:まず、CPUでフレームを生成する3Dグラフィックプログラムを実行することはありません。正気な人はすぐにGPUの使用を提案します。次に、これを行うと(非常に非推奨)、タイマーを使用してレンダリングできるフレーム数を測定します。それ以外の場合は、終了していないレンダリング呼び出しタスクのスタックを構築するだけです。ただし、ユーザーごとの入力イベントベースでレンダリングするほとんどの2Dレンダリングアプリケーションで、あなたの主張は完全に有効です。
ワイキんぐ

1
非同期と非ブロッキングは異なるパラダイムです。
ローンの侯爵

72

主な違いは同時実行並列処理の違いだと思います。

非同期コールバックは、通常、同時実行性、つまり、互いに対話してリソースを共有するエンティティのセットを表現する方法(ツールまたはメカニズム)です。非同期またはコールバック通信の場合は暗黙的ですが、リソースの共有はオプションです(リモートマシンで結果が計算されるRMIを検討してください)。正しく述べたように、これは通常、応答性を考慮して行われます。長い待ち時間のイベントを待たないようにするため。

並列プログラミングは通常、スループットを主な目的としていますが、レイテンシ、つまり単一要素の完了時間は、同等の順次プログラムよりも悪い場合があります。

並行処理と並列処理の違いをよりよく理解するために、並行処理の理論に関する優れた一連のメモであるダニエレバラッカの並行処理確率モデルから引用します。

計算モデルは、システムを独立した自律コンポーネントで構成されている可能性があり、相互に通信しているものとしてシステムを表すことができる場合の同時実行性のモデルです。並行性の概念を、並列処理の概念と混同しないでください。並列計算には通常、複数のプロセッサ間で作業を分散する中央制御が含まれます。並行性では、コンポーネントの独立性、およびコンポーネントが相互に通信するという事実を強調します。並列処理はファラオが決定し、奴隷が働く古代エジプトのようなものです。同時実行性は現代のイタリアのようなものであり、誰もが望むことを実行し、すべてが携帯電話を使用します。

結論として、並列プログラミングは並行性の特別なケースであり、別個のエンティティーが協力して(一般に)高いパフォーマンスとスループットを実現します。

非同期とコールバックは、プログラマが並行性を表現できるメカニズムにすぎません。master / workerやmap / reduceなどのよく知られた並列プログラミングデザインパターンは、このような低レベルのメカニズム(非同期)を使用してより複雑な集中型の相互作用を実装するフレームワークによって実装されることを考慮してください。


37

この記事はそれを非常によく説明しています:http : //urda.cc/blog/2010/10/04/asynchronous-versus-parallel-programming

非同期プログラミングについてこれがあります:

非同期呼び出しは、アプリケーション内の「ブロック」を防ぐために使用されます。[そのような]呼び出しは、既存のスレッド(I / Oスレッドなど)でスピンオフし、可能な場合はそのタスクを実行します。

これは並列プログラミングについてです:

並列プログラミングでは、まだ作業またはタスクを分割しますが、主な違いは、作業のチャンクごとに新しいスレッドを起動することです

そしてこれは要約すると:

非同期呼び出しを使用するシステムですでに使用されてスレッドをし、並列プログラミングが必要です必要な作業まで、スピンアップ、およびティアダウンスレッドを破るために、開発者を


3
この記事>ここでのすべての回答(もちろんこれを除いて!)
FellyTone84

1
リンクをありがとう。したがって、一般的には、UIからサーバーへ(またはクライアントからWebサービスへ)通信するときに非同期呼び出しを使用します。サーバーまたはWebサービスエンド、およびビジネスレイヤーで並列スレッドを使用します。
goku_da_master 2015

18

私の基本的な理解は:

非同期プログラミングは、他に何かをする前に、高価な操作が完了するのを待つという問題を解決します。操作が完了するのを待っている間に他のことを実行できる場合、それは良いことです。例:移動中にUIを実行し続け、Webサービスからさらにデータを取得する。

並列プログラミングは関連していますが、大きなタスクを同時に計算できる小さなチャンクに分割することにより関心があります。次に、小さいチャンクの結果を組み合わせて、全体的な結果を生成できます。例:個々のピクセルの色が本質的に独立しているレイトレーシング。

それはおそらくもっと複雑ですが、それが基本的な違いだと思います。


これはうまくいきますが、それはかなり間違っています。非同期性と同様に、並列処理により、アクションの完了を待たずに制御フローを続行できます。主な違いは、並列処理がハードウェアに依存することです。
serkan

13

私はこれらの用語の違いについて考える傾向があります:

非同期:離れてこのタスクを実行します。終了したら、戻ってきて、私に言って結果をもたらします。その間、他のことを続けます。

パラレル:このタスクを実行してほしい。それが簡単になる場合は、何人かの人々に助けを求めてください。これは緊急ですが、結果が返されるまでここで待機します。あなたが戻ってくるまで私は他に何もできません。

もちろん、非同期タスクは並列処理を利用するかもしれませんが、違いは、少なくとも私の考えでは、操作の実行中に他の処理を続行するか、結果が出るまですべてを完全に停止するかです。


13

async:別の場所で自分でこれを行い、完了(コールバック)したときに通知してください。その時までに、私は自分のことを続けることができます。

ここに画像の説明を入力してください

parallel:必要な数の人(スレッド)を雇い、ジョブをそれらに分割して、より早く完了させ、完了時に知らせます(コールバック)。そろそろ他のことをやっていけるかも

ここに画像の説明を入力してください

主な違いは、並列処理は主にハードウェアに依存することです。


11

それは実行の順番の問題です。

AがBと非同期である場合、AのサブパートがBのサブパートに関していつ発生するかを事前に予測することはできません。

AがBと並列である場合、Aの事柄はBの事柄と同時に発生します。ただし、実行の順序はまだ定義されている場合があります。

おそらく難しいのは、非同期という言葉が曖昧であることです。

店員にワインとチーズを買いに行くように言ったとき、非同期タスクを実行し、彼を忘れて、彼が書斎のドアをもう一度ノックするまで、小説に取り組みます。ここでは並列処理が行われていますが、執事と私は根本的に異なるタスクと異なる社会階級に従事しているため、ここではそのラベルを適用しません。

私のメイドのチームは、それぞれが別のウィンドウを洗っているときに並行して作業しています。

私のレースカーサポートチームは非同期的に並行しており、各チームは異なるタイヤで作業しており、仕事をしている間、互いに通信したり、共有リソースを管理したりする必要はありません。

私のフットボール(別名サッカー)チームは、各プレーヤーがフィールドに関する情報を個別に処理し、フィールド上を移動するため、並行して作業しますが、他のユーザーの通信に応答する必要があるため、完全に非同期ではありません。

私のマーチングバンドも平行しています。各プレーヤーが音楽を読み取り、楽器を制御しますが、非常に同期的です。つまり、お互いに時間を合わせて演奏して行進します。

カム式ガトリングガンは並列と見なすことができますが、すべてが100%同期しているため、1つのプロセスが前進しているように見えます。


9

なぜ非同期なのか?

今日のアプリケーションはますます接続されており、実行時間が長いタスクや、ネットワークI / Oやデータベース操作などの操作をブロックしている可能性があるため、これらの操作の待ち時間をバックグラウンドで開始してユーザーインターフェイスに戻すことにより、これらの操作の待ち時間を隠すことが非常に重要ですできるだけ早く。ここで、非同期性が応答性の画像に登場します。

なぜ並列プログラミングなのか?

今日のデータセットが大きくなり、計算がより複雑になっています。したがって、この場合は、ワークロードをチャンクに分割し、それらのチャンクを同時に実行することにより、これらのCPUバインド操作の実行時間を短縮することが非常に重要です。これを「パラレル」と呼ぶことができます。明らかにそれは私たちのアプリケーションに高いパフォーマンスを与えます。


5

非同期 あなたがクライアントの連絡窓口であり、応答性が必要であるとしましょう。つまり、ステータス、操作の複雑さ、必要なリソースなどを要求されたときに共有する必要があります。これで、時間のかかる操作を実行できるようになり、24時間年中無休でクライアントに応答する必要があるため、これを取り上げることができなくなりました。したがって、時間のかかる操作を他の誰かに委任して、応答性を高めることができます。これは非同期です。

並列プログラミング たとえば、テキストファイルから100行を読み取るタスクがあり、1行の読み取りに1秒かかるとします。したがって、テキストファイルを読み取るには100秒かかります。これで、クライアントは操作が完了するまで100秒待つ必要があると心配しています。したがって、さらに9つのクローンを作成し、それぞれにテキストファイルから10行を読み取らせます。これで、100行を読み取るのにかかる時間はわずか10秒になります。したがって、パフォーマンスが向上します。

要約すると、応答性を達成するために非同期コーディングが行われ、パフォーマンスのために並列プログラミングが行われます。


4

非同期:ブロックせずにバックグラウンドでメソッドまたはタスクを実行します。必ずしも別のスレッドで実行する必要はありません。コンテキスト切り替え/時間スケジューリングを使用します。

並列タスク:各タスクは平行して実行されます。コンテキスト切り替え/時間スケジューリングを使用しません。


4

私は2つの概念についてはかなり快適にここに来ましたが、それらについて私にははっきりしないものがあります。

いくつかの回答を読んだ後、違いを説明するための正確で役立つメタファーがあると思います。

コードの個々の行を別々の順序付けられたトランプとして考える場合(私が古い学校のパンチカードがどのように機能するかを説明している場合は、私を止めてください)、書かれた個別の手順ごとに、一意のカードのスタックがあります(しないでください)コピー&ペースト!)と、コードを正常に非同期に実行したときに通常起こることの違いは、気にするかどうかによって異なります。

コードを実行すると、OSにプロセッサに渡される単一の操作のセット(コンパイラまたはインタープリタが「より高い」レベルのコードを分割したもの)を渡します。1つのプロセッサでは、一度に1行のコードしか実行できません。したがって、複数のプロセスを同時に実行しているような錯覚を実現するために、OSは、特定のプロセスから一度に数行だけをプロセッサに送信し、見え方に従ってすべてのプロセスを切り替えるという手法を使用します。フィット。その結果、複数のプロセスが同時に見えるようにエンドユーザーに進行状況を示します。

比喩では、OSは常にカードをシャッフルしてからプロセッサに送信するという関係にあります。カードのスタックが別のスタックに依存していない場合、別のスタックがアクティブになったときにスタックが選択されなくなったことに気付かないでしょう。したがって、気にしない場合は問題ではありません。

ただし、気をつければ(たとえば、複数のプロセスまたはカードのスタックがあり、互いに依存している場合)、OSのシャッフルによって結果が台無しになります。

非同期コードを作成するには、その順序が最終的に何であるかに関係なく、実行順序間の依存関係を処理する必要があります。これが、「コールバック」などの構造が使用される理由です。彼らはプロセッサに、「次にすべきことは、私たちが何をしたかを他のスタックに伝えることです」と言います。そのようなツールを使用することにより、OSがそれ以上の命令を実行することを許可する前に、他のスタックに通知が送られることが保証されます。( "called called_back == false:send(no_operation)"-これが実際にどのように実装されているかはわかりませんが、論理的には一貫していると思います。)

並列プロセスの場合の違いは、お互いを気にしない2つのスタックと、それらを処理する2つのワーカーがあることです。1日の終わりに、2つのスタックの結果を組み合わせる必要がある場合があります。これは、同時性の問題になりますが、実行する場合は、再び気にする必要はありません。

これが役立つかどうかはわかりませんが、常に複数の説明が役立つと思います。また、非同期実行は個々のコンピューターとそのプロセッサーに制限されないことに注意してください。一般的に言えば、それは時間、または(さらに一般的に言えば)イベントの順序を扱います。したがって、依存スタックAをネットワークノードXに送信し、その結合スタックBをYに送信する場合、正しい非同期コードは、ラップトップでローカルに実行されているかのように状況を説明できるはずです。


2

通常、毎回複数のことを実行できる方法は2つしかありません。1つは非同期で、もう1つは並列です。

上位レベルから、人気のサーバーNGINXや有名なPythonライブラリTornadoのように、どちらも非同期パラダイムを完全に利用しています。つまり、シングルスレッドサーバーは数千のクライアント(いくつかのIOloopコールバック)を同時に処理できます。非同期プログラミングパラダイムを実装できるECF(exception control follow)を使用する。そのため、非同期では実際には同時には実行されないことがありますが、一部のioバインドされた作業では、非同期が実際にパフォーマンスを向上させる可能性があります。

平行パラダイムは常にマルチスレッドおよびマルチプロセッシングを指します。これにより、マルチコアプロセッサを十分に活用して、本当に同時に処理を実行できます。


-1

上記のすべての回答の要約

  1. 並列計算:

▪スループットの問題を解決します。大きなタスクを小さなチャンクに分割することに懸念

▪マシン関連(マルチマシン/コア/ cpu /プロセッサが必要)、例:マスタースレーブ、マップリデュース。

並列計算には通常、複数のプロセッサ間で作業を分散する中央制御が含まれます

  1. 非同期:

▪レイテンシの問題、つまり、コストのかかる操作が完了するまで「待機」してしまう問題を解決します。

▪スレッド関連(マルチスレッドが必要)

スレッド化(Thread、Runnable、Executorを使用)は、Javaで非同期操作を実行するための1つの基本的な方法です

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