From owner-freebsd-arch Wed Oct 31 11:47:55 2001 Delivered-To: freebsd-arch@freebsd.org Received: from devonshire.cnchost.com (devonshire.concentric.net [207.155.248.12]) by hub.freebsd.org (Postfix) with ESMTP id 314AC37B405 for ; Wed, 31 Oct 2001 11:47:48 -0800 (PST) Received: from bitblocks.com (adsl-209-204-185-216.sonic.net [209.204.185.216]) by devonshire.cnchost.com id OAA05182; Wed, 31 Oct 2001 14:47:28 -0500 (EST) [ConcentricHost SMTP Relay 1.14] Message-ID: <200110311947.OAA05182@devonshire.cnchost.com> To: Peter Jeremy Cc: Poul-Henning Kamp , Peter Wemm , arch@FreeBSD.ORG Subject: Re: 64 bit times revisited.. In-reply-to: Your message of "Wed, 31 Oct 2001 16:37:41 +1100." <20011031163741.C85128@gsmx07.alcatel.com.au> Date: Wed, 31 Oct 2001 11:47:28 -0800 From: Bakul Shah Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG > >> >Okay, how about this? Define N types that will be > >> >*exactly* the same on *all* machines: > >> > > >> > time_t 32 bits (1 second resolution, upto yr 2038) > >> > nstime64_t 64 bits (10^-9 second resolution, upto yr 2554) > >> > >> Should be 1/2^32 resolution or you have a math nightmare dividing > >> by 1000000000 all the time. > > > >On my 500Mhz PIII it takes about 4.6ns to divide a 64 bit > >number by a 64 bit 10^9. > > Are you sure? I've just _measured_ it on a PIII-600 and came up with > 211nsec (averaged over 1e7 loops). Keep in mind that this solution > has to also work in embedded applications - which are several orders > of magnitude slower than this. Dang! My number is bogus:-( The best number I get is about 130ns on a 533Mhz PIII. Test source code included below. I am not sure what the bug was in the original code.... But the point remains that this is not a math nighmare or all that expensive even on a slow machine. BTW, strtoll or strtoq don't seem to work for reading long long numbers! > There are two logical timestamp formats for a binary computer: s/logical/convenient/. > 1) Fixed point seconds with M bits to the left of the binary > point and N bits to the right. > 2) Integral number of (fractional second units). (As used on > the IBM System 360 and later). My vote is for 2), where the fractional unit is 10^-9 seconds and I called it `nstime64_t'. I don't like fixed point. You may as well use floating point like long double since most processors these days have very good floating point performance but then it won't make the embedded system folks happy. There have been over 100 messages on this subject in the past few days and rather than respond to individual messages I will summarize my (evolved) view below one more time! Please prefix IMHO to every point! - converting to 64 bit time_t in a piecemeal fashion is not worth it at this point. - The sky is not to falling down until 2038! - Let us use some of that time in coming up with a compromise that works across the board as this problem afflicts almost *all* variants of Unix, including the ones on 64 bit platform. - The issue is *what* that compromise will be and that requires thinking through the implications of changes (as opposed to having some free time to code up a solution). - I am certainly not suggesting waiting till the last moment or even years to fix the problem. - time_t doesn't have to be closely tied to a processor's native integer type -- it just has to be some arithmetic type so arguments about 64 bit time_t on a 64 bit platform (and by implication, 256 bit time_t on 256 bit platform) are weak. - I am advocating a 64 bit type with a nanosecond resolution and 584 years of span as a reasonable compromise type: - a 64 bit time_t with a second resolution is an overkill; it is way more than the expected life of universe! - very few applications require resolution less than 1ns. - 584 years is a long enough time -- we can not even imagine what computers will be like in 100 years. BTW, a signed representation will cut this in half to 292 years, which is still good enough. Note this is just a proposal and I have not thought through all of its implications (for example, on struct tm). It may be that we need a more radical solution such a 128 bit type as PHK & other advocate or a long double or something. - Just moving to a second resolution 64 bit time_t will mean there will be a lot of inertia against doing anything better. - Dealing with standards bodies is a pain but we do heed standards in FreeBSD and sooner or later POSIX will have to face this issue at which point if FreeBSD solution is different we will end up having to replicate a bunch of things. [It may be that POSIX won't be able to agree on anything more that 64 bit time_t but I am not so pessimistic!] - I am comfortable with a parallel set of system/library calls for any new time type if that means old programs don't have to recompiled to read, e.g. old dump tapes or create them for old machines. - The issue of what the kernel uses internally is separate. As long as the kernel's representation can be mapped to time_t (or its descendent) we are fine. - what a filesystem uses for timestamping files is related but I do not see how UFS1 can be made to stretch beyond 2038. As for UFS2 or some other fs, a sufficiently general time type may remove the need for timeval or timespec and there needs to be mapping between a file timestamp and time_t (at least for the limited life of a computer) but why constrain them any more? - It is true that frivolous topics like C style cause long drawn-out arguments but the converse is not true; this is not a `bikeshed' issue. Once again, all in my humble opinion! -- bakul #include #include long long f(long long x, long long y); long long g(long long x, long long y); int main(int argc, char**argv) { long long x = strtoll(a[1], 0, 10); long long y = strtoll(a[2], 0, 10); long long z; unsigned long count = strtoul(a[3], 0, 0); int i; struct timeval t0, t1, t2; double d0, d1, d2; /* make x bigger since we can't read > 32 bit numbers with strtoll */ x *= x; printf("x=%lld, y=%lld, count=%ld\n", x, y, count); gettimeofday(&t0, 0); for (i = 0; i < count; i++) z = f(x, y); gettimeofday(&t1, 0); /* t1 - t0 == overhead time */ for (i = 0; i < count; i++) z = g(x, y); gettimeofday(&t2, 0); /* t2 - t1 == overhead + count divides time */ d0 = t0.tv_sec*1E9 + t0.tv_usec*1E3; d1 = t1.tv_sec*1E9 + t1.tv_usec*1E3; d2 = t2.tv_sec*1E9 + t2.tv_usec*1E3; printf("%g\n", (d2-d1-(d1-d0))/count); exit(0); } long long f(long long x, long long y) { return x; } long long g(long long x, long long y) { return x / y; } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message