This seems to be some sort of decaying average algorithm. Wouldn't it be necessary that the number of calls to check_threads per second varies in a somewhat continuous way for it to work? I.e. isn't it possible that the program shifts the working set from one that causes 100 k calls/sec to one that only causes 1 k calls/sec? Then this could produce time slices of several seconds before it readjusts. Sure, it's not important that the time slices are exactly uniform, but that would probably be too erratic.
What about this crude but obvious solution:
static int div_; if(div_++ & 255) return; if (clock() - thread_start_clock < (clock_t) (CLOCKS_PER_SEC / 20)) return;
It would only put a cap on very short time slices. (Ideally one would like to put a cap on long ones too, but I guess there's no real risk that the function gets called as seldom as about 100 times/sec.)
/ Martin Stjernholm, Roxen IS
Previous text:
2002-09-06 00:24: Subject: Frequent context switches
clock() is a system call which takes a small but not insignificant amount of cpu time. The reason for the div_ construction is that check_threads is called a *lot*. Even using up a few cycles in this function creates measurable slowdowns.
My suggestion would be to make the code look something like:
static int divisor; static int context_switches; static float cps=50.0; static float last_time=-1.0;
void check_threads() { static int counter=0; if(counter--) return;
counter=divisor; context_switches++; ... }
And then, in some code which is called more seldom:
float t=float_time(); if(last_time != -1.0) { float s=10.0; /* Average time */ float frac=1.0-1.0/s;
cps=cps * pow(frac,t - last_time) + context_switches/s;
} context_switches=0; last_time=t;
if(cps < 20) divisor -= divisor / 5; if(cps > 100) divisor += divisor / 3;
This way, it will adapt automatically, not use much cpu, and you can fall back to gettimeofday() if you like, because the adaption function is not called as often.
As far as I'm concerned, it doesn't matter if time slices are uniform in length.
/ Fredrik (Naranek) Hubinette (Real Build Master)