Вот, можете сами проверить, построить распределение вероятностей... Вроде компилируется.
Код | // main.cpp #include <cstdio> #include <timer.hpp>
class X: public Timer { __int64 tick; double ms_max; int out, count; public: X (); void activate (); ~X (); };
void main () { init_timer (); X a; a.get_ready (); unsigned timer = GetTickCount () + 30 * 1000; while (timer > GetTickCount ()); }
X::X (): Timer (2, 0), tick (0), ms_max (-1.0), out (0), count (0) { tick = exec_rdtsc (); }
X::~X () { printf ("%G%%\n", out / count * 100.0); // Процент «непопаданий» }
void X::activate () { __int64 tick2 = exec_rdtsc (); __int64 delta = tick2 - tick; tick = tick2; double ms = double (delta) / timer_scale; if (ms > delay) { printf ("%G\n", ms); ms_max = ms; ++out; } ++count; }
|
«Нашлепка» для таймера:
Код | // timer.hpp #pragma once
#include <tchar.h> #include <windows.h> #include <mmsystem.h>
void init_timer (); __int64 exec_rdtsc ();
extern __int64 timer_scale;
class Timer { friend void CALLBACK timer_callback (UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR); public: Timer (unsigned delay, unsigned accuracy): handle (NULL), delay (delay), accuracy (accuracy) { }
virtual bool get_ready (); virtual void complete ();
virtual ~Timer () { complete (); }
protected: Timer (const Timer&); Timer& operator = (const Timer&);
virtual void activate () = 0;
MMRESULT handle; unsigned delay, accuracy; };
|
Реализация «нашлепки» для таймера:
Код | // timer.cpp #include <timer.hpp>
const int TIMER_TEST_TIME = 1000; // msec __int64 timer_scale;
__int64 exec_rdtsc () { static __int64 result; _asm { rdtsc // ReaD from Time Stamp Counter mov ebx, offset result mov dword ptr [ebx], eax mov dword ptr [ebx + 4], edx } return result; }
void init_timer () { __int64 start_timer, stop_timer; HANDLE current_process = GetCurrentProcess (); DWORD common_priority = GetPriorityClass (current_process); SetPriorityClass (current_process, REALTIME_PRIORITY_CLASS); DWORD tick_count = GetTickCount (), timer = tick_count + TIMER_TEST_TIME; start_timer = exec_rdtsc (); while (timer > GetTickCount ()); stop_timer = exec_rdtsc (); SetPriorityClass (current_process, common_priority); timer_scale = (stop_timer - start_timer) / TIMER_TEST_TIME; }
void CALLBACK timer_callback (UINT uTimerID, UINT uMsg, DWORD_PTR thread_ptr, DWORD_PTR dw1, DWORD_PTR dw2) { Timer& timer = *cast <Timer*>(thread_ptr); timer.activate (); }
bool Timer::get_ready () { timeBeginPeriod (accuracy); handle = timeSetEvent (delay, accuracy, timer_callback, cast <DWORD_PTR>(this), TIME_PERIODIC); return handle != NULL; } void Timer::complete () { if (handle != NULL) { timeKillEvent (handle); handle = NULL; timeEndPeriod (accuracy); } }
|
timer > x из командной строки пишет у меня в x следующее:
Цитата | 15.8527 2.96936 2.97209 2.96961 2.96853 2.97072 2.96829 2.96918 2.96884 2.96854 2.96822 2.96965 2.9632 2.96945 2.9695 2.9695 2.96833 2.96683 2.96956
...
2.96898 2.97007 2.96409 2.9694 2.96743 2.27022 2.68064 2.01943 2.96736 2.96892 0%
|
А потом, при желании, это можно запихать в фак. |