On Tue, May 08, 2007 at 05:04:31PM +0200, Ingo Molnar wrote:
> thanks Mike - value 0x8 looks pretty good here and doesnt have the 
> artifacts you found. I've done a quick -v11 release with that fixed, 
> available at the usual place:
> 
>     http://people.redhat.com/mingo/cfs-scheduler/
> 
> with no other changes.

Ingo,
        I had a question with respect to the definition of fairness used, esp
for tasks that are not 100% cpu hogs.

Ex: consider two equally important tasks T1 and T2 running on same CPU and 
whose execution nature is:

        T1 = 100% cpu hog
        T2 = 60% cpu hog (run for 600ms, sleep for 400ms)

Over a arbitrary observation period of 10 sec, 

        T1 was ready to run for all 10sec
        T2 was ready to run for 6 sec

Over this observation period, how much execution time should T2 get,
under a "fair" scheduler?

I was expecting both T2 and T1 to get 5 sec (50:50 split). Is this a
wrong expectation of fairness?

Anyway, results of this experiment (using testcase attached) is below.
T2 gets way below its fair share IMO (under both cfs and sd).


2.6.21.1:

 5444 vatsa     16   0  2468  460  388 R   59  0.0   0:19.76 3 T1
 5443 vatsa     25   0  2468  460  388 R   40  0.0   0:15.36 3 T2


2.6.21.1 + cfs-v11:

 5460 vatsa     31   0  2464  460  388 R   70  0.0   0:15.28 3 T1
 5461 vatsa     29   0  2468  460  388 R   30  0.0   0:05.65 3 T2


2.6.21 + sd-0.48:

 5459 vatsa     23   0  2468  460  388 R   70  0.0   0:17.02 3 T1
 5460 vatsa     21   0  2464  460  388 R   30  0.0   0:06.21 3 T2


Note: 

T1 is started as ./cpuhog 600 0 10 > /dev/null &
T2 is started as ./cpuhog 600 400 10 > /dev/null &

First arg = runtime in ms
Second arg = sleeptime in ms
Third arg = Observation period in seconds


-- 
Regards,
vatsa
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>

double loops_per_ms;

double elapsed_time(struct timeval *tv1, struct timeval *tv2)
{
        double d1, d2;
        int elapsed_ms;

        d1 = tv1->tv_sec + tv1->tv_usec * 1e-6;
        d2 = tv2->tv_sec + tv2->tv_usec * 1e-6;
        elapsed_ms = (d2 - d1) * 1000;

        return elapsed_ms;
}

void calibrate_delay(void)
{
        int i;
        double elapsed_ms;
        struct timeval tv1, tv2;

        gettimeofday(&tv1, NULL);
#define LOOP_COUNT 100000000
        for (i=0; i < LOOP_COUNT; ++i)
                ;
        gettimeofday(&tv2, NULL);
        elapsed_ms = elapsed_time(&tv1, &tv2);
        loops_per_ms = LOOP_COUNT / elapsed_ms;

        printf ("loops_per_ms = %f \n", loops_per_ms);
}

int run_length  = 52;   // in milliseconds
int sleep_length = 24;  // in milliseconds
int epoch_time = 5;     // in seconds

main(int argc, char *argv[])
{
        long int i, delay;
        time_t prevtime;
        double prevusage = 0;
        struct rusage stats;

        if (argc > 1) {
                run_length = atoi(argv[1]);
                if (argc > 2)
                        sleep_length = atoi(argv[2]);
                if (argc > 3)
                        epoch_time = atoi(argv[3]);
        }

        calibrate_delay();

        delay = run_length * loops_per_ms;

        printf ("run time = %d ms (%ld loops), sleep time = %d ms,"
                " epoch time = %d s\n", run_length, delay, sleep_length,
                 epoch_time);

        prevtime = time(NULL);
        while (1) {
                time_t curtime, deltatime;
                struct rusage stats;

                for (i = 0; i < delay; ++i)
                        ;
                usleep(sleep_length * 1000);

                curtime = time(NULL);
                deltatime = curtime - prevtime;
                if (deltatime >= epoch_time) {
                        double curusage, deltausage;

                        getrusage(0, &stats);
                        curusage = stats.ru_utime.tv_sec +
                                   stats.ru_utime.tv_usec * 1e-6 +
                                   stats.ru_stime.tv_sec + 
                                   stats.ru_stime.tv_usec * 1e-6;

                        deltausage = curusage - prevusage;
                        printf ("Obtained %3.2f seconds of execution time in"
                              " %d elapsed seconds \n", deltausage, deltatime);
                        prevtime = curtime;
                        prevusage = curusage;
                }
        }
}

Reply via email to