lkml.org 
[lkml]   [1998]   [Sep]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH] Faster scheduler and separate RT run queue
From
Date
Richard Gooch <rgooch@atnf.csiro.au> writes:
> Hi, all. Appended is a patch that does 3 things:
> - maintains a separate run queue for RT processes
> - simplifies the scheduler code path and makes it more robust
> - fixes a bug with sched_yield(2) and RT processes yielding to lower
> priority processes.

And what does it do to the common case? It looks like it makes it
slower... This patch is adding a fair whack of extras..

Summary; This patch removes one test + jump from the common case, and
adds at least 3 others to replace it. Also added numerous extra
variables (initalized), and changes a number of loads from 'load
constant' to 'load indirect offset'.

So it slows the common case while speeding up the case where there are
lots of sched other processes and only 1 or 2 RT process.

Now that makes sense to me.

Michael, off to watch his flying pigs.


> + struct task_struct *run_head; /* The run queue I am destined for */

Bad: Grow task struct by 4 bytes.

> - struct task_struct *next = init_task.next_run;
> + struct task_struct *head = p->run_head;
> + struct task_struct *next = head->next_run;

Extra var, and extra indirect load.


> - p->prev_run = &init_task;
> - init_task.next_run = p;
> + p->prev_run = head;
> + head->next_run = p;

Change from load constant to load indirect.

> + struct task_struct *head = p->run_head;

Extra var, extra indirect load.

> - p->next_run = &init_task;
> - prev = init_task.prev_run;
> - init_task.prev_run = p;
> + p->next_run = head;
> + prev = head->prev_run;
> + head->prev_run = p;

and again.

> + struct task_struct *head = p->run_head;

and again.

> - p->prev_run = &init_task;
> - next = init_task.next_run;
> - init_task.next_run = p;
> + p->prev_run = head;
> + next = head->next_run;
> + head->next_run = p;

and again...

> /*
> - * Realtime process, select the first one on the
> - * runqueue (taking priorities within processes
> - * into account).
> - */
> - if (policy != SCHED_OTHER)
> - return 1000 + p->rt_priority;
> -
> - /*

ahh! A saving. Remove one test and jump.


> - struct task_struct * p = init_task.next_run;
> + struct task_struct * p = rt_idle.next_run;
> + struct task_struct * op = init_task.next_run;

another var, with constant load this time.

> + /* First scan for RT process to run: ignore others */
> + while (p != &rt_idle) {

another test and jump added to common case..

> + p = (next == idle_task) ? op : &init_task;

another test, jump and load added to common case.

> - struct task_struct *p;
> + struct task_struct *p, *head;
> int retval;

This is starting to get silly..

> - if (p->next_run)
> - move_first_runqueue(p);
> + head = (policy == SCHED_OTHER) ? &init_task : &rt_idle;
> + if (p->next_run) {
> + del_from_runqueue(p);
> + p->run_head = head;
> + add_to_runqueue(p);
> + nr_running++;
> + }
> + else p->run_head = head;

Another slowdown on common case....
> - current->policy |= SCHED_YIELD;
> + if (current->policy == SCHED_OTHER)
> + current->policy |= SCHED_YIELD;

and another one!

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:44    [from the cache]
©2003-2011 Jasper Spaans