Subject: Re: getting cpu utilization
To: Steven M. Bellovin <smb@cs.columbia.edu>
From: Simon Burge <simonb@NetBSD.org>
List: netbsd-users
Date: 01/12/2007 12:58:41
"Steven M. Bellovin" wrote:

> On Thu, 11 Jan 2007 20:08:46 -0500
> "George Georgalis" <george@galis.org> wrote:
> 
> > On Thu, Jan 11, 2007 at 06:46:30PM -0600, Jeremy C. Reed wrote:
> > >> I'm using a /bin/sh function to generate a the cpu utilization 
> > >> 
> > >> util () { # CPU Utilization
> > >>  idle=$(echo "2 k $(top -b -d2 | grep '^CPU states' | awk '{print
> > >> $11}' | sed 's/%//') 1 + p" | dc) echo "2 k 1 $idle / p"  | dc ;}
> > >> 
> > >> That returns the inverse of the cpu idle % found in top.  I add
> > >> 1 to the value before I invert it to prevent divide by zero, so
> > >> output is pretty much between 0 and 1.
> > >> 
> > >> Running two top reports seems a pretty inefficient way to get the
> > >> value.  I think I can tune top a bit, but is there a more direct
> > >> way to get the measurement?
> > >
> > >Maybe "sysctl kern.cp_time" ?
> > 
> > hey that looks pretty good, but I cannot find any doc on it
> > sysctl(8) mentions it; but no detail in (3) 
> > 
> > my best guess to the numbers is the number of 0.01 seconds elapsed
> > per cpu, so idle athlon below increments idle time silghtly over
> > 100 per second, while the idle 8 core opteron increments at a
> > little more than 800 per second.
> > 
> Are you looking on -current?  Details are now in sysctl(7).  Anyway, I
> don't think it's what you want, since it looks to be a cumulative time,
> not the current one status.  You could, of course, take the difference
> between two samples.

This "difference between two samples" of kern.cp_time is exactly how
top(1) gets its numbers.  If you only want a ratio, what the numbers
represent isn't important, but it's the hardware clock rate.  See the
"hz" field in kern.clockrate.  Note that this is not guaranteed to be
100.


This is a bit messy but does roughly what top does:

#!/bin/sh
 
DELAY=1

( sysctl kern.cp_time ; sleep $DELAY ; sysctl kern.cp_time ) | awk '
{ 
	a = $4 + $7 + $10 + $13
	b = $16
 
	if (oldtot == 0) {
		oldcpu = a
		oldtot = a + b
	} else {
		newcpu = a
		newtot = a + b
		print "usage = ", (newcpu - oldcpu) / (newtot - oldtot)
	}
} 
' 

Cheers,
Simon.