Hi,
Tyler wrote:Brendan wrote:
With dynamically setting the time delay (i.e. using "one-shot" mode), if you want to give a task 700 ns then you can set the timer IRQ to occur 700 ns from now, and if you want to give a task 500 ms you can set the IRQ to occur 500 ms from now. There is no compromise between overhead and accuracy, and the scheduler can be as accurate as the timer itself (i.e. within 838 ns for the PIT, within 40 ns for a local APIC on a 25 MHz front-side bus, and within 1 ns for a local APIC on a 1 GHz front-side bus).
Would this not increase overhead because one must change the PIT settings (I/O overhead) on every call of the scheular?
Yes. For the PIT, if you're sneaky (i.e. if you use the "low byte only" access mode instead of the "low byte the high byte" access mode when setting the new PIT count) it can be done with a single OUT instruction. For my last kernel I didn't do this (it didn't give a wide enough range), so I used 2 OUTs.
If local APIC/s are present then it's much faster, because the local APIC is built into the CPU itself (it's probably faster to access the local APIC timer's count than it is to access RAM).
Tyler wrote:Also this would cause scheduler code to happen without the timer running meaning the program would be running for the entire length of the timer and measuring scheduler overhead would be harder?
For measuring scheduler overhead, use RDTSC or performance monitoring counters (much more accurate anyway).
For old CPUs (80486 or older) it's possible to use a PIT timer count (e.g. setup PIT channel 2 as a continuous count down timer, read the timer count, do what you need to, then read the timer count again and calculate the difference). As long as the time you're measuring is less than 55 ms (or you're using PIT channel 0 and use the IRQ to keep track of overflow) this works, and is accurate to within roughly 838 ns.
For a fixed frequency timer running at 1 MHz (relatively fast), it's likely that it'll be mostly useless for measuring scheduler overhead (unless your scheduler is so broken that it takes more than 1 ms to do it's work).
Combuster wrote:means that the IO overhead equals out when the timeslice equals 4x the minimal slice, with recalibrating taking less time when timeslices get larger. If we include privilege switches in the computation, which favors the first method when tasks switch less often than each interrupt, the equilibrium lies somewhere between 1 and 4 timer interrupts per timeslice. (which is probably processor/mobo dependent)
I don't think the diffences can be calculated so easily. For example, if most tasks don't run for their full time slice you could have 1000 task switches in 10 ms, and if there's only one task that's ready to run (e.g. the system is idle, or doing a long calculation and nothing else) you might have no task switches for 10 minutes.
Then there's keeping track of real time. For a fixed frequency scheduler IRQ you could use the same IRQ for keeping track of real time, while for dynamic scheduler IRQs you can't. This means for fixed frequency you could have N IRQs per CPU per second, while for a dynamic scheduler IRQ you could have N IRQs per second for measuring real time (as only one CPU is needed to keep track real time) plus an average of M IRQs per CPU per second for scheduling. This is "N * CPUs" compared to "N + M * CPUs".
Then there's other performance problems. If a task wants a 1 ms delay, can the scheduler run other tasks during that time or not? If the scheduler's timing isn't accurate enough you'd need to use a busy loop.
What if a task wants an extremely accurate 1 second delay? In this case you can run other tasks until just before the delay expires, and then do a busy loop (using RDTSC) until the delay expires. This should work regardless of how your scheduler is implemented and could give delays that are accurate to within a several CPU cycles - the difference is how much time is spent running other tasks and how much time is spent in the busy loop.
Lastly, in multi-CPU systems it's possible to have a situation where different CPUs are trying to choose which task to run next at the same time. In this case, if there's any re-entrancy locks in the scheduler's code (likely) you end up with CPU/s waiting for another CPU to release the lock (lock contention). Now imagine what happens if (for e.g.) you're using the PIT as a fixed frequency timer and broadcasting the same timer IRQ to all CPUs. In this case all CPUs get the scheduler IRQ at the same time and you're guaranteed to get very heavy lock contention in the scheduler (i.e. "worst case"). A better idea (still using fixed frequency timers) would be to use the local APIC timers and to stagger the timers so that (for e.g.) if there's 2 CPUs and the timers are running at 1 MHz then every 500 us a different CPU gets an IRQ. Of course this is a difficult thing to setup (especially for an arbitrary number of CPUs) but you'd could end up with very little lock contention (i.e. "best case").
For dynamic scheduler IRQs there is no direct relationship between IRQs on different CPUs, so any lock contention caused by IRQs happening at the same time is "self balancing". Basically, the new time delay is determined from when the task switch occurs, and any lock contention would delay when the task switch occurs. For example, imagine you're unlucky and 2 CPUs get a scheduler IRQ at the same time. One gets the re-entrancy lock, chooses a task to run, does a task switch and sets it's timer for 1 ms later. The second CPU waits for the first then gets the lock, chooses a task to run, does a task switch and sets it's timer for 1 ms later. After 1 ms the first CPU gets it's timer IRQ again, but the second CPU's 1 ms isn't up yet. In general (with variable time slices) you end up with "almost best case" - lock contention isn't quite as good as the "best case" above, but it's never as bad as the "worst case" above and there isn't any complicated setup requirements for staggering the timers.
Happy Egghead wrote:@Brandon:
Pity I can only code when the weathers less than 40 degrees. Had 4 blackouts in the last week, only of a few seconds, but it definately helps to save, save, save..... Must invest in a UPS one of these days to iron out the 'bumps'.
Oh for a nuclear power station
!
Just wait until
The Snowy runs dry and the hydro-electric power stations drop off the national grid - ETSA will sell our power at inflated prices to eastern states to make more cash, and shaft us as quick as they can (three cheers for privatisation). Don't tell anyone, but I've been collecting old smoke detectors - I figure it won't take long before I'll be able to refine the small amounts of low grade uranium and build my own personal reactor under my computer desk...
Cheers,
Brendan