トップ 最新 追記

Orz日記 by Akio Morita

ToDo:

  • 15 SAD Fit[]回りの障害事例の解析
  • 10 smart pointer版PEGクラスの再実装(Left Recursionまわり)
2006|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|06|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|07|08|09|10|11|12|
2013|01|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|06|07|08|10|12|
2016|01|02|03|05|06|08|10|11|
2017|01|02|03|04|05|06|07|09|10|11|12|
2018|01|02|03|04|06|07|08|09|10|11|12|
2019|01|03|04|05|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|

2016-11-07 [長年日記]

_ [FreeBSD]ULEスケジュラーでのnice値 19

古典的なunixでは、nice値 19のプロセスは、CPU時間割り当ての 優先順位が極めて低く、nice値の低いプロセス群へのCPU時間割り当てが 余った際に実行されていたので、余っているCPU時間を 割り当てたいプロセスに nice値 19を設定するという 運用が行なわれてきた。

FreeBSDでも、4BSDスケジュラーの振る舞いはこれに近かったのだが、 ULEスケジュラーでは、CPU時間を貪欲に消費するプロセスに対する CPU時間割り当ては、nice値 0と nice値 20(最大値)の間でも 大きく偏らないため、fork-waitモデルでnice付きのworker processを 大量に投入する古いタイプの並列演算ロードに対しての CPUスケジューリングの公平性が損なわれている。

下記のパッチで、対話的でないnice付きプロセスの一部を idle queueへ入れてみたのだが、idle queue内のロードバランスが 行なわれないようで、低い優先順位で並列負荷を実行するのには向かない模様。

やはり、timeshare queue内のスケジューリング回りを直さないと無理みたい

Index: sys/kern/sched_ule.c
===================================================================
--- sys/kern/sched_ule.c	(revision 306791)
+++ sys/kern/sched_ule.c	(working copy)
@@ -1537,6 +1537,8 @@
 		KASSERT(pri >= PRI_MIN_INTERACT && pri <= PRI_MAX_INTERACT,
 		    ("sched_priority: invalid interactive priority %d score %d",
 		    pri, score));
+	} else if (td->td_proc->p_nice >= 19) {
+		pri = PRI_MIN_IDLE + (td->td_proc->p_nice - 19);
 	} else {
 		pri = SCHED_PRI_MIN;
 		if (td_get_sched(td)->ts_ticks)

2016-11-08 [長年日記]

_ [FreeBSD]ULEスケジュラーをいじってみる

昨日のパッチで nice付きのバッチプロセスを idle queueへ突っ込むとidle queue内でラウンドロビンしない (timeshare queueじゃ無いからなぁ…)上に、 timeshare queueでプロセッサーが埋まると動かない(idleだからだが)

したがって、fork-waitモデルでnice付き worker processを大量に抱えるモデルだと worker process間の公平性が損なわれる、 他のタスクロードがある場合、worker processが idle queue内でストールし 続ける問題があるので、実用的には無理なので別案を試してみた。

nice値によらず timeshare queueでは定期的(多少、優先度による配給順の 偏りがあるが大きく偏らない)にtime sliceが配られるので、 time slice消費し尽した後に thread rescheduleを要求する sched_clock側に細工をしてみた

具体的には下記のパッチで、配給されるtime sliceの消費速度に nice値で荷重を付けることで、nice付きプロセスへの プロセッサー割り当てを減らすアプローチである

プロセスへのプロセッサ割り当てをnice値によって傾斜配分するという点に 関しては、期待通りで、nice付きでCPU時間を貪り食うプロセスが timeshare queueが埋まっている状況であっても、 nice無しのプロセスに積極的にプロセッサ時間が割り当てられるので、 フォアグラウンドの演算タスクの応答性がかなり改善した

運用上の主な問題は二つある。

一つ目は、thread queueがプロセッサ単位なため、プロセッサ時間の 傾斜配分はプロセッサ毎のthread queue内での分配となるために、 同一のnice値が付いたプロセスであっても、挿入されたthread queueの 混雑状況で、thread queueを跨いだプロセス間のプロセッサ時間の 割り当てが公平とならない点

二つ目は、time ticks毎の処理を変えてるだけなので、time sliceの配給単位と 最小のtime slice単位から決まる比率を越えるバイアスをかけられない点である (実測では、1:9程度の実行比率ぐらいが限界)

本当は、指数関数的な傾斜配分で沈めてるプロセスには 1/100程度のプロセッサ時間割り当てに抑えたいのだが…

実行時間が長く優先度の低い並列worker processを公平に駆動するには、 スケジューリング単位よりも長いスパンでプロセッサ割り当て時間比率を 統計し、スケジューリング集合内での nice値毎の割り当て比率が 所望の比率に収斂するように割り当てるtime sliceを管理する必要がある。 また、プロセッサ毎のthread queue間で実行時間の公平性を担保するために theradを入れ替えも必要となる(CPU affinity的には損になるが)

特に、shared memory経由で worker process間のメッセージパッシングを 行なう系の実装では、worker process間のプロセッサ割り当て時間の 均衡が崩れると性能の劣化につながることが懸念される

Index: sys/kern/sched_ule.c
===================================================================
--- sys/kern/sched_ule.c	(revision 306791)
+++ sys/kern/sched_ule.c	(working copy)
@@ -2286,10 +2286,28 @@
 	 * Force a context switch if the current thread has used up a full
 	 * time slice (default is 100ms).
 	 */
+#if 0
 	if (!TD_IS_IDLETHREAD(td) && ++ts->ts_slice >= tdq_slice(tdq)) {
 		ts->ts_slice = 0;
 		td->td_flags |= TDF_NEEDRESCHED | TDF_SLICEEND;
 	}
+#endif
+	if (!TD_IS_IDLETHREAD(td)) {
+		if (td->td_proc->p_nice > 0 && tdq_slice(tdq) > ts->ts_slice) {
+			const int nice = td->td_proc->p_nice;
+			const int exp1m_nice = (3 * nice * nice + 256) * (3 * nice + 16) - 4096;
+#ifdef SMP
+			ts->ts_slice += imax(0, (exp1m_nice + (sched_random() % 4096)) / 4096);
+#else
+			ts->ts_slice += imax(0, (exp1m_nice                          ) / 4096);
+#endif
+		}
+		if (++ts->ts_slice >= tdq_slice(tdq)) {
+			ts->ts_slice = imax(0, ts->ts_slice - tdq_slice(tdq));
+			td->td_flags |= TDF_NEEDRESCHED | TDF_SLICEEND;
+
+		}
+	}
 }

 u_int

2016-11-12 [長年日記]

_ [雑記][FreeBSD]ASRock Z170M Extreme4 GPE stormその後2

前回の続き

新しいファーム BIOS V7.00をインストールしてみた結果、GPE6F stormが収まりました

_ [Admin]ASRock Z170M Extreme4運用に投入

GPE stormも治ったことだし、サーバーをZ87M Extreme4からZ170M Extreme4へ交代

半導体の世代が進んだおかげで、Core i5-4670SからCore i7-6700への更新と1000BASE-Tx2 NICを10GBASE-Tx2(X550-T2)へ更新しても若干電力が減っている (UPS負荷率で 27%から24%)


カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記