top first execution inaccurate CPU usage

I am putting together a cron job script that will pull top information and format it into a log that I can pull into Excel for readability (one row per execution - run every 10 minutes outputting to a log file). I am using the command
sh:
top -nPd 1
to generate the lines needed to get CPU usage per CPU. My test system is FreeBSD13 (vanilla install) in VirtualBox on Windows 10.

Any time I run one execution of top ("-d 1"), it always shows all CPUs at 99% idle. I am running a shell session that is just counting up in a variable from 0 to a billion. That should show CPU usage. If I run more than 1 execution of top, all executions after the initial execution show significant CPU usage. So, my one pass at top gives inaccurate CPU usage, but is accurate after that. Is this a config/caching issue? How can I get a single pass at top to give accurate CPU usage?

Here is one execution with just the first few processes shown - see WCPU on the process, yet CPU shows idle:
chris@FreeBSD13:~ $ top -nPd 1
top -nPd 1
last pid: 1763; load averages: 0.90, 0.58, 0.45 up 0+07:59:55 16:18:45
28 processes: 2 running, 26 sleeping
CPU 0: 0.2% user, 0.0% nice, 0.3% system, 0.1% interrupt, 99.3% idle
CPU 1: 0.3% user, 0.0% nice, 0.3% system, 0.1% interrupt, 99.3% idle
CPU 2: 0.2% user, 0.0% nice, 0.4% system, 0.1% interrupt, 99.3% idle
Mem: 8704K Active, 31M Inact, 117M Wired, 3775M Free
ARC: 29M Total, 8078K MFU, 19M MRU, 242K Header, 1433K Other
14M Compressed, 42M Uncompressed, 2.98:1 Ratio
Swap: 2048M Total, 2048M Free

PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
1421 chris 1 101 0 13M 3364K CPU0 0 11:04 100.00% sh
494 root 1 20 0 11M 1564K select 0 0:14 0.00% devd
691 root 1 20 0 13M 2764K select 2 0:07 0.00% syslogd

Now see 2 executions - note that the same process is still running with high cpu usage. First pass shows CPU idle, subsequent executions show real usage:
chris@FreeBSD13:~ $ top -nPd 2
top -nPd 2
last pid: 1764; load averages: 0.90, 0.58, 0.45 up 0+07:59:58 16:18:48
28 processes: 2 running, 26 sleeping
CPU 0: 0.2% user, 0.0% nice, 0.3% system, 0.1% interrupt, 99.3% idle
CPU 1: 0.3% user, 0.0% nice, 0.3% system, 0.1% interrupt, 99.3% idle
CPU 2: 0.2% user, 0.0% nice, 0.4% system, 0.1% interrupt, 99.3% idle
Mem: 8768K Active, 31M Inact, 117M Wired, 3775M Free
ARC: 29M Total, 8078K MFU, 19M MRU, 242K Header, 1433K Other
14M Compressed, 42M Uncompressed, 2.98:1 Ratio
Swap: 2048M Total, 2048M Free

PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
1421 chris 1 102 0 13M 3364K RUN 2 11:10 100.00% sh
494 root 1 20 0 11M 1564K select 2 0:14 0.00% devd
691 root 1 20 0 13M 2764K select 1 0:07 0.00% syslogd
1350 chris 1 20 0 21M 9984K select 1 0:03 0.00% sshd
<snip>

last pid: 1764; load averages: 1.07, 0.62, 0.47 up 0+08:00:01 16:18:51
28 processes: 2 running, 26 sleeping
CPU 0: 0.0% user, 0.0% nice, 0.4% system, 0.0% interrupt, 99.6% idle
CPU 1: 33.9% user, 0.0% nice, 1.2% system, 0.0% interrupt, 65.0% idle
CPU 2: 66.1% user, 0.0% nice, 0.0% system, 0.4% interrupt, 33.5% idle
Mem: 9012K Active, 31M Inact, 117M Wired, 3775M Free
ARC: 29M Total, 8078K MFU, 19M MRU, 242K Header, 1433K Other
14M Compressed, 42M Uncompressed, 2.98:1 Ratio
Swap: 2048M Total, 2048M Free

PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
1421 chris 1 102 0 13M 3364K CPU0 0 11:14 203.36% sh
1764 chris 1 20 0 14M 3624K CPU1 1 0:00 0.30% top
1350 chris 1 20 0 21M 9984K select 1 0:03 0.19% sshd
494 root 1 20 0 11M 1564K select 0 0:14 0.03% devd
691 root 1 20 0 13M 2764K select 2 0:07 0.01% syslogd


 
top(1)
Code:
-d count
         Note that for count = 1 no information is available
        about the percentage of time spent by the CPU in every state.
Thanks, Charlie - I saw that a few hours after posting . Since I am new to the forum, I was not able to reply/modify or remove my post. (it was not posted until later)
 
top(1) is not an accurate tool, check the BUGS section in the man page.
I checked the bugs section of man and only saw 2 things - one about swapped processes command names and one that warns that things can change while top is collecting info. I already expect that things can change in the fractions of of a second that it takes to collect system, memory, cpu, disk, and process information. So for general use, it seems to be accurate enough to get a sense of how the system is doing from a memory and CPU usage stand point. Are there other bugs you are referring to that I do not see in this man page?

BUGS
The command name for swapped processes should be tracked down, but this
would make the program run slower.

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.

FreeBSD 13.2-RELEASE November 18, 2021 FreeBSD 13.2-RELEASE
 
So, I decided to take the approach of running top twice so that i got the more accurate information from the second display (-d 2). I was able to pass the information through two sed commands to get the information I needed from the second display of information. All I needed was the info at the top of a top display, not the process info. For those curious, here is that I used:
sh:
top -qPd 2 | sed -e '1,/^Swap/d' -e '/^Swap/q' | sed -e '1,/^$/d'
I then take that output and process it (just under 40 lines of shell code and only passing the output of the above through piped processes) down to a single line in a format that excel can open. Final output is like this (date time, uptime, processes summary, cpu count, each cpu usage, memory summary, swap summary, ARC summary):
"20231231 13:05:52","0+00:17:55","33 processes: 2 running, 31 sleeping","3","96.5% idle","0.4% idle","96.5% idle","21M Active, 19M Inact, 116M Wired, 3777M Free","2048M Total, 2048M Free","29M Total, 8178K MFU, 20M MRU, 243K Header, 1282K Other 14M Compressed, 43M Uncompressed, 3.02:1 Ratio"
That is output of top on FreeBSD13 running on 3 CPU, 4GB RAM, zfs with a CPU load of a single script doing mindless addition.
Part of the requirements are that the system needs to be vanilla - not even allowed to install htop. So, get system CPU and memory load/health using basic tools. This can be cronned to run periodically and collect in a log file that can be simply opened in excel for readability and further analysis.

Thoughts?
 
If output is the only issue, awk can be used.
top -nPd 2|awk 'BEGIN {getline} /^last\ pid/ {do print; while(getline)}'
 
If output is the only issue, awk can be used.
top -nPd 2|awk 'BEGIN {getline} /^last\ pid/ {do print; while(getline)}'
That is close, but i don't want the process lines. If you run top with the sed commands I have, you can see the desired outcome. I don't have an issue figuring out how to parse the text, just needed to get past the first display of bad CPU info from top.
 
Back
Top