並行処理/並列処理などの低レイヤーの基本を学ぶ
(Reactで並行レンダリングってのが出てきて、「やばいそもそも並行処理とかを知らん」となったので)
まずこれ読む
並行処理
並行処理とは、複数のプロセスが実行可能状態であることで、実際には同時にプロセスが動いていなくてもユーザー側から任意で切り替えが行えます。
人間の目には同時に処理が行われているように見えますが、マルチタスクOSではシングルコアで各プロセスをナノ秒ごとのタイムスライスで区切って高速に切り替えながら1処理ずつ行なっているのです。
並列処理
並列処理とは、計算処理系などの比較的小さくて独立した処理を別々のコアで実行する事で複数コアを持つハードウェアのパフォーマンスを引き出すための手法
マルチコアシステムでない場合には並列には実行できません。
つまり並行はマルチプロセス、並列はマルチコアってこと?
だが並行処理は「実際に並行している」訳ではなくあくまで「並行しているように見える」だけなのは注意か
なるほど
並行処理は1つのコアで各プロセスを高速に切り替えて1処理ずつ行なっていると書きましたね。
これに比べて並列処理は実際に複数のコアで同時に処理を行なっていることを指しています。
ていうことは...
「並列処理で複数コアにしつつ、その1つ1つのコアでは並行処理をする」みたいなこともできちゃうんかな?
とりあえず理解した。
ただそもそもコア,プロセス,スレッドとかが何なのか知らないので、まずこれ読んでみる
へぇ
実行中のプログラムは『プロセス』と呼ばれ、プロセスは 1 つ以上の『スレッド』を持ちます。
ほー、PIDとか出てきた
$ ps auxでシステム上の全プロセスを確認できます。(Mac OS Intelコア)
なるほど、PIDはProcess IDの略か。
プロセス(のメモリ)は独立してる感じか
1 つのプロセスには、OSによって1 つの独立したメモリ空間 (メモリ領域) が割り当てられます。(メモリ空間はプロセスから OS に要求すれば(空きがあれば)増やせます)
プロセスのメモリは自身のものしか参照できないため、基本的にお互いのメモリへアクセスすることはできません。
プロセスとタスクは同じなんだ
コンピュータにおいて複数のプロセス(タスク)を切り替えて実行できるシステムのことをマルチプロセス(マルチタスク)と言います。
なるほど、スレッドはメモリ空間共有するのか、おもろいな
一方で、スレッドは、そのスレッドが所属するプロセスのメモリ空間を共有するので、スレッド同士でグローバル変数などの共有リソースへアクセスすることができます。
また、ひとつのプロセスで複数のスレッドが動くことをマルチスレッドと言います。
さっきの
実行中のプログラムは『プロセス』と呼ばれ、プロセスは 1 つ以上の『スレッド』を持ちます。
という文章を踏まえると、「1つ以上」が「1つ」だった場合はマルチプロセスではなく、「2つ以上」だった場合にそれを「マルチプロセス」と呼ぶ感じか
なるほどぉぉぉ。確かにマルチスレッドプログラミング難しそう、でも楽しそう
マルチスレッドプログラミングが難しいと言われる所以が、上述したメモリ空間を共有するという点にあります。複数のスレッドが並行的に実行されるコードを何も考えずに書くと、データ競合、デッドロック、ライブロック、リソース枯渇などの問題を引き起こします。
これらの問題を引き起こさないように、一度に1つのスレッドのみがその共有データにアクセスするようにアプリケーションでしっかり排他制御をしなければなりません。
へぇ。スレッドセーフに書けたとき気持ち良いだろうなぁ
複数のスレッドが並行的に実行されても安全な状態のことを、スレッドセーフであると言います。(Go言語のgoroutineの文脈だとゴルーチンセーフといった言い方をします)
うわー良さげな記事、いつか読みたい
プロセッサがどのようにプログラムを解釈し処理しているかは、下記サイトがわかりやすいかったので是非参考にしてください!
プロセッサ = コアってこと?(プロセッサをよく知らん)
しかし、ムーアの法則により半導体チップに集積できるトランジスタ数が増えたことで、複数のプロセッサを1つの半導体チップに搭載できるようになりました。このそれぞれのプロセッサ部分をコア(CPUコア)と呼びます。そして、コアを複数もつプロセッサをマルチコアプロセッサと呼びます。
とりあえず読み終わった
1つ疑問があって、スレッドを複数もち得るのはプロセスだとさっき言ってなかった?
コアも同じように複数のスレッドを持つのであれば、コアとプロセスの違いは?
しかし、SMTの登場により1つのコアに対して複数のスレッド(多くは2つのスレッド)を割り当てることができるようになりました。(この技術によってスレッドへ割り当てることができる理論上のコア数を論理コア数や仮想コア数と言います)
物理的に1つのコアを、OSからは2つのコアであるように見せかけることができ、コアの利用率を上げることができるようになっています。
図解してる良さげな記事見つけたのでこちらを見ていく
前提知識:同時マルチスレッディング(SMT)とは
並行処理は「1つのコアで複数プロセス」だったが、
同時マルチスレッディングは「1つのコアで複数スレッド」ってことか
同時マルチスレッディング(SMT)とは、1つのコアに複数のスレッド(仕事)を並行で処理させるための技術とか機能とかあれやこれや です。
同時マルチスレッディング(SMT)登場以前はこれ
なるほど、図を見る限りコアはCPU内にあるもので、プロセスはメモリ内にあるものという区別ができそう
そっか確かにプロセスには1つのメモリ空間が対応するって話あったもんな
1 つのプロセスには、1 つのメモリ空間 (メモリ領域) が割り当てられます。メモリ空間はプロセスから OS に要求すれば (空きがあれば) 増やしてくれます。
んで、確かに1つのコアに1つのスレッドしか対応してないな
ほーなるほど、スレッドは「コアを利用する単位」か
スレッドとは、プロセス内で命令を逐次実行する部分であり、CPU コアを利用する単位のことです。
んでコアってCPUコアとも呼ぶのか。やっぱコアはCPU内の概念なんだな
なるほど
ですが最近の CPU は、SMT (Intel ではハイパースレッディングと呼ぶ) 機能を搭載しているモデルが多くなってきており、この機能を使うと、1 つのコアに対して複数のスレッド (多くは 2 つのスレッド) を割り当てることができます。
ほぇ
物理的に 1 つのコアを、OS からは 2 つのコアであるように見せかけることができ、コアの利用率を上げることができるのです。
それを図解したのがこれ。現在はこれが多いとのこと
なるほど、確かに1コアに複数(2つの)スレッドが対応してるな
だが、これだとまだ並行処理つまり「1つのコアに複数のプロセスが動作しているかのように高速切り替え」をしている訳ではないはず
なので並行処理というのは更なる応用の話なのかも?
とはいえ図を見る限り、同時マルチスレッディングは「違うプロセスに属す複数のスレッドを1つのコアに結びつける」ということは行っているっぽいな
(ただそれが並行処理と言えるのかはわからないという感じ)
たしかに。
なので、2 スレッドの SMT に対応している CPU であれば、「スレッド数」は「コアの数」の倍になります。
であれば自分のPCは6コア/12スレッドなので、「2スレッドのSMT(同時マルチスレッディング)に対応しているCPUを持っているPC」をと言えるのかもしれない
なるほど。JSもシングルスレッドなので、それだけを考えるとCPUのスペックに拘っても意味ないか
例えばプロキシソフトの SQUID はシングルスレッドなので、SQUID の動作を早めたい!と思って CPU のコアをたくさん搭載しても、意味がありません。
一方、マルチスレッドの場合は 1 つのプロセス中に複数の処理を並行して行えるので、パフォーマンスが良い傾向にあります。
そしてさっきも見た通り、マルチスレッドにするにしてもメモリの共有による問題は考えないといけないというのはある
なお、プロセス間でメモリ領域を侵食しないかは OS が管理してくれますが、マルチスレッドでは、プロセスに割り当てられた 1 つのメモリ領域を複数のスレッドが共有するので、マルチスレッドアプリケーションがスレッド間で互いにメモリを侵食しないよう、プログラミングする人で意識する必要があります。
へぇ
CPU の Context (コンテキスト) というのがプロセスに紐づいており、この Context にそのプロセスで最後に実行した状態が記憶されており、また順番が回ってきたらその Context から情報を引っ張り出し、処理を継続するのです。
この切替のことを『コンテキストスイッチ』と呼びます。