Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Jan 2002 07:26:00 +1100
From:      Peter Jeremy <peter.jeremy@alcatel.com.au>
To:        Thomas Hurst <tom.hurst@clara.net>
Cc:        arch@FreeBSD.ORG
Subject:   Re: 64 bit counters again
Message-ID:  <20020116072600.A72142@gsmx07.alcatel.com.au>
In-Reply-To: <20020114201018.GA64041@voi.aagh.net>; from tom.hurst@clara.net on Mon, Jan 14, 2002 at 08:10:18PM %2B0000
References:  <Pine.BSF.4.41.0201132057560.62182-100000@prg.traveller.cz> <3C41F3FD.4ECC8CD@mindspring.com> <20020113231459.GA30349@voi.aagh.net> <3C42390A.F9E9F533@mindspring.com> <3C42E899.CB21BD0A@FreeBSD.org> <3C431EE5.1CFF557B@mindspring.com> <20020114201018.GA64041@voi.aagh.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Jan 14, 2002 at 08:10:18PM +0000, Thomas Hurst wrote:
>I'm just interested in how much bandwidth I'm using, but if the counters
>are going to overflow this easily, they cease being terribly useful,
>unless I'm going to actively count them and watch for overflows in
>userspace.

All this needs is a counter big enough to represent the number of
bits/bytes/whatever transmitted/received/whatever during the sample
period.  It doesn't matter if the absolute counter value overflows
during the sample period (as long as it doesn't overflow more than
once).  [This assumes an unsigned 2's complement representation
with arithmetic overflows ignored - which covers virtually all
current hardware].

For example, the following function will report the average bandwidth
since it was last called:

static ulong	prev_val;
struct {
	ulong	low, high;
}	total_val;

double bytes_per_second()
{
	static timeval	prev_time;
	timeval		cur_time;
	ulong		cur_val;
	double		bps;

	cur_val = read_counter();
	gettimeofday(&cur_time, NULL);
	bps = (double)(cur_val - prev_val) /
	      (cur_time.tv_sec - prev_time.tv_sec +
		(cur_time.tv_usec - prev_time.tv_usec) / 1e6);
#ifdef CALCULATE_TOTAL_VALUE
	total_val.low = cur_val;
	if (cur_val < prev_val)
		total_val.high++;
#endif
	prev_time = cur_time;
	prev_val = cur_val;
	return (bps);
}

The optional code inside CALCULATE_TOTAL_VALUE will give you an accurate
total units count with an extended range as long as the sample rate is
high enough.

>I'm not really bothered if they're totally accurate, since they're just
>a guide - how about a float that counts kb? ;)

Two major downsides:
1) The FreeBSD kernel (as well as most other Un*x kernels) avoid the use
   of FP for various reasons.  The use of FP within interrupt handlers
   would seriously affect interrupt latency - by a factor or two or more.
2) FP trades accuracy for range.  After a while your counters will lose
   more and more precision and eventually stop counting at all:
   33554432.0f + 1.0f == 33554432.0f

Peter

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020116072600.A72142>