Date: Mon, 28 Jul 2008 16:47:37 -0400 From: John Baldwin <jhb@FreeBSD.org> To: src-committers@FreeBSD.org Cc: cvs-src@FreeBSD.org, cvs-all@FreeBSD.org Subject: Re: cvs commit: src/sys/kern sched_4bsd.c Message-ID: <200807281647.37400.jhb@freebsd.org> In-Reply-To: <200807282039.m6SKdU1T073711@repoman.freebsd.org> References: <200807282039.m6SKdU1T073711@repoman.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Monday 28 July 2008 04:39:21 pm John Baldwin wrote: > jhb 2008-07-28 20:39:21 UTC > > FreeBSD src repository > > Modified files: > sys/kern sched_4bsd.c > Log: > SVN rev 180937 on 2008-07-28 20:39:21Z by jhb > > When choosing a CPU for a thread in a cpuset, prefer the last CPU that the > thread ran on if there are no other CPUs in the set with a shorter per-CPU > runqueue. I used the test program below. Prior to this change, the two child processes bounced between the two CPUs constantly. With this patch on an otherwise-idle box, they only switched CPUs once after starting. With ULE they switch CPUs occasionally (once every few seconds) but not nearly as bad as 4BSD before this patch (multiple switches per second). Granted, this is a very contrived test. :) Note that I ran this on a 4-CPU box and used CPUs 2 and 3. You can change which CPUs are used by changing the 'cpus[]' array. This is also quite x86 specific. :) #include <sys/param.h> #include <sys/cpuset.h> #include <err.h> #include <stdio.h> #include <unistd.h> #include <machine/cpufunc.h> int apic_ids[2]; int cpus[2] = { 2, 3 }; int apic_id(void) { u_int regs[4]; do_cpuid(1, regs); return (regs[1] >> 24); } void check_id(pid_t pid, int *id) { int new; new = apic_id(); if (*id == new) return; printf("%d: moved from APIC ID %d to APIC ID %d\n", pid, *id, new); *id = new; } void child(void) { int last_id; pid_t pid; int i; pid = getpid(); last_id = apic_id(); printf("%d: starting on APIC ID %d\n", pid, last_id); for (;;) { for (i = 0; i < 10000000; i++) check_id(pid, &last_id); usleep(5); check_id(pid, &last_id); } } int main(int ac, char **av) { cpuset_t set; int i; for (i = 0; i < 2; i++) { CPU_ZERO(&set); CPU_SET(cpus[i], &set); if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(set), &set)) err(1, "cpuset_affinity(%d)", cpus[i]); apic_ids[i] = apic_id(); printf("CPU%d has APIC ID %d\n", cpus[i], apic_ids[i]); } CPU_ZERO(&set); for (i = 0; i < 2; i++) CPU_SET(cpus[i], &set); if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(set), &set)) err(1, "cpuset_affinity"); for (i = 0; i < 2; i++) { switch (fork()) { case -1: err(1, "fork"); case 0: break; default: child(); } } for (i = 0; i < 2; i++) wait(NULL); return (0); } -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807281647.37400.jhb>