Kirjoittaja: Pöytälamppu
Kirjoitettu: 23.01.2008 – 23.01.2008
Tagit: koodi näytille, vinkki
Tämä luokka tarkentaa Sleep-funktiota kutsumalla NtSetTimerResolution-funktiota. Oletusarvoilla Sleep voi olla hyvinkin epätarkka, mikä korostuu, kun odotusaika on lyhyt. Tämä luokka hakee ja asettaa automaattisesti suurimman tarkkuuden ja myös hoitaa vapautuksen. Esimerkkituloste osoittaa tarkkuuden kasvun. Tästä on hyötyä esimerkiksi peleissä, joissa halutaan limittää tarkasti FPS säästäen samalla prosessorin kuormaa.
#include <windows.h> class SleepinTarkentaja { typedef LONG (_stdcall *PtrTyyppi_NtSTR)( IN ULONG DesiredTime, IN BOOLEAN SetResolution, OUT PULONG ActualTime); typedef LONG (_stdcall *PtrTyyppi_NtQueryTimerResolution)( OUT PULONG MinimumResolution, OUT PULONG MaximumResolution, OUT PULONG ActualResolution); HINSTANCE instNtDll; bool onnistui; PtrTyyppi_NtSTR Pointteri; public: SleepinTarkentaja(){ onnistui = false; //Ladataan ntdll.dll instNtDll = LoadLibrary("NTDLL.dll"); if (instNtDll == NULL) return; //Haetaan NtQueryTimerResolution-funktio PtrTyyppi_NtQueryTimerResolution hakuPtr; hakuPtr = (PtrTyyppi_NtQueryTimerResolution)GetProcAddress (instNtDll,"NtQueryTimerResolution"); if (hakuPtr==NULL) return; //Haetaan tarkin resoluutio ULONG SuurinReso,PieninReso, NykyinenReso; hakuPtr(&PieninReso,&SuurinReso,&NykyinenReso); //Haetaan NtSetTimerResolution-funktio Pointteri = (PtrTyyppi_NtSTR)GetProcAddress(instNtDll," NtSetTimerResolution"); if (Pointteri==NULL) return; //Asetetaan tarkin mahdollinen ULONG todellinen = 0; Pointteri(SuurinReso,TRUE,&todellinen); //Onnistuiko? if (todellinen>SuurinReso) return; //Kaikki onnistui onnistui = true; } ~SleepinTarkentaja(){ //Vapautetaan... if (onnistui){ //Palauteaan alkuperäinen tarkkuus ULONG todellinen; Pointteri(NULL,FALSE,&todellinen); } if (instNtDll) { FreeLibrary(instNtDll); } } bool TarkennusOnnistui(){ return onnistui; } };
esimerkkiohjelma
#include <iostream> using namespace std; int main(){ cout << "Testaus:" << endl; { DWORD loppuAika = GetTickCount() + 1000; int Laskuri = 0; while (GetTickCount() < loppuAika){ Sleep(1); Laskuri++; } cout << "Laskuri:" << Laskuri << "\n"; cout << "Sleep(1) kesti keskimäärin " << 1000.0f / Laskuri << "ms" << endl; } { SleepinTarkentaja tr; DWORD loppuAika = GetTickCount() + 1000; int Laskuri = 0; while (GetTickCount() < loppuAika){ Sleep(1); Laskuri++; } cout << "Laskuri:" << Laskuri << "\n"; cout << "Sleep(1) kesti keskimäärin " << 1000.0f / Laskuri << "ms" << endl; } cin.get(); return 0; }
esimerkkituloste
Testaus: Laskuri:64 Sleep(1) kesti keskimäärin 15.625ms Laskuri:494 Sleep(1) kesti keskimäärin 2.02429ms