Quantcast
Viewing all articles
Browse latest Browse all 25

goroutineとスレッドの違いって?

この記事は、Go3 Advent Calendar 2018 の11日目の記事です。

はじめに

Goにはgoroutineという並行処理を簡単に実行できる機能があります。
goroutineは「goroutineとは軽量スレッドである」と説明されていますが、結局goroutineとスレッドって何が違うのかということを調べてみました。

まず最初に言うとgoroutineの実体はスレッドです。
ですが大きく3つの違いがあります。順番に見ていきましょう。

メモリ消費量

スレッドのデフォルトスタックサイズは Windows だと 1 MB、Linux だと 2 MB で
goroutineは数キロバイトで済みます。
必要に応じてヒープ領域を割り当てたり開放したりします。一方でスレッドはスレッド間のメモリが干渉し合わないように「スタックガードページ」と呼ばれる 1Mbの領域の確保から始めます。
数キロバイトで済む goroutine に比べると、10 KB だとしても100〜200倍の違いがあります。

生成と破棄に要する時間

スレッドは生成と破棄のたびに OS に要求を投げて、それが完了して返ってくるのを待つため時間がかかります。
一方で goroutine では、生成と破棄に関する操作を非常に低コストで行うことができます。

スイッチングに要する時間

スレッドがブロックされると、別のスレッドがスケジューリングされます。 プリエンプティブ方式でスレッドがスケジューリングされ、スレッドの実行がスイッチされる際にスケジューラーは全てのレジスタ、つまり 16種類の汎用レジスタ、PC(プログラムカウンタ)、SP(スタックポインタ)、16種類の XMM レジスタ、 FP co-processor の状態、16種類の AVX レジスタ、そしてモデル固有のレジスタを別の場所に保存したり、保存したそれらをレジスタに戻す処理が必要になります。これはスレッド間で迅速にスイッチングしたい場合に、無視できません。
goroutine は協調してスケジューリングされ、スイッチングが発生したときも、たった 3つのレジスタ(PC、SP、DX)しか保存したり、レジスタに戻したりしません

まとめ

Goは並行処理をするにあたってgoroutineを使うことによってメモリ消費量を抑えてました。
メモリ使用量が多くなり過ぎると、スワップが発生し性能低下を招くため、小さなメモリ使用量で済むというのは大きな利点だと思います。
ここで述べた以外にもgoroutineはスレッドよりも起動時間が早かったり、メモリ消費量がすくないためスレッドに比べてもより多く
の並行処理を実行することができるとも言われています。(他にも利点は色々とある)
並行処理が簡単に実行できて、スレッドよりも数多くの並行処理を実行できるgoroutineという機能があるGoは最高ですね。
(気付いた点等ございましたら、お知らせください)


Viewing all articles
Browse latest Browse all 25

Trending Articles