Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Oct 2005 06:15:05 +1000
From:      Peter Jeremy <PeterJeremy@optushome.com.au>
To:        Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc:        current@freebsd.org
Subject:   Re: Timers and timing, was: MySQL Performance 6.0rc1
Message-ID:  <20051028201505.GV39882@cirb503493.alcatel.com.au>
In-Reply-To: <30571.1130493159@critter.freebsd.dk>
References:  <20051028093402.GT39882@cirb503493.alcatel.com.au> <30571.1130493159@critter.freebsd.dk>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 2005-Oct-28 11:52:39 +0200, Poul-Henning Kamp wrote:
>In message <20051028093402.GT39882@cirb503493.alcatel.com.au>, Peter Jeremy wri
>>FreeBSD already supports a variety of different timecounters with
>>different levels of accuracy/performance/guarantees.  One problem is
>>that this is a system-wide knob whereas different applications may
>>have different requirements.
>
>We _really_ don't want different programs using different hardware
>for timecounting, so I hope you're just taking about the various
>levels of quality supported (ie: [get]{bin,nano,micro}[up]time())

I was thinking that if the cost differential is large enough, it might
be worthwhile using different hardware counters (especially for duration
values where you don't have to worry about getting a valid UTC time).
This would probably mean adding a system call to set a default timer
type which is part of the struct proc - upon reflection, there would be
a significant amount of kernel API churn (at least) to get this to work.

To go off on a different tangent, would it be possible to use the NTP
algorithms to synchronize the TSC?  If the TSC's all tick together
(which may be true on i386 but I believe isn't on Alpha) then all you
need is a relative offset, otherwise you need a rate multiplier as
well.  Have one kthread per CPU to manage the local TSC and (ideally)
publish the offset and ratio on a per-CPU magic data page that
everyone is discussing elsewhere in this thread.

This gives something like:
    now = magic->offset + (rdtsc() * magic->multiplier) >> magic->shift;
(though the (x*y)>>z would need to be implemented more carefully to avoid
truncation in the multiplication).

[The SunOS 4.x approach was something like 0xFFFFn000 was the page for
CPU n (or maybe n/2 - I can't remember whether they were 4K or 8K pages)
and 0xFFFFE000 was the page for the CPU you were executing on.]

-- 
Peter Jeremy



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