From owner-freebsd-performance@FreeBSD.ORG Wed Jul 16 14:44:41 2003 Return-Path: Delivered-To: freebsd-performance@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4582C37B401 for ; Wed, 16 Jul 2003 14:44:41 -0700 (PDT) Received: from silver.he.iki.fi (silver.he.iki.fi [193.64.42.241]) by mx1.FreeBSD.org (Postfix) with ESMTP id 249EB43F75 for ; Wed, 16 Jul 2003 14:44:40 -0700 (PDT) (envelope-from pete@he.iki.fi) Received: from PETEX31 (h81.vuokselantie10.fi [193.64.42.129]) by silver.he.iki.fi (8.12.9/8.11.4) with SMTP id h6GLicsL010061; Thu, 17 Jul 2003 00:44:38 +0300 (EEST) (envelope-from pete@he.iki.fi) Message-ID: <071401c34be3$71a03510$812a40c1@PETEX31> From: "Petri Helenius" To: "Jin Guojun [DSD]" , References: <3F15C584.38848DCE@lbl.gov> Date: Thu, 17 Jul 2003 00:44:32 +0300 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1158 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165 Subject: Re: timer counter chip access mystery] X-BeenThere: freebsd-performance@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Performance/tuning List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jul 2003 21:44:41 -0000 This access happens over ISA bus and thus happens at the speed the bus operates at. Use TSC or ACPI for faster gettimeofday. Pete ----- Original Message ----- From: "Jin Guojun [DSD]" To: Sent: Thursday, July 17, 2003 12:37 AM Subject: [Fwd: timer counter chip access mystery] > i386/isa/clock.c, line 1207 > i8254_get_timecount(...) > { > outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); > > low = inb(TIMER_CNTR0); > high = inb(TIMER_CNTR0); > ... > inb(IO_ICU1); > return counter. > } > > This routine takes about 4000 ns. It makes gettimeofday() > cost over 4000 ns. > > measure_i8254_get_timecount: Two_TIMER_CNTR0 2362 ns > measure_i8254_get_timecount: IO_ICU1 936 ns > and outb() looks like to take another 700 ns. > > The Linux uses the same process to get the time counter (see below). > It also comments that this is from Steve McCanne's microtime-i386 for BSD. > However, gettimeofday() under Linux costs 900 ns. > See attached GIF file for a table of comparison. > > Any idea why linux is 4 times faster than FreeBSD in > reading the same time counter chip? > > -Jin > > ----------------- Linux source code for the same routine ----------- > > arch/x86_64/kernel/time.c (line 68) > void do_gettimeofday(struct timeval *tv) > { > unsigned long flags, t; > unsigned int sec, usec; > > read_lock_irqsave(&xtime_lock, flags); > spin_lock(&time_offset_lock); > > sec = xtime.tv_sec; > usec = xtime.tv_usec; > > t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset(); > if (t > timeoffset) timeoffset = t; > usec += timeoffset; > > spin_unlock(&time_offset_lock); > read_unlock_irqrestore(&xtime_lock, flags); > > tv->tv_sec = sec + usec / 1000000; > tv->tv_usec = usec % 1000000; > } > > arch/i386/kernel/time.c (line 127) > > /* This function must be called with interrupts disabled > * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs > * > * However, the pc-audio speaker driver changes the divisor so that > * it gets interrupted rather more often - it loads 64 into the > * counter rather than 11932! This has an adverse impact on > * do_gettimeoffset() -- it stops working! What is also not > * good is that the interval that our timer function gets called > * is no longer 10.0002 ms, but 9.9767 ms. To get around this > * would require using a different timing source. Maybe someone > * could use the RTC - I know that this can interrupt at frequencies > * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix > * it so that at startup, the timer code in sched.c would select > * using either the RTC or the 8253 timer. The decision would be > * based on whether there was any other device around that needed > * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz, > * and then do some jiggery to have a version of do_timer that > * advanced the clock by 1/1024 s. Every time that reached over 1/100 > * of a second, then do all the old code. If the time was kept correct > * then do_gettimeoffset could just return 0 - there is no low order > * divider that can be accessed. > * > * Ideally, you would be able to use the RTC for the speaker driver, > * but it appears that the speaker driver really needs interrupt more > * often than every 120 us or so. > * > * Anyway, this needs more thought.... pjsg (1993-08-28) > * > * If you are really that interested, you should be reading > * comp.protocols.time.ntp! > */ > > static unsigned long do_slow_gettimeoffset(void) > { > int count; > > static int count_p = LATCH; /* for the first call after boot */ > static unsigned long jiffies_p = 0; > > /* > * cache volatile jiffies temporarily; we have IRQs turned off. > */ > unsigned long jiffies_t; > > /* gets recalled with irq locally disabled */ > spin_lock(&i8253_lock); > /* timer count may underflow right here */ > outb_p(0x00, 0x43); /* latch the count ASAP */ > > count = inb_p(0x40); /* read the latched count */ > > jiffies_t = jiffies; > > count |= inb_p(0x40) << 8; > > /* VIA686a test code... reset the latch if count > max + 1 */ > if (count > LATCH) { > outb_p(0x34, 0x43); > outb_p(LATCH & 0xff, 0x40); > outb(LATCH >> 8, 0x40); > count = LATCH - 1; > } > > spin_unlock(&i8253_lock); > ... > return count; > } -------------------------------------------------------------------------------- > _______________________________________________ > freebsd-performance@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-performance > To unsubscribe, send any mail to "freebsd-performance-unsubscribe@freebsd.org" >