Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern When balancing threads over multiple CPUs, use fixp...



details:   https://anonhg.NetBSD.org/src/rev/d75381960dd2
branches:  trunk
changeset: 349764:d75381960dd2
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Thu Dec 22 14:11:58 2016 +0000

description:
When balancing threads over multiple CPUs, use fixpoint arithmetic
for averages. Otherwise the decisions can be heavily biased by rounding
errors.

Add sysctl kern.sched_average_weight to change the weight of
historical data, the default is 50%.

diffstat:

 sys/kern/kern_runq.c |  30 +++++++++++++++++++++++++-----
 1 files changed, 25 insertions(+), 5 deletions(-)

diffs (86 lines):

diff -r 66d21cac4cd1 -r d75381960dd2 sys/kern/kern_runq.c
--- a/sys/kern/kern_runq.c      Thu Dec 22 13:42:14 2016 +0000
+++ b/sys/kern/kern_runq.c      Thu Dec 22 14:11:58 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_runq.c,v 1.45 2016/07/07 06:55:43 msaitoh Exp $   */
+/*     $NetBSD: kern_runq.c,v 1.46 2016/12/22 14:11:58 mlelstv Exp $   */
 
 /*
  * Copyright (c) 2007, 2008 Mindaugas Rasiukevicius <rmind at NetBSD org>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.45 2016/07/07 06:55:43 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.46 2016/12/22 14:11:58 mlelstv Exp $");
 
 #include "opt_dtrace.h"
 
@@ -80,7 +80,7 @@
        uint32_t        r_bitmap[PRI_COUNT >> BITMAP_SHIFT];
        /* Counters */
        u_int           r_count;        /* Count of the threads */
-       u_int           r_avgcount;     /* Average count of threads */
+       u_int           r_avgcount;     /* Average count of threads (* 256) */
        u_int           r_mcount;       /* Count of migratable threads */
        /* Runqueues */
        queue_t         r_rt_queue[PRI_RT_COUNT];
@@ -118,6 +118,7 @@
 static u_int   cacheht_time;           /* Cache hotness time */
 static u_int   min_catch;              /* Minimal LWP count for catching */
 static u_int   balance_period;         /* Balance period */
+static u_int   average_weight;         /* Weight old thread count average */
 static struct cpu_info *worker_ci;     /* Victim CPU */
 #ifdef MULTIPROCESSOR
 static struct callout balance_ch;      /* Callout of balancer */
@@ -138,6 +139,8 @@
 
        /* Minimal count of LWPs for catching */
        min_catch = 1;
+       /* Weight of historical average */
+       average_weight = 50;                    /*   0.5   */
 
        /* Initialize balancing callout and run it */
 #ifdef MULTIPROCESSOR
@@ -525,6 +528,10 @@
        runqueue_t *ci_rq;
        CPU_INFO_ITERATOR cii;
        u_int highest;
+       u_int weight;
+
+       /* sanitize sysctl value */
+       weight = MIN(average_weight, 100);
 
        hci = curcpu();
        highest = 0;
@@ -533,8 +540,15 @@
        for (CPU_INFO_FOREACH(cii, ci)) {
                ci_rq = ci->ci_schedstate.spc_sched_info;
 
-               /* Average count of the threads */
-               ci_rq->r_avgcount = (ci_rq->r_avgcount + ci_rq->r_mcount) >> 1;
+               /*
+                * Average count of the threads
+                *
+                * The average is computed as a fixpoint number with
+                * 8 fractional bits.
+                */
+               ci_rq->r_avgcount = (
+                       weight * ci_rq->r_avgcount + (100 - weight) * 256 * ci_rq->r_mcount
+                       ) / 100;
 
                /* Look for CPU with the highest average */
                if (ci_rq->r_avgcount > highest) {
@@ -840,6 +854,12 @@
                CTL_CREATE, CTL_EOL);
        sysctl_createv(clog, 0, &node, NULL,
                CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+               CTLTYPE_INT, "average_weight",
+               SYSCTL_DESCR("Thread count averaging weight (in percent)"),
+               NULL, 0, &average_weight, 0,
+               CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, &node, NULL,
+               CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
                CTLTYPE_INT, "min_catch",
                SYSCTL_DESCR("Minimal count of threads for catching"),
                NULL, 0, &min_catch, 0,



Home | Main Index | Thread Index | Old Index