第4章アルゴリズムの言語による実現:低水準プログラミング言語
Designing Parallel Programs並列プログラムの設計
Designing and developing parallel programs has historically been a very manual process. The programmer is typically responsible for both identifying and actually implementing parallelism. Developing parallel code is often a time-consuming, complex, error-prone, and iterative process. For a number of years now, various tools have been available to assist the programmer with converting serial programs into parallel programs. The most common type of tool used to automatically parallelize a serial program is a parallelizing compiler or pre-processor. A parallelizing compiler generally works in two different ways: fully automatic or programmer directed.
英語のヒント
並列プログラムの設計と開発は、歴史的に非常に手作業の多い過程だった。通常、プログラマーは、どこを並列化できるかを見つけることと、実際に実装することの両方を担う。並列コードの開発は、多くの場合、時間がかかり、複雑で、誤りが起こりやすく、繰返しを要する。ここ何年も、逐次プログラムを並列プログラムへ変換するのを助ける、さまざまなツールが利用できるようになっている。逐次プログラムを自動で並列化する最も一般的なツールは、並列化コンパイラーまたはプリプロセッサーである。並列化コンパイラーは通常、完全自動か、プログラマーによる指示かの、2通りで動く。
In the fully automatic method, the compiler analyzes the source code and identifies opportunities for parallelism. The analysis includes identifying inhibitors to parallelism, and it may determine whether the parallelism would actually improve performance. Loops (do, for) are the most frequent target for automatic parallelization.
英語のヒント
完全自動の方法では、コンパイラーがソースコードを解析し、並列化できる箇所を見つける。解析には、並列化を妨げる要因の特定も含まれ、並列化によって実際に性能が上がるかどうかを判断する場合もある。ループ(do、for)は、自動並列化の最も一般的な対象である。
In the programmer-directed method, the programmer explicitly tells the compiler how to parallelize the code using "compiler directives" or possibly compiler flags. This approach may be used in conjunction with some degree of automatic parallelization. The most common compiler-generated parallelization is done using on-node shared memory and threads.
英語のヒント
プログラマーが指示する方法では、「コンパイラー指示文」や、場合によってはコンパイラーフラグを使い、コードをどう並列化するかを、プログラマーが明示的にコンパイラーへ伝える。この手法は、ある程度の自動並列化と併用できる。コンパイラーによる最も一般的な並列化は、ノード内の共有メモリとスレッドを使う。
If you are beginning with an existing serial code and have time or budget constraints, then automatic parallelization may be the answer. However, there are several important caveats that apply to automatic parallelization: wrong results may be produced, performance may actually degrade, it can be much less flexible than manual parallelization, is limited to a subset (mostly loops) of code, and it may actually not parallelize code if the compiler analysis suggests there are inhibitors or the code is too complex.
英語のヒント
既存の逐次コードから始め、時間や予算の制約があるなら、自動並列化が答えになるかもしれない。しかし、自動並列化には、いくつかの重要な注意点がある。誤った結果を出す可能性があり、性能が実際には落ちることもある。手動の並列化よりはるかに柔軟性が低い場合があり、コードの一部、主にループに限られる。さらに、コンパイラーの解析で妨げる要因が見つかったり、コードが複雑すぎたりすると、そもそも並列化されない場合もある。
The first step in developing parallel software is to (1) understand the problem that you wish to solve in parallel. Next steps include (2) partitioning, or breaking the problem into discrete "chunks" of work; (3) identifying the need for communications between tasks; (4) synchronizing the sequence of work and the tasks being performed; (5) identifying data dependencies between program statements; (6) performing load balancing to distributing approximately equal amounts of work among tasks so that all tasks are kept busy all of the time; (7) establishing granularity as the qualitative measure of the ratio of computation to communication; (8) managing I/O operations that are generally regarded as inhibitors to parallelism; (9) debugging (a technique where the program is read through line-by-line to check for any bugs) parallel code; and (10) analyzing and tuning parallel program performance. Figure 4.31 shows these steps.
英語のヒント
並列ソフトウェア開発の最初の手順は、(1)並列に解きたい問題を理解することである。続く手順は、(2)分割、つまり問題を独立した作業の「塊」に分けること、(3)タスク間で必要な通信を特定すること、(4)作業の順序と、実行されるタスクを同期させること、(5)プログラムの文同士のデータ依存関係を特定することである。さらに、(6)すべてのタスクが常に働き続けるよう、ほぼ等量の作業を各タスクに配る負荷分散を行うこと、(7)計算と通信の比率を定性的に表す尺度として、粒度を定めること、(8)一般に並列化を妨げるとみなされる入出力操作を管理すること、(9)並列コードをデバッグすること、(10)並列プログラムの性能を解析し、調整することがある。デバッグとは、バグを調べるためにプログラムを1行ずつ読み進める技法である。図4.31は、これらの手順を示す。

attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license · CC BY 4.0 · Source出典
Figure 4.31 Developing parallel software follows ten important steps. (attribution: Copyright Rice University, OpenStax, under CC BY 4.0 license)
図4.31 並列ソフトウェアの開発は、10の重要な手順に従う。(出典表記:著作権者 Rice University、OpenStax、CC BY 4.0ライセンス)
LINK TO LEARNING学習リンク
Parallel programming is a deep subject with many avenues for further study, from the low-level details of hardware and programming to high-level parallel algorithm design. Learn more about the Introduction to Parallel Computing Tutorial (https://openstax.org/r/76ParallelComp) at Lawrence Livermore National Laboratory.
英語のヒント
並列プログラミングは奥深い分野であり、ハードウェアとプログラミングの低水準の細部から、高水準の並列アルゴリズム設計まで、さらに学ぶ道が多くある。ローレンス・リバモア国立研究所の並列計算入門チュートリアル(https://openstax.org/r/76ParallelComp)で、さらに学ぼう。
Using C with MPI and OpenMP Parallel LibrariesCでMPIとOpenMPの並列ライブラリーを使う
We focus here on how parallel programs can be written in the C language using an API, which is the most popular method. Some programming languages support parallel programming and may also be used to program parallel applications using message passing features that are built into the language itself. A message passing feature is a parallel programming approach where separate processes communicate only by sending messages, not sharing memory. The symmetric multiprocessor (SMP) model applies when programming multiple processors that are practically identical. OpenMP is a library for parallel programming in the SMP model. When programming with OpenMP, all threads share memory and data. OpenMP supports C, C++ and Fortran. The OpenMP functions are included in a header file called omp.h. An OpenMP program has sections that are sequential and sections that are parallel. In general, an OpenMP program starts with a sequential section in which it sets up the environment, initializes the variables, and so on. When run, an OpenMP program will use one thread in the sequential sections, and several threads in the parallel sections. The parent thread is the thread that runs from the program beginning through end, and starts and manages child threads. A child thread is started by the parent thread and only runs for a limited period in a parallel section. A section of code that is to be executed in parallel is marked by a special directive that will cause child threads to form. Each thread executes the parallel section of the code independently. When a thread finishes, it joins the parent. When all threads finish, the parent continues with code following the parallel section.
英語のヒント
ここでは、最も一般的な方法である、APIを使ってC言語で並列プログラムを書く方法に焦点を当てる。並列プログラミングに対応する言語もあり、その言語自体に組み込まれたメッセージパッシング機能を使って、並列アプリケーションを書ける。メッセージパッシング機能は、別々のプロセスがメモリを共有せず、メッセージの送信だけで通信する、並列プログラミングの手法である。対称型マルチプロセッサー(SMP)モデルは、実質的に同一の複数のプロセッサーをプログラミングするときに当てはまる。OpenMPは、SMPモデルの並列プログラミングのためのライブラリーである。OpenMPでは、すべてのスレッドがメモリとデータを共有する。C、C++、Fortranに対応しており、OpenMPの関数はomp.hというヘッダーファイルに含まれる。OpenMPプログラムには、逐次実行の部分と並列実行の部分がある。一般に、環境の設定や変数の初期化などを行う逐次実行部分から始まる。実行すると、逐次実行部分では1つのスレッド、並列実行部分では複数のスレッドを使う。親スレッドは、プログラムの最初から最後まで動き、子スレッドを開始して管理するスレッドである。子スレッドは親スレッドが開始し、並列実行部分の限られた期間だけ動く。並列に実行するコードの部分には、子スレッドを生成させる特別な指示文を付ける。各スレッドは、並列部分のコードを独立に実行する。スレッドが終わると、親へ合流する。すべてのスレッドが終わると、親は並列部分の後のコードを続けて実行する。