[PATCH] Cygwin: Minor updates to load average calculations

Brian Inglis Brian.Inglis@SystematicSW.ab.ca
Thu Oct 10 13:17:35 GMT 2024


On 2024-10-10 00:12, Mark Geisert wrote:
> Hi Brian,
> 
> On 10/9/2024 9:36 AM, Brian Inglis wrote:
>> Clarity suggestions and questions that could perhaps benefit from more comment:
>>
>> On 2024-10-08 23:19, Mark Geisert wrote:
> [...]
>>
>>>     The number of running processes is estimated as (NumberOfProcessors) * (%
>>> -  Processor Time).  The number of runnable processes is estimated as
>>> -  ProcessorQueueLength.
>>> +  Processor Time).  The number of runnable threads is estimated as
>>
>> This looks weird with arbitrary split then indentation; maybe move at least 
>> "(%" to next line, maybe also "*", or the whole expression, and maybe add 
>> semantic newlines after the sentences:
>>
>>  >   The number of running processes is estimated as NumberOfProcessors *
>>  >   % Processor Time.  The number of runnable threads is estimated as
>>
>>  >   The number of running processes is estimated as
>>  >     NumberOfProcessors * % Processor Time.
>>  >   The number of runnable threads is estimated as
>>  >    ProcessorQueueLength / NumberOfProcessors.
>>  >   The instantaneous load ...
> 
> There was a construct like this in an inline comment that I caught, but I missed 
> this in top commentary.  Your suggestion reads much better.
> 
>>> +  (ProcessorQueueLength) / (NumberOfProcessors).  The "instantaneous" load
>>> +  estimate is taken to be the sum of those two numbers.
>>
>> Which two are the values summed: running processes + runnable threads?
> 
> The sum of the (product expression) and the (division expression).  Not exactly 
> what you said, but something related.  I can/will make it clearer.
> 
>>
>>> @@ -62,31 +69,46 @@ static bool load_init (void)
>>   +    Sleep (15); /* let other procs run; multiple yield()s aren't enough */
>>
>> Why so long - why not clock_/nanosleep for just a 16ms tick or even 1ms, as 
>> when system has 1ms multimedia timer ticks enabled by e.g. javascript or ntpd, 
>> or possibly set <1ms by some games? Effects on other processes may vary by 
>> version.
> 
> A good question!  This only happens on load_init(), i.e. the first access of the 
> counters by whatever program has called the getloadavg() syscall.  Right after 
> the counters have been defined there is no data to be read.  Some time in the 
> next 15ms there will be data available, because Windows updates all counters 
> every 15ms.  We don't know in advance when that will be.  We could have a loop 
> checking for data every X ms, but given this code is only run on the first 
> access, just waiting 15ms guarantees data will be available when load_init() 
> returns to its caller.  I can/will add commentary to that effect.

The official rate is 64Hz 15.625ms, but as I said, some programs increase that 
rate, although some are now being more conservative when systems are on battery, 
and limiting that request to ~2x 125Hz 8ms e.g. Chrome.
So you are probably better requesting to Sleep(16/*ms*/) to ensure the minimum 
update interval is exceeded by a small margin; and please document the expected 
time interval units dimensions, as these kinds of functions use various units, 
reasons, and expectations, as the underlying behaviour and its effects seem to 
change every version, especially low values like Sleep(1/*ms*/) which may vary 
from ~2-~15, and documentation lags and may be limited, requiring testing.

For example, IIRC, GetSystemTimePreciseAsFileTime has a resolution of about CPU 
clock/1024, or 1024 rdtsc units, so 3.5GHz -> 3.5MHz, probably to reduce 
variation from CPU clock frequency wander, so you can interpolate very high 
accuracy UTC stamps with bounded error.

> I'll make these changes in a v2 patch.  I'm going to hold off on submitting that 
> until I hear whether the technical content is OK.

LGTM but others have better technical background on internals.

-- 
Take care. Thanks, Brian Inglis              Calgary, Alberta, Canada

La perfection est atteinte                   Perfection is achieved
non pas lorsqu'il n'y a plus rien à ajouter  not when there is no more to add
mais lorsqu'il n'y a plus rien à retirer     but when there is no more to cut
                                 -- Antoine de Saint-Exupéry


More information about the Cygwin-patches mailing list