#ifndef _E6103821_0B93_11d4_B033_00A40080D29C #define _E6103821_0B93_11d4_B033_00A40080D29C #if !defined(__cplusplus) #error C++ compiler required. #endif /*#ifdef cpuid #error cpuid already defined #endif #ifdef rdtsc #error rdtsc already defined #endif #define cpuid __asm __emit 0fh __asm __emit 0a2h #define rdtsc __asm __emit 0fh __asm __emit 031h*/ namespace microtime { unsigned base_; unsigned cycles_start_low_; unsigned cycles_start_high_; unsigned calibrate() { unsigned base,base_extra=0; unsigned cycles_low, cycles_high; __asm { pushad ; CPUID ; RDTSC ; mov cycles_high, edx ; mov cycles_low, eax ; popad ; pushad ; CPUID ; RDTSC ; popad ; pushad ; CPUID ; RDTSC ; mov cycles_high, edx ; mov cycles_low, eax ; popad ; pushad ; CPUID ; RDTSC ; popad ; pushad ; CPUID ; RDTSC ; mov cycles_high, edx ; mov cycles_low, eax ; popad ; pushad ; CPUID ; RDTSC ; sub eax, cycles_low ; mov base_extra, eax ; popad ; pushad ; CPUID ; RDTSC ; mov cycles_high, edx ; mov cycles_low, eax ; popad ; pushad ; CPUID ; RDTSC ; sub eax, cycles_low ; mov base, eax ; popad ; } // End inline assembly // The following provides insurance for the above code, // in the instance the final test causes a miss to the // instruction cache. if (base_extra < base) base = base_extra; base += 1; base_ = base; return base; } inline void start() { __asm { pushad ; CPUID ; RDTSC ; mov cycles_start_high_, edx ; mov cycles_start_low_, eax ; popad ; } } inline void stop(__int64& elapsed_clocks) { unsigned cycles_end_low; unsigned cycles_end_high; __asm { pushad ; CPUID ; RDTSC ; mov cycles_end_high, edx ; mov cycles_end_low, eax ; popad } __int64 cycles_start; __int64 cycles_end; cycles_start = __int64(cycles_start_low_) + (__int64(cycles_start_high_) << 32); cycles_end = __int64(cycles_end_low) + (__int64(cycles_end_high) << 32); elapsed_clocks = cycles_end - cycles_start - base_; } }; #endif