1. 序章

このチュートリアルでは、オペレーティングシステム(OS)で使用される2つの一般的な処理手法を分析します。 複数のプロセスが実行されるのを待っている場合、通常、これら2つの概念が必要です。

2. 主な定義

並行性と並列性について詳しく説明する前に、これら2つの処理方法の説明で使用されている主要な定義を見てみましょう。

  • マルチプロセッシング:単一のコンピューターシステム内で2つ以上の中央処理装置(CPU)を使用することは、マルチプロセッシングと呼ばれます。
  • マルチスレッド:この手法により、単一のプロセスにスレッドのような複数のコードセグメントを含めることができます。 これらのセグメントは、そのプロセスのコンテキスト内で同時に実行されます。
  • 分散コンピューティング:分散コンピューティングシステムは、単一のシステムとして実行される複数のコンピューターシステムで構成されます。 システム内のコンピューターは、物理的に近接してローカルネットワークで接続することも、離れてワイドエリアネットワークで接続することもできます。
  • マルチコアプロセッサ:[X25X]複数のコアプロセッシングユニットを含む単一の統合プロセッサです。 チップマルチプロセッサ(CMP)とも呼ばれます。
  • パイプライン:実行中に複数の命令がオーバーラップする手法です。

3. 並行性

並行性とは、実際には、重複する期間に複数のタスクを実行できることを意味します。 タスクの1つは、前のタスクが完了する前に開始できます。 ただし、同時に実行されることはありません。 CPUは、タスクごとにタイムスライスを調整し、コンテキストを適切に切り替えます。 そのため、この概念の実装、特にデバッグは非常に複雑です。

3.1. 並行性はどのように機能しますか?

同時実行の主な目的は、アイドル時間を最小化することによってCPUを最大化することです。 現在のスレッドまたはプロセスが入出力操作、データベーストランザクション、または外部プログラムの起動を待機している間、別のプロセスまたはスレッドがCPU割り当てを受け取ります。カーネル側で、OSは割り込みをそれを停止するアクティブなタスク:

2つ以上のジョブがシングルコアまたはマルチコアCPUの同じコアで実行されている場合、それらは同時に同じリソースにアクセスできます。 データの読み取り操作は並行して実行され、安全ですが、書き込みアクセス中、プログラマーはデータの整合性を維持する必要があります。

効率的なプロセススケジューリングは、並行システムにおいて重要な役割を果たします。 先入れ先出し(FIFO)最短ジョブ優先(SJF)、およびラウンドロビン(RR)は、一般的なタスクスケジューリングアルゴリズムです。 。

前述したように、特にカーネルレベルでの同時実行の実装とデバッグは複雑になる可能性があるため、タスクの1つがCPUを長時間取得すると、プロセス間で枯渇する可能性があります。 この状況を防ぐために、割り込みが設計され、CPUが他のプロセスを割り当てるのを助けます。 これは、プリエンプティブスケジューリングとも呼ばれます。 OSは、他のアプリケーションと同様に、同時タスクを調整するためにCPU時間を必要とします。

4. 並列処理

並列処理とは、プログラムの独立したタスクを同時に実行する機能です。 並行タスクとは異なり、これらのタスクは、別のプロセッサコア、別のプロセッサ、または分散システムである可能性のあるまったく異なるコンピュータで同時に実行できます。実世界のアプリケーションからのコンピューティング速度に対する要求が高まるにつれて、並列処理より一般的で手頃な価格になります。

4.1. 並列処理はどのように機能しますか?

下の図は分散システムの例を表しています。前述のように、分散コンピューティングシステムは複数のコンピューターシステムで構成されていますが、単一のシステムとして実行されます。 システム内にあるコンピューターは、物理的に近接してローカルネットワークで接続することも、離れて広域ネットワークで接続することもできます。

並列処理は、パフォーマンスを向上させるために必須です。 並列処理には複数の利点があり、さまざまなレベルの抽象化で実装できます。

  • 上の図からわかるように、分散システムは並列システムの最も重要な例の1つです。 それらは基本的に、独自のメモリとIOを備えた独立したコンピュータです。
  • たとえば、1つの命令セットで管理される、複数の加算器や乗算器などの複数の機能ユニットを使用できます。
  • プロセスのパイプライン化は、並列処理のもう1つの例です。
  • チップレベルでも、並列処理により操作の同時実行性が向上する可能性があります。
  • 同じコンピューターで複数のコアを使用することで、並列処理を利用することもできます。 これにより、携帯電話などのさまざまなエッジデバイスが可能になります。

5. 並行性と並列性

以下の例で、並行性と並列性がどのように機能するかを見てみましょう。 ご覧のとおり、2つのコアと2つのタスクがあります。 同時アプローチでは、各コアは時間の経過とともにそれらを切り替えることによって両方のタスクを実行しています。 対照的に、並列アプローチはタスクを切り替えませんが、代わりに時間の経過とともに並列に実行します。

並行処理のこの単純な例は、テキストエディタなどの任意のユーザー対話型プログラムにすることができます。 このようなプログラムでは、CPUサイクルを浪費するIO操作が発生する可能性があります。 ファイルを保存または印刷するときに、ユーザーは同時に入力できます。 メインスレッドは、入力、保存、および同様のアクティビティを同時に行うために多くのスレッドを起動します。 それらは同じ期間に実行される可能性があります。 ただし、実際には並行して実行されていません。

対照的に、並列システム用のHadoopベースの分散データ処理の例を示すことができます。 多くのクラスターで大規模なデータ処理を必要とし、並列プロセッサーを使用します。 プログラマーは、システム全体を単一のデータベースと見なします。

5.1. 並行性と並列性における潜在的な落とし穴

このチュートリアルで前述したように、並行性と並列性は複雑なアイデアであり、高度な開発スキルが必要です。 そうしないと、システムの信頼性を損なう可能性のあるリスクが発生する可能性があります。

たとえば、並行環境を注意深く設計しないと、デッドロック競合状態、または枯渇が発生する可能性があります。

同様に、並列プログラミングを行う場合にも注意が必要です。 どこで停止し、何を共有するかを知る必要があります。 そうしないと、メモリの破損、リーク、またはエラーに直面する可能性があります。

5.2. 並行性と並列性をサポートするプログラミング言語

プロセスとスレッドを同時に実行することが、並行プログラミング言語が使用する主なアイデアです。 一方、並列処理をサポートする言語を使用すると、プログラミング構造を複数のマシンで実行できるようになります。 命令とデータストリームは、並列処理分類法の重要な用語です。

これらの言語には、いくつかの重要な概念が含まれています。 言語自体を学ぶ代わりに、これらの主題の基礎を理解する方が良いでしょう:

  • システムプログラミング:これは基本的なOSとハードウェアの管理であり、システムコールの実装とOSの新しいスケジューラの作成を含めることができます。
  • 分散コンピューティング:前述したように、並列CPUを利用する必要があります。
  • パフォーマンスコンピューティング:この概念は、CPUリソースの最適化に必要です。

次に、さまざまな言語、フレームワーク、およびAPIを分類しましょう。

  • 共有メモリ言語: Orca、Java、C(いくつかの追加ライブラリを含む)
  • オブジェクト指向の並列処理: Java、C ++、Nexus
  • 分散メモリ: MPI、コンカレントC、エイダ
  • メッセージパッシング: Go、Rust
  • 並列関数型言語: LISP
  • フレームワークとAPI: Spark、Hadoop

これらは、並行性と並列性に使用できるさまざまな言語のほんの一部です。 言語自体の代わりに、Cプログラミング言語用のPOSIXスレッドライブラリなどのライブラリ拡張機能があります。 このライブラリを使用すると、セマフォ、マルチスレッド、条件変数など、ほぼすべての並行プログラミングの概念を実装できます。

6. 結論

この記事では、並行性と並列性がどのように機能するか、およびそれらの違いについて説明しました。 これら2つの概念に関連するいくつかの例を共有し、そもそもなぜそれらが必要なのかを説明しました。 最後に、並行性と並列性の潜在的な落とし穴について簡単に要約し、これら2つの重要な概念をサポートするプログラミング言語をリストしました。