Kirjautuminen

Haku

Tehtävät

Koodit: C++: NtSetTimerResolution

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

Kirjoita kommentti

Muista lukea kirjoitusohjeet.
Tietoa sivustosta