Just to head off any comments to the effect of "why do you need to know this??": This is just a puzzle I was curious about, not something I need to do for any practical reason.
Given a typical POSIX system[1], how would you design an experiment to determine the scheduling quantum[2] of a CPU-bound process?
[1]: but NOT one that lets you query for this information through a syscall or /proc interface
[2]: "Scheduling quantum" is defined as the amount of time a process will run on the CPU without blocking or yielding before its scheduled time is over and the OS lets a different process run.
I'm not sure how accurate it would be, but this might work:
- Make sure your computer is idle (or as idle as you can make it)
- Spawn off 2N threads (where N is the number of cores in your computer). All of these threads should be set to run at the same priority as each other.
- Each of the threads should be running an infinite loop where it does nothing but repeatedly retrieve the current monotonically-increasing-wallclock time using a high-resolution timer (e.g. calling std::chrono::steady_clock::now() or similar).
- At each iteration of the the loop, each thread should check the resulting time value for "sudden gaps", i.e. where the clock time jumps from (t) to (t+n milliseconds, with n being greater than the usual delta value). Those gaps most likely indicate a time period when the thread got kicked off of the CPU so that another one of the threads could run.
- At some point, compute the average of the sizes of all of those gaps, and that is your estimate of the scheduler's quantum size.
Note that this assumes that your clock's resolution is greater than the scheduler's quantum size; if it's not (e.g. if you trying to use a clock with 10mS resolution to measure a 5mS quantum length), then measuring the quantum length would be difficult AFAICT.
I think you could get the answer through a statistical analysis of enough runs of the following system:
Run one thread per processor that clears a terminate flag, then runs a loop for a fixed number of iterations or until a terminate flag is set, whichever comes first. These threads record whether they terminated due to running all the iterations, or due to the terminate flag being set.
At the same time, run an additional thread that sets the terminate flag.
Do this at a variety of number of iterations in the loop.
If the loop completes within the thread time slice, it will complete all iterations. If it does not complete within the thread time slice, the termination thread will have a chance to interrupt one of the looping threads.
Now, the termination thread will sometimes be scheduled first, and there may also be other threads running that complicate the behavior, so you may need to run this a lot of times on multiprocessor systems and analyze the results statistically. You'll also need to account for things like thread startup time and memory access time, since there will presumably be a memory barrier on each iteration through the loop to check the flag.
With enough repetitions at enough different loop iteration limits, though, this should give you the number of times you can iterate through the loop in one time slice. You can then run a large number of iterations on an unloaded system to get the length of time it takes for each iteration, and then calculate the wall clock time for each time slice.
来源:https://stackoverflow.com/questions/37505887/how-to-experimentally-determine-the-scheduling-quantum-of-a-process-thread