// toIntTest.cpp : Defines the entry point for the console application. // #include #include #include #include #undef min #undef max #if defined( WIN32 ) //#define QUERY_PERFORMANCE_COUNTER #define RDTSC #else #define GET_TIME_OF_DAY #endif #ifdef RDTSC #include class perf { __int64 r64; __forceinline __int64 getCurrentTime() { __asm { // // Serialized instruction ensure all previouse // instructions a done befor reading the performance // counter. // // cpuid // // Read the time stamp counter. // rdtsc } } public: __forceinline perf() { ::Sleep( 0 ); __asm cpuid r64 = getCurrentTime(); } __forceinline double elapsed() { __int64 now = getCurrentTime(); return double(now - r64 ); } }; __int64 nCPUFrequency; double dblCPUFrequency; inline __int64 getCurrentTimeI() { __asm { rdtsc } } inline double getCurrentTime() { // return double(getCurrentTimeI()); // // The time stamp counter. // union { __int64 r64; __int32 r32[2]; } tsc; // // Read the time stamp counter. // __asm { // // Serialized instruction ensure all previouse // instructions a done befor reading the performance // counter. // // cpuid // // Read the counter. // rdtsc // // // // mov tsc.r32[0], eax // mov tsc.r32[4], edx movd xmm0,eax movd xmm1,edx pshufd xmm1, xmm0, 0xF7 } // // Get time in seconds. // return double(tsc.r64);// / dblCPUFrequency; } void initGetCurrentTimeLib_hlpr() { // // Use only one fixed CPU // BOOL b; DWORD_PTR proc_affi; DWORD_PTR sys_affi; DWORD_PTR exclud_affi; GetProcessAffinityMask( GetCurrentProcess(), &proc_affi, &sys_affi ); exclud_affi = proc_affi & ~sys_affi; proc_affi = ( exclud_affi ) ? proc_affi : proc_affi; int i = 0; while (( proc_affi >>= 1 )) ++i; proc_affi = 1 << i; b = SetProcessAffinityMask( GetCurrentProcess(), proc_affi ); // // Set the priority of thread high. // b = SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ); b = SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); // // Get the frequency. // nCPUFrequency = 2000000000; // QueryPerformanceFrequency( // reinterpret_cast( &nCPUFrequency ) ); // // Frequency counter supported in CPUs of family x86 // starting from Pentium 4 or Pentium 3. So for old CPUs // this will not work. // // If CPU doesn't support performance counter then just return. // if ( !nCPUFrequency ) puts("WARNING: This CPU doesn't support QueryPerformanceFrequency."); // // Convert to double. // dblCPUFrequency = double(nCPUFrequency); } #endif #ifdef QUERY_PERFORMANCE_COUNTER #include double dblCPUFrequency; inline double getCurrentTime() { // // This call must be quite fast. Since, in x86 architectur // it is one instruction. Yet WIN32 API might added some // additional processing. // // \todo Vahagn: add our assembly optimised function. // __int64 nCPUTickCount; QueryPerformanceCounter( reinterpret_cast( &nCPUTickCount ) ); // // Get time in seconds. // return double(nCPUTickCount) / dblCPUFrequency; } void initGetCurrentTimeLib_hlpr() { // // Use only one fixed CPU // BOOL b; DWORD_PTR proc_affi; DWORD_PTR sys_affi; DWORD_PTR exclud_affi; GetProcessAffinityMask( GetCurrentProcess(), &proc_affi, &sys_affi ); exclud_affi = proc_affi & ~sys_affi; proc_affi = ( exclud_affi ) ? proc_affi : proc_affi; int i = 0; while (( proc_affi >>= 1 )) ++i; proc_affi = 1 << i; b = SetProcessAffinityMask( GetCurrentProcess(), proc_affi ); // // Set the priority of thread high. // b = SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ); b = SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); // // Get the frequency. // __int64 nCPUFrequency; QueryPerformanceFrequency( reinterpret_cast( &nCPUFrequency ) ); // // Frequency counter supported in CPUs of family x86 // starting from Pentium 4 or Pentium 3. So for old CPUs // this will not work. // // If CPU doesn't support performance counter then just return. // if ( !nCPUFrequency ) puts("WARNING: This CPU doesn't support QueryPerformanceFrequency."); // // Convert to double. // dblCPUFrequency = double(nCPUFrequency); } #endif #ifdef GET_TIME_OF_DAY #include inline double getCurrentTime() { timeval t; gettimeofday(&t,0); return (double)t.tv_sec + ((double)t.tv_usec/1000000.0); } void initGetCurrentTimeLib_hlpr() { } #endif void initGetCurrentTimeLib() { initGetCurrentTimeLib_hlpr(); #if 0 for ( int j=0; j < 10000; ++j ) { // // Calculate the time expectation and dispersion // of getCurrentTime on this CPU. // const int nProbeCount = 100000; double dblTimeExpect = 0.; double dblTimeDispersia = 0.; for ( int i = nProbeCount; i; --i ) { register double dblTimeBase = getCurrentTime(); register double dblTimeCurrent = getCurrentTime(); double dblTimeDelta = dblTimeCurrent - dblTimeBase; dblTimeExpect += dblTimeDelta; dblTimeDispersia += dblTimeDelta * dblTimeDelta; } // // finalize. // dblTimeExpect /= double( nProbeCount ); dblTimeDispersia = dblTimeDispersia / double( nProbeCount ) - dblTimeExpect * dblTimeExpect; printf( "Expectation: %f\n" "Dispersion: %f\n", dblTimeExpect, sqrt(dblTimeDispersia) ); puts( "----------------------------------------------------" ); } #endif #if 0 const int nProbeCount = 1000; double* ddd = new double[ nProbeCount ]; double* p = ddd; double m = std::numeric_limits::max(); for ( int i = nProbeCount; i; --i ) { register double dblTimeBase = getCurrentTime(); register double dblTimeCurrent = getCurrentTime(); *p++ = dblTimeCurrent - dblTimeBase; m = std::min( m, dblTimeCurrent - dblTimeBase ); // printf( "%10.1f\n", dblTimeCurrent - dblTimeBase ); } printf( "%10.1f\n", m ); std::ofstream o; o.open( "times.txt" ); p = ddd; for ( int i = nProbeCount; i; --i ) { o << *p++ << std::endl; } o << std::endl; delete [] ddd; #endif #if 1 for ( int j = 0; j < 1000; ++j ) { const int nProbeCount = 10000; double m = 1e300; for ( int i = nProbeCount; i; --i ) { perf pc; __asm cpuid __asm cpuid __asm cpuid __asm cpuid double c = pc.elapsed(); m = min( m, c ); } std::cout << m << std::endl; } #endif }