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