This is the mail archive of the cygwin@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

We can get down to 30us resolution!


Hi

Thanks to Tim,  I have found the solution. On Windows NT and Windows 95 we
can use QueryPerformanceCounter and QueryPerformanceFrequency. Although it
is non-portable, it IS a way of getting better resolution time performance
on a Windows PC.

Adapted from http://www.amd-embedded.com/ackerman.htm

#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 
#include <windows.h> 
#include <string.h> 
#include <memory.h> 
#include <process.h> 
#include <tchar.h>
#include <time.h>
#include <dos.h>
#include <conio.h>
#define ITERATIONS  10
/* Special globals for NT performance timers */
double freq;
long start;
/* Initialize everything to 0 */
void sec_init(void)
{
	LARGE_INTEGER lFreq, lCnt;
	QueryPerformanceFrequency(&lFreq);
	freq = (double)lFreq.LowPart;
	QueryPerformanceCounter(&lCnt);
	start = lCnt.LowPart;
}
/* return number of seconds since sec_init was called with
** a gross amount of detail
*/
double sec(void)
{
	LARGE_INTEGER lCnt;
	long tcnt;
	QueryPerformanceCounter(&lCnt);
 	tcnt = lCnt.LowPart - start;
 	return ((double)tcnt) / freq;
}
/* End of NT special stuff */	

int main()
{
	unsigned long i;
	double start_time , stop_time;
	double benchtime;


	/* initialization of timers, record start time, empty loop
calibration (if necessary) */
	sec_init();
	start_time = sec();

	/* perform the timed computation */
	for (i = 0; i < ITERATIONS; ++i)
	{
		//	Sleep(1000);	 // Sleep for 1000 ms
		stop_time = sec(); 
		benchtime = (stop_time - start_time);
        printf("%lf \n", benchtime );
	}
	/* calculate stop time and print results */

	printf("Special high resolution Windows NT counters used.\n");
	printf("Elapsed time, seconds: %f\n", benchtime);
	printf("Seconds per iteration: %f\n", benchtime/ITERATIONS);
	printf("Iterations per second: %f\n", ITERATIONS/benchtime);
	exit(0);
}

After compiling using Visual C++ on a Pentium ??? I got

D:\src\DEBUG>nttime2
0.000005
0.000298
0.000453
0.001508
0.013916
0.014093
0.014978
0.016131
0.017343
0.018565
Special high resolution Windows NT counters used.
Elapsed time, seconds: 0.018565
Seconds per iteration: 0.001857
Iterations per second: 538.633983

D:\src\DEBUG>

Sorry, I haven't tried Cygwin. Doh!

Homer Wong
Telstra
Australia.
> -----Original Message-----
> From:	Tim Prince [SMTP:tprince@computer.org]
> Sent:	Thursday, 23 March 2000 2:04 am
> To:	Wong, Homer; cygwin@sourceware.cygnus.com
> Cc:	Wong, Homer
> Subject:	Re: Can Cygwin's gettimeofday() count to 30us resolution
> instead of 1 0ms?
> 
> I got similar results here, with egcs-20000320 running on a more recent
> cygwin on W2K RC2.
> Shuttle HOT-637/P with Award BIOS v4.51PG (a relative oldster).
> While this resolution is typical of NT style configurations, I had an HP
> Kayak XW on my
> last job, which had 1.000 second resolution in linux as well as windoze.
> As
> even the code
> you refer to shows, the linux libraries must adjust to what is provided by
> the machine.
> 
>  Besides, if you really got down to it, on the Kayak,
> timings were extremely erratic at the sub-second level.  One of the
> Canadian academic types informed me that the BIOS was using thermal
> throttling, regulating
> the clock speed (as well as the fan speed) according to temperature.  If
> not, the clock
> speed was sagging each time the coal was poured to the fan.  So you really
> can't count
> on much.
> 
> If you want to experiment, you can download the cygwin source code as
> well.
> All that is
> likely to get you is a verification of which Windows API calls are in use.
> Or, you could
> just ignore newlib and try running the linux timer code of your choice.
> 
>   I generally time
> code sequences by replacing clock() or cpu_time() with a version based on
> QueryPerformanceCounter which has a resolution better than 10 microseconds
> on
> most machines.  This is the way we had to do cpu_time() for W9x anyway.
> It
> seems that you can get better resolution by dropping the effort to refer
> to
> a
> real clock time datum, even though your linux code appears to be using
> what
> are likely to be the same hardware calls to interpolate sub-second
> intervals.
> 
> Maybe we can get a real expert to explain this stuff, but it makes sense
> to
> me
> for cygwin to use API calls for timing rather than attempt direct hardware
> access.  That doesn't stop you from bypassing the API when you choose,
> as long as you document it as a potentially less portable hack.
> 
> ----- Original Message -----
> From: "Wong, Homer" <Homer.Wong@team.telstra.com>
> >
> > Can Cygwin's gettimeofday() measure down to Linux's 30us (microsecond)
> timer
> > resolution instead of Windows' 10 ms (millisecond) timer resolution? I
> used
> > the following program to test gettimeofday():
> >
> > When I compiled it using Cygwin B20.1 on a Pentium II ??? Windows NT
> box,
> > the (annotated) output was:
> >
> > 217722273000.000000 (repeated ??? times)
> > 217722283000.000000 (repeated 287 times)
> > 217722293000.000000 (repeated 287 times)
> > 217722303000.000000 (repeated 287 times)
> > 217722313000.000000 (repeated ??? times)

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]