
処理に時間がかかるなら並列計算しよう!--イントロダクション--
案内人の加藤です🥕
研究でシミュレーションを行う必要があり、そのシミュレーションに時間がかかるので、先輩に相談したところ「並列計算やりなよ」と言われ、いろいろ教えてもらったので共有します。
今回は、並列計算に入るまでの前座になります。
※基本情報や応用情報を勉強中、または取り終えた人や、研究でとても時間がかかるシミュレーションをする必要がある方向けの記事になります。
一般的なコンピュータはノイマン型コンピュータ
現代のコンピュータの基本的な仕組みとなるモデルのことで、フォン・ノイマンにより提唱された物です。
基本的な要素は以下の5つからなります。
中央処理装置(CPU)
記憶装置(メモリ)
入出装置
出力装置
装置をつなぐ線(バス)
また、特徴は以下の2つです。
プログラム内蔵方式:プログラムとデータがメモリに格納される。
逐次処理:命令を一つずつ順に実行する。
ざっくりとこんなもんです。
プログラム内蔵方式のおかげで、昔は大きな部屋にコンピュータをいくつもよういして、配線でプログラミングしていた状況を打破し、大幅な小規模化を実現できるようになったのです!
逐次処理とは
「逐次」は「次々に」という意味があるので、処理を一つずつ順番に実行する処理です。具体的には、命令とデータを読みだして、命令の内容を理解し、実行するプロセスを順番通りに処理します。
例えば、配列の計算
int main (void){
int a[100] = {1, 2, ..., 100};
int b[100] = {1, 2, ..., 100};
for(int i = 0; i < 100; i++){
printf("%d\n",a[i]+b[i]);
}
}
これを実行すると、
2
4
…
200
のように順番に処理されます。
図で例えれば、「一人の人間がひとつひとつ順番に計算して答えを出している」のです。

デコード = 命令を解読し、何をするか理解する
処理の速さは「クロック周波数」に依存する
クロック周波数とはコンピュータ内部で用いられる基準となる周波数のことです。
クロック周波数はCPUの性能を示す上で重要な指標の1つで、CPU のクロック周波数が高いほど、一定の時間内に多くの信号が処理されます。それゆえ、処理能力は向上することになります
しかし、実はクロック周波数の性能は2000年代に入り頭打ちになっている現状があります。

つまりコンピュータ単体の処理速度はこれ以上は期待できないことがわかります。
では、今のコンピュータの処理速度をもっと上げたいとなったときに、どうするのでしょうか?答えは「並列計算」を用います。しかし、実際に処理速度が上がっているわけではないことに注意してください。
並列処理で計算の速さを上げる(用に見せる)
現在、処理速度を速めるメジャーな手法として多数のCPUコアを搭載することで高速化を実現しています。これが並列処理になります。
逐次処理だと、「一人の人間がひとつひとつ順番に計算して答えを出している」ものでした。
並列処理にすることで、「コア数の人間がひとつひとつ順番に計算して答えを出している」ようになります!
そうです。大人数でやれば速いだろ!です。
サーバは多数のCPUコアとキャッシュからなるプロセッサを複数所持しているので、PCよりも速く結果を返してくれるようになっています。
PC(1人) < サーバ(1000人くらい)
で人数が圧倒的に違いますよね!そりゃ速いよってなります。
逐次処理と並列処理の比較
逐次処理は一人の人間が、命令とデータを持ってきて(フェッチ)、その命令を解読(デコード)し、命令を実行します。N個並んだ命令を順番通りに実行するので逐次処理をする人はN回の逐次処理を行います。

並列処理は複数の人間は、並列処理をする人間を複数に増やすことです。

要は、マンパワーを増やすことで、命令の実行終了時間は短縮できるようになります!N個の命令を実行するとすると、1人あたりの命令実行回数は(N/3)回になります!
一人あたりの処理速度は変わらないので、単純に人が多いほど処理が終了する時間は短縮できます!
ただ、注意するべきこともあって、コンピュータ内のアーキテクチャにより、若干の速度差が生じるという事です。すると、それぞれの人間が処理を実行するまでの時間は非決定的になるので、演算の順序が結果に影響を与える場合は、慎重にならないといけません。例えば、桁落ちや情報落ちが発生してしまいそうなときです。
この問題はプログラムの中身を見て、判断します。
並列処理を行う典型的な物がスーパーコンピュータ
スーパーコンピュータはざっくりといえば多数のサーバを接続した並列計算機になります。科学技術計算や気象予測のシミュレーションで用いられています。
国内だと「富岳」が有名で、コロナ禍での飛沫シミュレーションで用いられて話題になりましたね!
PC (1人) < サーバ (1,000人) < スーパーコンピュータ (1,000,000人)
みたいな感じです!さすが"スーパー"なコンピュータですね!
スーパー = 規模感がえげつない
という事ですので、何でもできるコンピュータではない事は頭に入れておいてください!
並列処理を行わせるプログラムを書く必要がある!
常時、逐次処理を行うので、並列処理を行わせるようにプログラムに反映させる必要があります。しかし、難しいことはなく、逐次処理のプログラム+「並列処理してね」という指示だけでOKなんです!
分割のやり方は、コンパイラに全部任せる方法や、自分でコンパイラに指示する方法があるので、自由に行えます!
終わりに
次回は実際にメジャーどころのC言語とPythonの並列処理のやり方を説明します!