top -d1 behavior
Fernando Apesteguía
fernando.apesteguia at gmail.com
Sun Nov 23 21:57:36 UTC 2014
On Sun, Nov 23, 2014 at 9:07 PM, Allan Jude <allanjude at freebsd.org> wrote:
> On 2014-11-23 14:34, Fernando Apesteguía wrote:
>> On Sun, Nov 23, 2014 at 6:45 PM, David Wolfskill <david at catwhisker.org> wrote:
>>> On Sun, Nov 23, 2014 at 06:11:02PM +0100, Fernando Apesteguía wrote:
>>>> Hi hackers,
>>>>
>>>> While writing a small script for a friend, I run into a peculiar top behavior:
>>>>
>>>> top -d1 shows only one 'iteration' of the information screen, but in
>>>> it, the CPU percentages line is not well formed: there are 5 columns
>>>> with the '%' symbol, but no values are shown. This only happens for
>>>> -d1 and this behavior is deliberately done in the sources (see
>>>> 'dostates' variable).
>>>> ...
>>>> My point is: why are we doing this? If we remove that constraint, top
>>>> would show the values for -d1. I don't know if they would be really
>>>> accurate, but not printing anything doesn't seem a nice behavior
>>>> either (especially when this is not documented in the man page)
>>>> ....
>>>
>>> At the time of the inital display, the program only has access to the
>>> counters (from kern.cp_time) from one instant.
>>>
>>> In order to calculate the relative proportion of CPU time spent in each
>>> of the 5 states, it is necessary to determine the extent to which those
>>> counters changed over an interval.
>>>
>>> If we call the time when the first sample is taken "T0" and the time
>>> when the second sample is takne "T1", we get something like:
>>>
>>> Time user nice sys intr idle
>>> T0 user_0 nice_0 sys_0 intr_0 idle_0
>>> T1 user_1 nice_1 sys_1 intr_1 idle_1
>>>
>>> To determine the relative proportions for the interval from T0:T1, we
>>> first determnine the differences (or deltas):
>>>
>>> user_delta <== user_1 - user_0
>>> nice_delta <== nice_1 - nice_0
>>> sys_delta <== sys_1 - sys_0
>>> intr_delta <== intr_1 - intr_0
>>> idle_delta <== idle_1 - idle_0
>>>
>>> Then sum the deltas:
>>>
>>> Interval_total = user_delta + nice_delta + sys_delta + intr_delta + idle_delta
>>>
>>> Then, for each of user, nice, sys, intr, and idle, the percentage for
>>> the interval is
>>>
>>> 100 * _delta / Interval_total.
>>>
>>> Here's a sample (produced by a little shell script):
>>>
>>> albert(10.1-S)[6] get_sys_info -N 0 -c 2 -w 10 kern.cp_time
>>> time:1416763949 kern.cp_time:20934 0 28872 5664 1027225
>>> time:1416763959 kern.cp_time:20980 0 28933 5674 1029686
>>>
>>> Given those numbers, we have:
>>>
>>> Time user nice sys intr idle
>>> 1416763949 20934 0 28872 5664 1027225
>>> 1416763959 20980 0 28933 5674 1029686
>>>
>>> The differences:
>>> user nice sys intr idle
>>> 46 0 61 10 2461
>>>
>>> The total of the deltas is 46+0+61+10+2461 ==> 2578.
>>>
>>> The percentages:
>>> user nice sys intr idle
>>> 1.78 0.00 2.37 0.39 95.46
>>>
>>>
>>> (System's uptime, in this case, was a little over an hour -- I had just
>>> updated in to stable/10 @r274909.)
>>
>> OK, but if we use -d1, T0 is 0 since cp_time, cp_old and cp_diff are
>> all declared as static, so we should not have any problems with just
>> having one lecture of the kern.cp_time sysctl and doing all the
>> calculation above. Am I right?
>>
>> That's in fact what top in linux (from the procps package) does. They
>> have the CPU_t struct declared as static. top in Linux is able to show
>> CPU statistics for number of iterations == 1 but we are not.
>>
>> Cheers.
>>
>>>
>>> Peace,
>>> david
>>> --
>>> David H. Wolfskill david at catwhisker.org
>>> Taliban: Evil cowards with guns afraid of truth from a 14-year old girl.
>>>
>>> See http://www.catwhisker.org/~david/publickey.gpg for my public key.
>> _______________________________________________
>> freebsd-hackers at freebsd.org mailing list
>> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
>>
>
> You would either need to make top sleep for 1 second and then calculate
Not really. The computation is possible. Do you mean we would need two
readings of cp_time to be _accurate_? We state in the man page
something like this:
"As with ps(1), things can change while top is collecting information
for an update. The picture it gives is only a close approximation to
reality"
And in any case, why 1 second? The default interval between updates is
2 seconds. This can be overridden with -s but the flag is ignored if
-d1 is present so we don't have a way to let the user decide for how
long he/she wants to wait until the result is calculated.
> the delta, or make it calculate the average of each time by taking the
> counter and dividing it by the uptime.
>
> Neither seem like what the user would expect.
Agreed. But this is mostly unexpected (and can lead scripts to fail):
$ top -d1
last pid: 1013; load averages: 0.54, 0.59, 0.43
up 0+00:11:33 22:39:27
37 processes: 2 running, 35 sleeping
CPU: % user, % nice, % system, % interrupt, % idle
Mem: 327M Active, 169M Inact, 98M Wired, 1984K Cache, 76M Buf, 375M Free
Swap: 3615M Total, 3615M Free
What I would suggest is this:
- Change top so it can show results for cpu states even for -d1 _and_
specifically state in the man page that in this case, the result can
be specially inaccurate due to 'cold start' effect.
- If the previous thing doesn't seem reasonable, state in the man page
that the CPU states line is kind of "broken" when -d1 is specified.
Cheers.
>
> --
> Allan Jude
>
More information about the freebsd-hackers
mailing list