From: Mike Galbraith <efault@gmx.de>
To: Ingo Molnar <mingo@elte.hu>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Dmitry Adamushko <dmitry.adamushko@gmail.com>,
Linux Kernel <linux-kernel@vger.kernel.org>,
Con Kolivas <kernel@kolivas.org>
Subject: Re: SD scheduler testing hitch
Date: Sat, 07 Apr 2007 19:17:35 +0200 [thread overview]
Message-ID: <1175966255.11408.5.camel@Homer.simpson.net> (raw)
In-Reply-To: <1175962840.10478.49.camel@Homer.simpson.net>
[-- Attachment #1: Type: text/plain, Size: 915 bytes --]
On Sat, 2007-04-07 at 18:20 +0200, Mike Galbraith wrote:
> xx.c
>
> #include <stdio.h>
> #include <sys/time.h>
>
> #define max(a,b) ((a) > (b) ? (a) : (b))
> #define min(a,b) ((a) < (b) ? (a) : (b))
>
> int main(void)
> {
> struct timeval then, now;
> struct timespec t = {0, 1000}, r;
>
> for(;;) {
> int t1, t2;
> short i;
>
> if (gettimeofday(&then, 0))
> break;
> for (i = 1; i > 0; i++);
> if (gettimeofday(&now, 0))
> break;
> t2 = max(then.tv_usec, now.tv_usec);
> t1 = min(then.tv_usec, now.tv_usec);
> if (t2 - t1 >= 1000 && nanosleep(&t, &r))
> break;
> }
> return 0;
> }
I lowered the time to 500us, and ran at nice -10.. it starves tenpercent
here every time. (ran as taskset -c 1 nice -n -10 ./fairtest) The
starving 10% duty cycle task has trouble getting 1% CPU.
-Mike
[-- Attachment #2: fairtest.c --]
[-- Type: text/x-csrc, Size: 4377 bytes --]
// gcc -O2 -o tenp tenp.c -lrt
// code from interbench.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
/*
* Start $forks processes that run for 10% cpu time each. Set this to
* 15 * number of cpus for best effect.
*/
int forks = 1;
unsigned long run_us = 1000000000, sleep_us;
unsigned long loops_per_ms;
void terminal_error(const char *name)
{
fprintf(stderr, "\n");
perror(name);
exit (1);
}
unsigned long long get_nsecs(struct timespec *myts)
{
if (clock_gettime(CLOCK_REALTIME, myts))
terminal_error("clock_gettime");
return (myts->tv_sec * 1000000000 + myts->tv_nsec );
}
void burn_loops(unsigned long loops)
{
unsigned long i;
/*
* We need some magic here to prevent the compiler from optimising
* this loop away. Otherwise trying to emulate a fixed cpu load
* with this loop will not work.
*/
for (i = 0 ; i < loops ; i++)
asm volatile("" : : : "memory");
}
/* Use this many usecs of cpu time */
void burn_usecs(unsigned long usecs)
{
unsigned long ms_loops;
ms_loops = loops_per_ms / 1000 * usecs;
burn_loops(ms_loops);
}
void microsleep(unsigned long long usecs)
{
struct timespec req, rem;
rem.tv_sec = rem.tv_nsec = 0;
req.tv_sec = usecs / 1000000;
req.tv_nsec = (usecs - (req.tv_sec * 1000000)) * 1000;
continue_sleep:
if ((nanosleep(&req, &rem)) == -1) {
if (errno == EINTR) {
if (rem.tv_sec || rem.tv_nsec) {
req.tv_sec = rem.tv_sec;
req.tv_nsec = rem.tv_nsec;
goto continue_sleep;
}
goto out;
}
terminal_error("nanosleep");
}
out:
return;
}
/*
* In an unoptimised loop we try to benchmark how many meaningless loops
* per second we can perform on this hardware to fairly accurately
* reproduce certain percentage cpu usage
*/
void calibrate_loop(void)
{
unsigned long long start_time, loops_per_msec, run_time = 0,
min_run_us = run_us;
unsigned long loops;
struct timespec myts;
int i;
printf("Calibrating loop\n");
loops_per_msec = 1000000;
redo:
/* Calibrate to within 1% accuracy */
while (run_time > 1010000 || run_time < 990000) {
loops = loops_per_msec;
start_time = get_nsecs(&myts);
burn_loops(loops);
run_time = get_nsecs(&myts) - start_time;
loops_per_msec = (1000000 * loops_per_msec / run_time ? :
loops_per_msec);
}
/* Rechecking after a pause increases reproducibility */
microsleep(1);
loops = loops_per_msec;
start_time = get_nsecs(&myts);
burn_loops(loops);
run_time = get_nsecs(&myts) - start_time;
/* Tolerate 5% difference on checking */
if (run_time > 1050000 || run_time < 950000)
goto redo;
loops_per_ms=loops_per_msec;
printf("Calibrating sleep interval\n");
microsleep(1);
/* Find the smallest time interval close to 1ms that we can sleep */
for (i = 0; i < 100; i++) {
start_time=get_nsecs(&myts);
microsleep(1000);
run_time=get_nsecs(&myts)-start_time;
run_time /= 1000;
if (run_time < run_us && run_us > 1000)
run_us = run_time;
}
/* Then set run_us to that duration and sleep_us to 9 x that */
sleep_us = run_us * 9;
printf("Calibrating run interval\n");
microsleep(1);
/* Do a few runs to see what really gets us run_us runtime */
for (i = 0; i < 100; i++) {
start_time=get_nsecs(&myts);
burn_usecs(run_us);
run_time=get_nsecs(&myts)-start_time;
run_time /= 1000;
if (run_time < min_run_us && run_time > run_us)
min_run_us = run_time;
}
if (min_run_us < run_us)
run_us = run_us * run_us / min_run_us;
printf("Each fork will run for %lu usecs and sleep for %lu usecs\n",
run_us, sleep_us);
}
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) < (b) ? (a) : (b))
void steal(void)
{
struct timeval then, now;
struct timespec t = {0, 500}, r;
for(;;) {
int t1, t2;
short i;
if (gettimeofday(&then, 0))
break;
for (i = 1; i > 0; i++);
if (gettimeofday(&now, 0))
break;
t2 = max(then.tv_usec, now.tv_usec);
t1 = min(then.tv_usec, now.tv_usec);
if (t2 - t1 >= 500 && nanosleep(&t, &r))
break;
}
}
int main(void){
int i, child;
calibrate_loop();
printf("starting %d forks\n", forks);
for(i = 0; i < forks; i++){
if(!(child = fork()))
break;
}
if (child)
steal();
else while(1){
burn_usecs(run_us);
microsleep(sleep_us);
}
return 0;
}
next prev parent reply other threads:[~2007-04-07 17:17 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-04 14:04 [sched] redundant reschedule when set_user_nice() boosts a prio of a task from the "expired" array Dmitry Adamushko
2007-04-04 14:15 ` Ingo Molnar
2007-04-04 15:23 ` Dmitry Adamushko
2007-04-04 20:05 ` [PATCH] " Dmitry Adamushko
2007-04-07 0:03 ` Andrew Morton
2007-04-07 9:16 ` Dmitry Adamushko
2007-04-07 9:24 ` Ingo Molnar
2007-04-07 16:20 ` SD scheduler testing hitch Mike Galbraith
2007-04-07 17:17 ` Mike Galbraith [this message]
2007-04-08 8:02 ` Mike Galbraith
2007-04-09 0:14 ` Dmitry Adamushko
2007-04-09 0:23 ` Dmitry Adamushko
2007-04-09 5:54 ` Mike Galbraith
2007-04-07 9:19 ` [PATCH] [sched] redundant reschedule when set_user_nice() boosts a prio of a task from the "expired" array Ingo Molnar
2007-04-08 18:34 SD scheduler testing hitch Al Boldi
2007-04-09 6:23 ` Mike Galbraith
2007-04-09 9:20 ` Dmitry Adamushko
2007-04-09 9:57 ` Mike Galbraith
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1175966255.11408.5.camel@Homer.simpson.net \
--to=efault@gmx.de \
--cc=akpm@linux-foundation.org \
--cc=dmitry.adamushko@gmail.com \
--cc=kernel@kolivas.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome