On Thu, Feb 02, 2006 at 04:17:56AM -0800, Roman wrote: > I don't think it's filesystem related, i.e. there is not much I/O happening > at the time. Maybe NetBSD's /bin/sh is a lot faster than Solaris > /bin/{sh,ksh,bash}, maybe NetBSD's fork() is a lot faster. I didn't benchmark > the two operating systems. I'm hoping to conduct some benchmarks soon and > will post the results. > > This brings me to another question: newer x86 CPUs have a time stamp counter, > wich can be accessed with rdtsc assembly instruction. I think ultrasparc CPUs > have a similar counter, accessed via %tick register. This is useful in > benchmarks when measuring high resolution timing evens. > > On x86 with GCC I use the following function to take a time stamp: > > uint64_t rdtsc(void) { > /* > ** rdtsc sets register %edx to the high-order 32 bits of the counter > ** and register %eax to the low-order 32 bits. Those values are stored > ** in an array of two 32 bit integers, and returned as a single 64 bit > ** value. > */ > > union { > uint64_t u64ts; > uint32_t u32arr[2]; > } un_rdtsc; > > __asm__ __volatile__ ("rdtsc; movl %%edx,%0; movl %%eax,%1" > : "=r" (un_rdtsc.u32arr[1]), "=r" (un_rdtsc.u32arr[0]) > : /* No input */ > : "%edx", "%eax"); > > return(un_rdtsc.u64ts); > } > > The above function will work with GCC, but I think it will not compile > with SunPro compiler. Does anyone have any suggestions on how I could > convert such a function into portable x86 and sparc assembly code > (using rdtsc for x86 and %tick for sparc)?
Using RDTSC/%tick is fraught with complications. In particular, there is no guarantee that the values will be synchronized between different CPUs in a multi-CPU box. In addition, %tick is a privileged register on SPARC. I'd recommend using gethrtime(3C); it's guaranteed to be in sync, and is in easily processed nanoseconds. If you *MUST* use rdtsc, here's an assembly file for i386 and amd64: % cat Makefile ASFLAGS=-D_ASM % cat rdtsc.S #include <sys/asm_linkage.h> #if defined(__amd64) ENTRY(rdtsc) rdtsc / %edx:%eax = RDTSC shlq $32, %rdx orq %rdx, %rax ret SET_SIZE(rdtsc) #elif defined(__i386) ENTRY(rdtsc) rdtsc / %edx:%eax = RDTSC ret SET_SIZE(rdtsc) #else #error undefined architecture #endif % make rdtsc.o cc -D_ASM -c -o rdtsc.o rdtsc.S % This is derived from: http://cvs.opensolaris.org/source/xref/on/usr/src/uts/intel/ia32/ml/ia32.il#293 http://cvs.opensolaris.org/source/xref/on/usr/src/uts/intel/amd64/ml/amd64.il#286 In addition, the GCC code above seems rather complex; why not just: #include <sys/types.h> uint64_t rdtsc(void) { uint64_t v; __asm__ __volatile__ ("rdtsc" : "=A" (v)); return (v); } Cheers, - jonathan -- Jonathan Adams, Solaris Kernel Development _______________________________________________ perf-discuss mailing list perf-discuss@opensolaris.org