4BSD/ULE numbers...

Taku YAMAMOTO taku at tackymt.homeip.net
Thu Sep 29 16:33:17 PDT 2005


Hi all,


I found that slice_min and slice_max in sched_ule.c are calculated
based on hz rather than stathz, which results to a thread hogging
7.5 times more cpu time than the author's intension.

For those who feel sluggish when doing computation-bound things,
I recommend the following tunings with sysctl:

# for RTC based systems...
kern.sched.slice_min=1
kern.sched.slice_max=18

# for APIC based systems driven at hz=1000
# (where stathz = hz * 2 / 15)
kern.sched.slice_min=1   # (hz * 2 / 15) / 100 
kern.sched.slice_max=19  # (hz * 2 / 15) / 7

The attached patch addresses this problem with the bonus of increased
accuracy of tickincr.


On Mon, 26 Sep 2005 13:47:38 -0400
Kris Kennaway <kris at obsecurity.org> wrote:

> On Mon, Sep 26, 2005 at 06:47:27PM +0200, Emanuel Strobl wrote:
> > Hello,
> > 
> > I tried ULE with BETA5 and for me it felt a bit sluggish when making ports.
> > So I did some "realworld" simulation and compared 4BSD/ULE to see what 
> > numbers tell me. And the prooved my feeling right.
> > It seems that ULE is priorizing nice a little higher, but in general the 
> > output of the 4 BSD machine is higher and finishing the tests took not so 
> > long as with ULE, especially the "make configure" differs horribly.
> 
> That's consistent with my testing.  ULE seems a bit more stable now in
> 6.0 (except on my large SMP machines, which reboot spontaneously under
> moderate load), but it doesn't perform as well as 4BSD under real
> application workloads.
> 
> Kris


-- 
-|-__   YAMAMOTO, Taku
 | __ <     <taku at tackymt.homeip.net>

-------------- next part --------------
--- sched_ule.c.orig	Thu Sep 22 10:25:31 2005
+++ sched_ule.c	Thu Sep 22 10:25:31 2005
@@ -69,6 +69,9 @@ SYSCTL_INT(_kern, OID_AUTO, ccpu, CTLFLA
 static void sched_setup(void *dummy);
 SYSINIT(sched_setup, SI_SUB_RUN_QUEUE, SI_ORDER_FIRST, sched_setup, NULL)
 
+static void sched_initticks(void *dummy);
+SYSINIT(sched_initticks, SI_SUB_CLOCKS, SI_ORDER_THIRD, sched_initticks, NULL)
+
 static SYSCTL_NODE(_kern, OID_AUTO, sched, CTLFLAG_RW, 0, "Scheduler");
 
 SYSCTL_STRING(_kern_sched, OID_AUTO, name, CTLFLAG_RD, "ule", 0,
@@ -81,7 +84,7 @@ static int slice_max = 10;
 SYSCTL_INT(_kern_sched, OID_AUTO, slice_max, CTLFLAG_RW, &slice_max, 0, "");
 
 int realstathz;
-int tickincr = 1;
+int tickincr = 1 << 10;
 
 /*
  * The following datastructures are allocated within their parent structure
@@ -921,6 +924,11 @@ sched_setup(void *dummy)
 	int i;
 #endif
 
+	/*
+	 * To avoid divide-by-zero, we set realstathz a dummy value
+	 * in case which sched_clock() called before sched_initticks().
+	 */
+	realstathz = hz;
 	slice_min = (hz/100);	/* 10ms */
 	slice_max = (hz/7);	/* ~140ms */
 
@@ -1011,6 +1019,26 @@ sched_setup(void *dummy)
 	mtx_unlock_spin(&sched_lock);
 }
 
+/* ARGSUSED */
+static void
+sched_initticks(void *dummy)
+{
+	mtx_lock_spin(&sched_lock);
+	realstathz = stathz ? stathz : hz;
+	slice_min = (realstathz/100);	/* 10ms */
+	slice_max = (realstathz/7);	/* ~140ms */
+
+	tickincr = (hz << 10) / realstathz;
+	/*
+	 * XXX This does not work for values of stathz that are much
+	 * larger than hz.
+	 */
+	if (tickincr == 0)
+		tickincr = 1;
+	mtx_unlock_spin(&sched_lock);
+}
+
+
 /*
  * Scale the scheduling priority according to the "interactivity" of this
  * process.
@@ -1492,7 +1520,7 @@ sched_fork_ksegrp(struct thread *td, str
 	child->kg_runtime = kg->kg_runtime;
 	child->kg_user_pri = kg->kg_user_pri;
 	sched_interact_fork(child);
-	kg->kg_runtime += tickincr << 10;
+	kg->kg_runtime += tickincr;
 	sched_interact_update(kg);
 }
 
@@ -1615,22 +1643,6 @@ sched_clock(struct thread *td)
 	if (kseq->ksq_assigned)
 		kseq_assign(kseq);	/* Potentially sets NEEDRESCHED */
 #endif
-	/*
-	 * sched_setup() apparently happens prior to stathz being set.  We
-	 * need to resolve the timers earlier in the boot so we can avoid
-	 * calculating this here.
-	 */
-	if (realstathz == 0) {
-		realstathz = stathz ? stathz : hz;
-		tickincr = hz / realstathz;
-		/*
-		 * XXX This does not work for values of stathz that are much
-		 * larger than hz.
-		 */
-		if (tickincr == 0)
-			tickincr = 1;
-	}
-
 	ke = td->td_kse;
 	kg = ke->ke_ksegrp;
 
@@ -1653,7 +1665,7 @@ sched_clock(struct thread *td)
 	 * We used a tick charge it to the ksegrp so that we can compute our
 	 * interactivity.
 	 */
-	kg->kg_runtime += tickincr << 10;
+	kg->kg_runtime += tickincr;
 	sched_interact_update(kg);
 
 	/*


More information about the freebsd-current mailing list