Re: fair clock use in CFS

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

 



* Srivatsa Vaddagiri <[email protected]> wrote:

> 	I have been brooding over how fair clock is computed/used in 
> CFS and thought I would ask the experts to avoid wrong guesses!

hey, thanks for the interest :-)

> As I understand, fair_clock is a monotonously increasing clock which 
> advances at a pace inversely proportional to the load on the runqueue. 
> If load = 1 (task), it will advance at same pace as wall clock, as 
> load increases it advances slower than wall clock.

correct.

> In addition, following calculations depend on fair clock: task's wait 
> time on runqueue and sleep time outside the runqueue (both reflected 
> in p->wait_run_time).

(note that in -v12 only the on-runqueue wait time is used.)

> Few questions that come up are:
> 
> 1. Why can't fair clock be same as wall clock at all times? i.e fair
>    clock progresses at same pace as wall clock independent of the load 
>    on the runqueue.
> 
>    It would still give the ability to measure time spent waiting on 
>    runqueue or sleeping and use that calculated time to give 
>    latency/bandwidth credit?

155 milliseconds spent waiting for CPU time while there are another 10 
tasks contending for the CPU is a different scenario from when there is 
just one task running on the CPU. In the 10-task case a single task 
would only have a 'fair expectation' to run for 15.5 milliseconds, in 
the 1-task case a single task has a 'fair expectation' to run the full 
155 milliseconds. The 'fair clock' measures this capacity of 'effective 
CPU power' in essence.

but let me give you some more CFS design background:

80% of CFS's design can be summed up in a single sentence: CFS basically 
models an "ideal, precise multi-tasking CPU" on real hardware.

"Ideal multi-tasking CPU" is a (non-existent :-) CPU that has 100% 
physical power and which can run each task at precise equal speed, in 
parallel, each at 1/nr_running speed. For example: if there are 2 tasks 
running then it runs each at 50% physical power - totally in parallel.

On real hardware, we can run only a single task at once, so while that 
one task runs the other tasks that are waiting for the CPU are at a 
disadvantage - the current task gets an unfair amount of CPU time. In 
CFS this fairness imbalance is expressed and tracked via the per-task 
p->wait_runtime (nanosec-unit) value. "wait_runtime" is the amount of 
time the task should now run on the CPU for it become completely fair 
and balanced.

( small detail: on 'ideal' hardware, the p->wait_runtime value would
  always be zero - no task would ever get 'out of balance' from the
  'ideal' share of CPU time. )

CFS's task picking logic is based on this p->wait_runtime value and it 
is thus very simple: it always tries to run the task with the largest 
p->wait_runtime value. In other words, CFS tries to run the task with 
the 'gravest need' for more CPU time. So CFS always tries to split up 
CPU time between runnable tasks as close to 'ideal multitasking 
hardware' as possible.

Most of the rest of CFS's design just falls out of this really simple 
concept, with a few add-on embellishments like nice levels, 
multiprocessing and various algorithm variants to recognize sleepers.

In practice it works like this: the system runs a task a bit, and when 
the task schedules (or a scheduler tick happens) the task's CPU usage is 
'accounted for': the (small) time it just spent using the physical CPU 
is deducted from p->wait_runtime. [minus the 'fair share' it would have 
gotten anyway]. Once p->wait_runtime gets low enough so that another 
task becomes the 'leftmost task' (plus a small amount of 'granularity' 
distance relative to the leftmost task so that we do not over-schedule 
tasks and trash the cache) then the new leftmost task is picked and the 
current task is preempted.

The rq->fair_clock value tracks the 'CPU time a runnable task would have 
fairly gotten, had it been runnable during that time'. So by using 
rq->fair_clock values we can accurately timestamp and measure the 
'expected CPU time' a task should have gotten. All runnable tasks are 
sorted in the rbtree by the "rq->fair_clock - p->wait_runtime" key, and 
CFS picks the 'leftmost' task and sticks to it. As the system progresses 
forwards, newly woken tasks are put into the tree more and more to the 
right - slowly but surely giving a chance for every task to become the 
'leftmost task' and thus get on the CPU within a deterministic amount of 
time.

> 2. Preemption granularity - sysctl_sched_granularity
> 
> 	This seems to be measured in the fair clock scale rather than 
> 	wall clock scale. As a consequence of this, the time taken for a 
> 	task to relinquish to competetion is dependent on number N of 
> 	tasks? For ex: if there a million cpu hungry tasks, then the 
> 	time taken to switch between two tasks is more compared to the 
> 	case where just two cpu hungry tasks are running. Is there any 
> 	advantage of using fair clock scale to detect preemtion points?

yes, there is an advantage. The granularity is really mostly a property 
of the physical CPU and not part of the "precise scheduling" model. 
Granularity expresses the fact that a task has caching affinity to the 
CPU and there is a cost to scheduling in a too finegrained way. This 
granularity value does not depend on the number of tasks running. For 
example the granularity value could be made really small if CPUs had no 
task-switching costs.

( small detail: the granularity value is currently dependent on the nice
  level, making it easier for higher-prio tasks to preempt lower-prio
  tasks. )

( i'd agree in theory with the proposition that the granularity could be
  made a function of load too, but only to model cache/affinity effects,
  _not_ due to the basic model of precise scheduling. )

	Ingo
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux