Slide 1

Slide 1 text

FlexSC-Threadsの紹介 プログラムの変更無しに マルチスレッドプロセスを高速化 V1.0.1 Aug 8, 2018 Satoru Takeuchi twitter: satoru_takeuchi 1

Slide 2

Slide 2 text

はじめに ● 本書の目的 ○ “FlexSC: Flexible System Call Scheduling with Exception-Less System Calls”[1]という論文に記載されている FlexSC-Threadsの紹介 ● 執筆動機 ○ FlexSC-Threadsは機能の効果、実装ともにかっこいいので、多 くの人に知ってもらいたかった ○ 元論文を読むのに必要なOS、とくにスケジューラ)の知識が無く ても読める、副読本を作りたかった 2

Slide 3

Slide 3 text

注意点 ● 本書に記載の数値やグラフは単純化してある ● 正確なところを知りたければ、元論文を参照してほ しい ● 元論文以上の知識は得られないので、元論文を最 初から理解できるような人は対象外 ● 本書の中に記載されている「性能」とは、とくに断り がなければCPUのInstruction per secondのこと 3

Slide 4

Slide 4 text

目次 1. FlexSC-Threadsとは 2. 前提知識 3. 動作のしくみ 4. 実装 5. まとめ 6. 参考文献 4

Slide 5

Slide 5 text

FlexSC-Threadsとは: 概要 ● Linuxのマルチスレッドプロセスを高速化する pthread互換ライブラリ ● 使い方: pthreadライブラリとしてFlexSC-Threads をリンク ● プログラムの変更は不要 5

Slide 6

Slide 6 text

FlexSC-Threadsとは: 効果と適用範囲 ● 性能向上の例 ○ Apache: 116%Up ○ MySQL: 40%Up ○ BIND: 105%Up ● 性能向上が見込める条件 ○ スレッド数が多い ○ システムコールの呼び出し頻度が高い 6

Slide 7

Slide 7 text

FlexSC-Threadsとは: 着想 ● 後述の、ユーザモードとカーネルモードの間の状態 遷移(以下、状態遷移と記載)の数を極力減らすこ とによって性能向上を図る ○ 状態遷移の頻度が減少 ○ キャッシュヒット率向上 ○ 性能向上 7

Slide 8

Slide 8 text

FlexSC-Threadsとは: 現在の状況 ● glibcに実装しようとした計画もかつては存在 ○ その後音沙汰が無いので、立ち消えになった模様 ● 自前で実装してみた人もいるらしい[2] ○ 筆者は動作確認をしていないため、まともに動くかどうかは不明 8

Slide 9

Slide 9 text

前提知識(1/3): システムコール発行時の状態遷移 ● プロセスがシステムコールを発行するたびに状態 遷移が2回発生 ユーザモード カーネルモード 状態遷移 ユーザのための システムコールを処理 カーネルから割り当てられた 一部システムリソースしか使えない システムリソースを 全て利用可能 9

Slide 10

Slide 10 text

前提知識(1/3): キャッシュメモリを消費 ユーザモード カーネルモード キャッシュメモリ を消費 10

Slide 11

Slide 11 text

前提知識(1/3): キャッシュメモリ使用の 悪影響 ● カーネルモードから戻ってきてしばらくはキャッシュ ヒット率が下がるため、性能劣化 ユーザプロ セスのIPC システムコール発行 からの経過時間 syscall発行 syscallからの復帰 11

Slide 12

Slide 12 text

前提知識(1/3): 短時間に多くのシステ ムコールを発行した場合 ● 低い性能のまま時間が経過 性能(単位時間 あたりの 命令実行数) 経過時間 ユーザモード カーネルモード トータルでは斜線部分の 面積だけ性能劣化 12

Slide 13

Slide 13 text

前提知識(2/3): スレッドモデル ● スレッドを実装する方法 ○ 1x1モデル: スレッドとカーネル内のスケジューリング対象が1:1 に対応 ■ glibcのデフォルトpthreadライブラリ(NPTL)はこれ ○ Mx1モデル: 同、M(スレッド数):1に対応 ■ 1CPUのFlexSC-Threadsはこれ ○ MxNモデル: 同、MxNに対応 ■ 複数CPUのFlexSC-Threadsはこれ ● どれも一長一短 ● 以降、1x1とMx1について図解説明 13

Slide 14

Slide 14 text

前提知識(2/3): 時分割によるプロセス の並行処理 ● 1CPU上に複数プロセスが存在する場合、各プロ セスが一定時間ごとに、順番にCPUを使用 ● 例) p1, p2, p3の3つのプロセスが存在 ● 全プロセスがCPUを使う処理のみ実行 CPU上で動作 中の処理 時刻経過 p1 p2 p3 p1 p2 14

Slide 15

Slide 15 text

前提知識(2/3): 並行処理時の状態遷 移 ● 実はCPU上で動作するプロセスが変化するたびに状態遷移が起 き、カーネル上のスケジューラという処理が動作(*1) ● スケジューラは次にどのプロセスを動かすかを決定(詳細は割愛) ● そのたびに性能劣化 CPU上で動作 中の処理 カーネルモード p1 ユーザモード p2 p3 p1 p2 時刻経過 *1) 簡単のため、個々のタイマ 割り込みによる状態遷移は無視 15

Slide 16

Slide 16 text

前提知識(2/3): 1x1モデルにおけるス レッドの並行処理 ● 例) 3スレッドt1, t2, t3が存在する場合 ○ 全スレッドがCPUを使う処理のみ実行 ● 結果は複数プロセスが存在する場合と同じ ○ そのたびに性能劣化 CPU上で動作 中の処理 カーネルモード t1 ユーザモード t2 t3 t1 t2 時刻経過 16

Slide 17

Slide 17 text

前提知識(2/3): Mx1モデルにおけるス レッドの並行処理 ● 例) 3スレッドt1, t2, t3が存在する場合 ○ 全スレッドがCPUを使う処理のみ実行 ● CPU上で別スレッドが動き出す際に状態遷移が発 生しない ○ 理由: Mx1モデルはユーザ空間でスレッドのスケジューリングを している CPU上で動作 中の処理 カーネルモード t2 ユーザモード 時刻経過 t1 t3 t1 t2 17

Slide 18

Slide 18 text

前提知識(3/3): システムコールのラッ パ関数 ● 通常、システムコールはlibcのラッパ関数を介して呼び出す ● 直接呼び出すにはアセンブリ言語を使う必要があり、移植性が無い ユーザプロセス 直接呼び出し 移植性なし アーキテクチャ依存 アセンブリ言語で書く libcのラッパ関数呼び出し Cで書く libc経由で呼び出し 移植性あり アーキテクチャ依存 アセンブリ言語で書く libcのラッパ関数 18

Slide 19

Slide 19 text

動作のしくみ: 前置き ● 簡単のため、1CPUの場合について説明 ● 複数CPUの場合でも基本的には同じ ○ ここでいう複数CPUとは、複数コア、複数スレッドの場合も含む 19

Slide 20

Slide 20 text

動作のしくみ: NPTLにおける複数ス レッドの動作 ● スレッドモデルは1x1 ● 例) 複数スレッドt1, t2, t3がCPU上で動作するたびにシステムコー ルを発行 ○ 簡単のため、システムコールがブロックされる場合は考えない ● 大量の状態遷移が発生 CPU上で動作 中の処理 カーネルモード(スケジューラ) ユーザモード 時刻経過 t1 カーネルモード(システムコール処理) t1 t2 t2 t3 t3 t1 t1 20

Slide 21

Slide 21 text

動作のしくみ: FlexSC-Threads ● Mx1スレッドモデル ● システムコール発行時の処理が以下のように変わ る 1. 各スレッドのシステムコール要求を一旦溜めておく 2. 所定のタイミング(後述)で、システムコールを連続実行 21

Slide 22

Slide 22 text

動作のしくみ: FlexSC-Threadsにおけ る複数スレッドの動作 ● 例) 複数スレッドt1, t2, t3がCPU上で動作するたびに システムコールを発行 ● 状態遷移の数が激減することによって性能向上 ○ Mx1モデルなので、CPU上で動作するスレッドが変わっても状態 遷移無し ○ システムコールの発行は3回に1回で済む CPU上で動作 中の処理 カーネルモード(スケジューラ) ユーザモード 時刻経過 カーネルモード(システムコール処理) t1 t2 t3 t1 t2 t3 t1 t2 t3 t1, t2, t3用の システムコールを 連続実行 22

Slide 23

Slide 23 text

動作のしくみ: さらなる性能向上 ● スレッドがn本あれば、n回のシステムコール発行 につき2回だけ状態遷移 ● スレッド数が多くなるほど、システムコール呼び出 し頻度が高くなるほど、システムコールを連続実行 できる頻度が向上し、さらなる性能向上が期待でき る 23

Slide 24

Slide 24 text

動作のしくみ: 複数CPUの場合 ● 全CPUに同じ処理が並ぶだけ(図は2CPUの場合) ○ カーネル処理がCPUの数存在するので、スレッドモデルはM(ス レッド数)xN(CPU数) CPU2上で動 作中の処理 カーネルモード(スケジューラ) ユーザモード 時刻経過 カーネルモード(システムコール処理) t4 t5 t6 t4 t5 t6 t4 t5 t6 CPU1上で動 作中の処理 t1 t2 t3 t1 t2 t3 t1 t2 t3 24

Slide 25

Slide 25 text

実装: 概要 ● 前述のしくみを実現するために、以下の作り込み が必要 ○ カーネル: 新規システムコールの追加 ■ 初期化用 ■ システムコールの連続実行用(以下、連続実行用と記載) ○ FlexSC-Threads: 新規作成 ■ ロード時に初期化用システムコールを呼び出す ■ システムコールのラッパ関数 ■ pthreadライブラリ関数 25

Slide 26

Slide 26 text

実装: 初期化用システムコール ● 連続実行用システムコールを使用可能にする ● ユーザとカーネルの共有メモリを作成し、前述の キューとして使用 ○ キュー内エントリのデータ構造 ■ システムコール実行に必要なパラメタ ■ システムコールの終了状態 ■ 戻り値 ● プロセスにキューのアドレスを返す 26

Slide 27

Slide 27 text

実装: 連続実行用システムコール 1. キューから取り出した全エントリについて、以下の 処理を実行 1. システムコールを実行 2. 実行したシステムコールの戻り値を、該当する キューのエントリに書き込む 3. 終了状態を更新 2. キューが空になったらユーザモードに復帰 27

Slide 28

Slide 28 text

実装: システムコールのラッパ関数 キューにシステムコールのパラメタを書いたエントリを挿入 キューが一杯? 連続実行用システム コールを呼び出す 他に実行可能な スレッドが存在? 他のスレッドにCPU 実行権を明け渡す 自身の戻り値を必要箇所に書き込んだ上で次の処理に進む システムコールが完了済の スレッドを全て起こす 他のスレッドの システムコールが 完了済? Yes No No Yes No Yes 28

Slide 29

Slide 29 text

実装: pthreadライブラリ関数 ● カーネルの助け無しに、ライブラリ内だけでスレッド 制御の仕組みを作成 ○ 理由: スレッドモデルがMx1 29

Slide 30

Slide 30 text

実装: FlexSC-Threadsの動的リンク ● 動的リンクをすれば準備完了 ○ 連続実行用システムコールが使用可能になる ○ libc提供のラッパ関数を上書き ○ pthreadライブラリ関数を上書き ● プログラムのバイナリ変更は不要 ● 以下の場合はFlexSC-Threadsの恩恵を受けられ ない ○ libcを静的リンクしている ○ libc提供のラッパ関数経由でシステムコールを呼んでいない 30

Slide 31

Slide 31 text

複数CPUの場合 ● キューとカーネル処理がCPUごとに存在するだけ で、後は1CPUの場合と一緒 ● キューがCPUごとに存在するため、排他制御は不 要 ● スケーラビリティあり 31

Slide 32

Slide 32 text

まとめ: ユーザから見た変化 ● libcのインターフェイスは全く変更が無いため、プロ グラムは変更不要 ○ スレッドモデルの変更に伴い/proc//以下の見え方が変わ るため、そこに依存するような処理をしている場合には考慮が必 要 ● スレッドライブラリの入れ替えだけで性能向上 ○ システム標準のlibc(通常glibc)が対応していれば、環境変数の 設定など、より簡単な方法でFlexSC-Threadsを使用できるよう になるかも 32

Slide 33

Slide 33 text

まとめ: 使用するにあたって ● システムコールの発行数が少ない or スレッド数が 少ない場合、期待に反して性能劣化する可能性あ り ○ とくにシングルスレッドの場合、システムコール発行毎に連続実 行用システムコールを発行するため使う意味がない ● 使用可否の判断をする前の性能実測が必須 33

Slide 34

Slide 34 text

まとめ: 個人的な感想 ● レイテンシの最悪値/中央値/最良値も見てみたい ○ 元論文中にはスループットと平均レイテンシについての情報の み ○ 個々のレイテンシを重要視するようなシステムにも適用できるか 否かを確認したい ● 原理的には他のOSでも実装可能なので、やってみる と面白いかも 34

Slide 35

Slide 35 text

参考文献 1. Livio Soares and Michael Stumm. FlexSC: Flexible System Call Scheduling with Exception-Less System Calls http://www.cs.cmu.edu/~chensm/Big_Data_rea ding_group/papers/flexsc-osdi10.pdf 2. Github ID “spinlock”. implements flexsc (flexiable system call, OSDI '10) on ubuntu https://github.com/spinlock/flexsc 35