QueryPerformanceCounter in C#

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

QueryPerformanceCounter in C#

Beitrag von Niki »

Hallo Leute,

ich muss mir einen kleinen Editor basteln, der sowohl ein 3D Panel als auch viel GUI hat. Ich möchte hier nun gerne C# mit Windows Forms benutzen, weil ich damit ganz einfach schneller eine GUI erzeugen kann. Für die 3D Ausgabe selbst benutze ich SharpDX.

Nun möchte ich gerne QueryPerformanceCounter für das Timing im 3D Panel benutzen. Das bedeutet Thread-Affinität setzen, damit QueryPerformanceCounter immer auf dem selben Prozessor benutzt wird. Nun sind aber Managed Threads nicht das selbe wie OS Threads, und mein Wissen über Managed Code geht nicht soooo tief als das ich mit Sicherheit sagen könnte, dass der foldende Code okay ist. Augenscheinlich funktioniert er, aber dass muss nicht viel heissen. Kann mal jemand der sich damit auskennt einen Blick drauf werfen? :) Bitte auch beachten, dass das Begin-EndThreadAffinity-Paar die MainLoop des Programms einschließt.

EDIT: Ich weiß zum Beispiel nicht, ober der Code zur Folge hätte, dass nun alle Managed Threads plötzlich auf demselben OS Thread laufen. Das wäre von Übel!

Code: Alles auswählen

static class NativeWin32
{
	[DllImport("kernel32.dll")]
	public static extern UIntPtr SetThreadAffinityMask(UIntPtr handle, UIntPtr mask);

	[DllImport("kernel32.dll")]
	public static extern bool GetProcessAffinityMask(IntPtr hProcess, out UIntPtr lpProcessAffinityMask, out UIntPtr lpSystemAffinityMask);

	[DllImport("kernel32.dll")]
	public static extern UIntPtr GetCurrentThread();

	[DllImport("Kernel32.dll")]
	public static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

	[DllImport("Kernel32.dll")]
	public static extern bool QueryPerformanceFrequency(out long lpFrequency);
}

static class Program
{

	/// <summary>
	/// The main entry point for the application.
	/// </summary>
	[STAThread]
	[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlThread)]
	static void Main()
	{
		Application.EnableVisualStyles();
		Application.SetCompatibleTextRenderingDefault(false);

		// Ensure that the following code is always running on the current OS thread.
		Thread.BeginThreadAffinity();

		// Restrict the current OS thread to always run on the same processor.
		UIntPtr proccessAffinityMaskPtr = (UIntPtr)0;
		UIntPtr systemAffinityMaskPtr = (UIntPtr)0;

		if (NativeWin32.GetProcessAffinityMask(Process.GetCurrentProcess().Handle, out proccessAffinityMaskPtr, out systemAffinityMaskPtr))
		{
			ulong proccessAffinityMask = proccessAffinityMaskPtr.ToUInt64();
			if (proccessAffinityMask != 0)
			{
				proccessAffinityMask = (proccessAffinityMask & ((~proccessAffinityMask) + 1));
				NativeWin32.SetThreadAffinityMask(NativeWin32.GetCurrentThread(), (UIntPtr)proccessAffinityMask);
			}
		}
		
		// Create main form
		MainForm mainForm = new MainForm();
		mainForm.Show();

		long qpcLastTime, qpcFrequency;
		NativeWin32.QueryPerformanceFrequency(out qpcFrequency);
		NativeWin32.QueryPerformanceCounter(out qpcLastTime);

		// Main loop
		while (mainForm.Created)
		{
			// Handle application events
			Application.DoEvents();

			// Test code to calculate elapsed seconds
			long qpcCurrentTime;
			NativeWin32.QueryPerformanceCounter(out qpcCurrentTime);

			long elapsedTime = qpcCurrentTime - qpcLastTime;
			if (elapsedTime < 0) elapsedTime = 0;

			qpcLastTime = qpcCurrentTime;

			double elapsedSeconds = (double)elapsedTime / (double)qpcFrequency;

			// Render scene
			mainForm.Render(elapsedSeconds);
		}

		// From here on code may run on any OS thread.
		Thread.EndThreadAffinity();
	}
}
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

http://msdn.microsoft.com/en-us/library ... watch.aspx

Siehe Remarks, das mit der Thread Affinity ist lediglich ein Workaround für verbuggte Mainboards...
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von Krishty »

Zum letzten Mal habe ich von solchen Problemen auf Systemen gehört, die um 2007 produziert wurden. Trotzdem hätte auch ich gern mal eine Quelle, die fundiert begründet, ob man nun darauf aufpassen sollte oder nicht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

Ich hab bis jetzt generell immer nur davon gehört, es aber noch nie mit eigenen Augen gesehen...
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von Blue Cobold »

Wozu eigentlich QueryPerformanceCounter? Ich weiß ja, was man so alles schlechtes über DateTime.Now.Ticks erzählt, aber wahr ist davon ganz selten etwas.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: QueryPerformanceCounter in C#

Beitrag von Artificial Mind »

Blue Cobold hat geschrieben:Wozu eigentlich QueryPerformanceCounter? Ich weiß ja, was man so alles schlechtes über DateTime.Now.Ticks erzählt, aber wahr ist davon ganz selten etwas.
DateTime.Now.Ticks hat Millisekunden Auflösung (genau 1ms), QueryPerformanceCounter hat Microsekunden bis Nanosekunden Auflösung.

Als Beweis:

Code: Alles auswählen

            DateTime start = DateTime.Now;
            while ((DateTime.Now - start).TotalSeconds < 1)
                Console.WriteLine(DateTime.Now.Millisecond + " - " + DateTime.Now.Ticks);
Ticks sind zwar größer, ändern sich aber genau mit den Millisekunden.
Benutzeravatar
Blue Cobold
Beiträge: 58
Registriert: 13.06.2001, 00:00
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von Blue Cobold »

Und Du brauchst mehr Genauigkeit als Millisekunden?
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

Dafür gehöre ich mal wieder geschlagen! Weißt du, ich habe nach "C# game timer" gegoogelt und finde Leute die GetTickCount importierten oder einen Timer Event benutzen. Geht ja überhaupt gar nicht! Auf zwei Seiten fand ich dann auch die Stopwatch. Das waren zwei von diesen Seiten wo du gleich auf den Close Button drauf haust. Und ich war blind genug in der MS Doku die QPC Remarks janz weiten zu übersehen! Danke das du mir das Ding noch mal vor Augen geführt hast :)
Kristhy hat geschrieben:Zum letzten Mal habe ich von solchen Problemen auf Systemen gehört, die um 2007 produziert wurden. Trotzdem hätte auch ich gern mal eine Quelle, die fundiert begründet, ob man nun darauf aufpassen sollte oder nicht.
Ich weiß nicht ob man das als "fundiert" bezeichnen kann, aber MS hält es für nötig uns an mindestens drei Stellen mitzuteilen, dass man die Thread-Affinität setzen soll. Dies findest du in der QPC Doku, in der Stopwatch Doku, und in der DirectX SDK Doku "Game Timing and Multicore Processors". Wahrscheinlich kennst du die Texte schon, aber damit niemand suchen muss...
Microsoft DirectX SDK Documentation June 2010 hat geschrieben: Use QueryPerformanceCounter and QueryPerformanceFrequency instead of RDTSC. These APIs may make use of RDTSC, but might instead make use of a timing devices on the motherboard or some other system services that provide high-quality high-resolution timing information. While RDTSC is much faster than QueryPerformanceCounter, since the latter is an API call, it is an API that can be called several hundred times per frame without any noticeable impact. (Nevertheless, developers should attempt to have their games call QueryPerformanceCounter as little as possible to avoid any performance penalty.)

When computing deltas, the values should be clamped to ensure that any bugs in the timing values do not cause crashes or unstable time-related computations. The clamp range should be from 0 (to prevent negative delta values) to some reasonable value based on your lowest expected framerate. Clamping is likely to be useful in any debugging of your application, but be sure to keep it in mind if doing performance analysis or running the game in some unoptimized mode.

Compute all timing on a single thread. Computation of timing on multiple threads — for example, with each thread associated with a specific processor — greatly reduces performance of multi-core systems.

Set that single thread to remain on a single processor by using the Windows API SetThreadAffinityMask. Typically, this is the main game thread. While QueryPerformanceCounter and QueryPerformanceFrequency typically adjust for multiple processors, bugs in the BIOS or drivers may result in these routines returning different values as the thread moves from one processor to another. So, it's best to keep the thread on a single processor.

All other threads should operate without gathering their own timer data. We do not recommend using a worker thread to compute timing, as this will become a synchronization bottleneck. Instead, worker threads should read timestamps from the main thread, and because the worker threads only read timestamps, there is no need to use critical sections.

Call QueryPerformanceFrequency only once, because the frequency will not change while the system is running.
Zuletzt geändert von Niki am 27.04.2013, 20:21, insgesamt 2-mal geändert.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: QueryPerformanceCounter in C#

Beitrag von Artificial Mind »

Blue Cobold hat geschrieben:Und Du brauchst mehr Genauigkeit als Millisekunden?
Innerhalb meiner Gameloops brauche ich das, ja. Sogar häufig.

Wenn du nur 16ms pro Frame hast und innerhalb eines Frames deine Teilsysteme profilen willst, tust du gut daran, mehr als 1ms Auflösung zu haben ;)

Aber das hängt halt vom Anwendungsfall ab, richtig?
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

Die Auflösung von DateTime.Now liegt allerdings im Bereich von 10ms, auf Multicores wahrscheinlich sogar eher 15ms, passend zum Heartbeat des Systems... ;)

Der Grund für die Thread Affinität ist afaik tatsächlich, dass QueryPerformanceCounter auf manchen Systemen angeblich ein Fallback auf rdtsc macht. Ich hab so ein System allerdings noch nie gesehen und zu diesem Thema auch noch nie eine wirklich eindeutige Aussage aus vertrauenswürdiger Quelle gefunden; es fällt mir fast schwer, mir vorzustellen, wie alt die Hardware sein muss, damit das nötig würde. Und die Probleme die man dann hat, lassen sich mit Thread Affinity wohl auch nur in sehr begrenztem Umfang beherrschen. Einfach mal aus Prinzip die Thread Affinity setzen ist imo jedenfalls alles andere als die minimalinvasive Lösung und so ziemlich das letzte, was ich tun würde. Ich würd einfach QPC benutzen und die ganze Sache im Hinterkopf behalten, falls es wirklich mal Probleme geben sollte...
Zuletzt geändert von dot am 27.04.2013, 20:26, insgesamt 1-mal geändert.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: QueryPerformanceCounter in C#

Beitrag von Artificial Mind »

dot hat geschrieben:Die Auflösung von DateTime.Now liegt im Bereich von 10ms, auf Multicores wahrscheinlich sogar eher 15ms, passend zum Heartbeat des Systems... ;)
Sorry, das ist falsch ;)

Ich habe weiter oben Code gepostet womit ich das vorhin verifiziert habe. Auf meinem Windows 7 64bit System (6 Core + HT) habe ich eine Auflösung von ziemlich Exakt einer Millisekunde (DateTime.Now).
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

Artificial Mind hat geschrieben: Sorry, das ist falsch ;)
Ich habe weiter oben Code gepostet womit ich das vorhin verifiziert habe. Auf meinem Windows 7 64bit System (6 Core + HT) habe ich eine Auflösung von ziemlich Exakt einer Millisekunde (DateTime.Now).
Nicht unbedingt falsch. Ich könnte mir denken, dass das Hardware-abhängig ist.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: QueryPerformanceCounter in C#

Beitrag von Artificial Mind »

Ja, das habe ich mir auch gedacht und meine Specs angedeutet.

Bin mir nicht genau sicher, wann sich das geändert hat, aber zB ctime clock() hat bei meinen Systemen mittlerweile auch meist 1ms Auflösung, was früher definitiv 10ms waren.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

Artificial Mind hat geschrieben:
dot hat geschrieben:Die Auflösung von DateTime.Now liegt im Bereich von 10ms, auf Multicores wahrscheinlich sogar eher 15ms, passend zum Heartbeat des Systems... ;)
Sorry, das ist falsch ;)

Ich habe weiter oben Code gepostet womit ich das vorhin verifiziert habe. Auf meinem Windows 7 64bit System (6 Core + HT) habe ich eine Auflösung von ziemlich Exakt einer Millisekunde (DateTime.Now).
Hm, in der Tat, dann ist die Information in der MSDN dazu wohl nicht ganz richtig, ich mess' auf meinem Windows 8 Laptop hier das gleiche. Dann kommt die FileTime wohl von einem anderen Timer...
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

Ich habe Artificial Mind's Code hier mal laufen lassen:

354 - 635026916183547640
370 - 635026916183703640
573 - 635026916185731643
775 - 635026916187759647
978 - 635026916189787651
181 - 635026916191815654

Habe die Duplikate entfernt, und nur die Unterschiede behalten. Das scheint mir auf meinem Rechner sehr ungenau zu sein. Aber vielleicht lese ich das nur falsch.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

Hast du vielleicht im Hintergrund was laufen, das den PCI Express Bus in irgendeiner Form belastet (Disk Access etc.)?
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

dot hat geschrieben:Hast du vielleicht im Hintergrund was laufen, das den PCI Express Bus in irgendeiner Form belastet (Disk Access etc.)?
Ich habe noch mal alles dicht gemacht, inklusive Virenscanner und Co, aber das Ergebnis ist nicht besser geworden.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

Hm, wär mal interessant inwiefern die Rückgabewerte von DateTime.Now mit der Stopwatch übereinstimmen...
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

dot hat geschrieben:Hm, wär mal interessant inwiefern die Rückgabewerte von DateTime.Now mit der Stopwatch übereinstimmen...
Stopwatch ist hier genau so, allerdings benutze ich das Ding zu ersten Mal und vielleicht falsch.

Code: Alles auswählen

Stopwatch sw = new Stopwatch();
sw.Start();
double start = sw.ElapsedMilliseconds;
while (sw.ElapsedMilliseconds < 1000.0)
{
    double cur = sw.ElapsedMilliseconds;
    Console.WriteLine(cur - start + " - " + cur);
}
sw.Stop();
QPC gibt mit delta-Zeiten kleiner 1*10^(-6) Sekunden, also wesentlich genauer.

Ob das aber alles so messbar ist, das ist fraglich, da ich nicht weiß ob Console.WriteLine das alles komplett verfälscht.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: QueryPerformanceCounter in C#

Beitrag von Artificial Mind »

Also ich kann ca. 20 mal Pro Millisekunde Console.WriteLine ausführen, daher wird keine Verfälschung kommen bei dem Millisekundentest.

Aber echt interessant dass du anscheinend 15ms bekommst, was für ein System hast du denn?

QPC sollte halt die genauste dem System verfügbare Zeit zurückgeben, deswegen ist das Ergebnis soweit zu erwarten, allerdings sollte man da wirklich nicht mehr Console.WriteLine nutzen ;)
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

Ok, mein Stopwatch Code ist voll daneben. Hab's nochmal richtig gemacht, und das Ergebnis ist vergleichbar mit QPC:

Code: Alles auswählen

Stopwatch sw = new Stopwatch();
sw.Start();
long start = sw.ElapsedTicks;
long last = start;
while (sw.ElapsedTicks < Stopwatch.Frequency)
{
    long cur = sw.ElapsedTicks;
    double delta = (double)(cur - last) / (double)Stopwatch.Frequency;
    last = cur;
    Console.WriteLine(String.Format("{0:0.0000000}", delta));
}
sw.Stop();
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von Krishty »

Ich habe den Thread nicht verfolgt, will aber einwerfen, dass die Timer-Auflösung von Windows standardmäßig 15,6 ms beträgt.

Sobald eine Anwendung auf dem System timeBeginPeriod(1) ausgeführt hat (meistens Multimedia-Anwendungen, aber früher auch Flash oder Chrome; Firefox afaik heute noch) ist die Genauigkeit auf 1 ms erhöht. Das bleibt so lange bestehen bis eine Anwendung einen anderen Wert schreibt oder das System neu gestartet wird. Man sollte also nur mit einem frisch neu gestarteten System testen.


Okay; hat sich wohl gerade erledigt.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

Artificial Mind hat geschrieben:Aber echt interessant dass du anscheinend 15ms bekommst, was für ein System hast du denn?
64 Bit Core i7 920 @ 2.67 GHz. Das Motherboard ist glaube ich ein Asus PT6 Deluxe, aber da müsste ich jetzt booten um sicher zu sein. Das Ding ist schon recht alt, aber das ist noch Qualität die nicht tot zu kriegen ist.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: QueryPerformanceCounter in C#

Beitrag von Artificial Mind »

Ok das mit timeBeginPeriod ist echt interessant. Globale Nebeneffekte ftw.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

An timeBeginPeriod() hatte ich auch schon gedacht, das kann man aber ausschließen, da DateTime.Now bei mir 1ms Auflösung besitzt, während der TickCount die gewohnten 15ms zeigt...
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

Mein Code zum Setzen der Thread-Affinität sieht nun wie folgt aus:

Code: Alles auswählen

Thread.BeginThreadAffinity();

Process process = Process.GetCurrentProcess();
ProcessThreadCollection threadCollection = process.Threads;

uint currentThreadId = (uint)NativeWin32.GetCurrentThreadId();
foreach (ProcessThread processThread in threadCollection)
{
    if ((uint)processThread.Id == currentThreadId)
    {
        processThread.IdealProcessor = 0;
        processThread.ProcessorAffinity = (IntPtr)1;
        break;
    }
}

// ... yada yada, blah blah

Thread.EndThreadAffinity();
So soll's nun hoffentlich in Ordnung sein. Bitte beachten, dass ProcessThread.Id keine Managed Thread ID ist. Auch ist der aktuelle ProcessThread in der ProcessThreadCollection i.d.R. nicht an Index 0.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

Wie gesagt, die Geschichte mit der Thread Affinity ist ein ziemlich brutaler Workaround für uralte, verbuggte Hardware und ganz besonders auf modernen Systemen (XP aufwärts, Hardware jünger als 2005) ziemlich sicher hinfällig, da QPC dort in der Regel wohl den HPET verwenden sollte, sofern das System nicht merkwürdig konfiguriert wurde (HPET im BIOS disabled, HAL per Bootoption zu anderem Verhalten gezwungen etc.). Und auch auf älteren Systemen sollte QPC noch eher den APIC verwenden als rdtsc (seit dem Tag, da ich QPC verwende, hab ich noch kein System gesehen, das nicht den APIC oder HPET verwendet). Diese ganzen Geschichten bezüglich der Probleme mit QPC gingen gerade um, als ich vor 10 Jahren angefangen hab und praktisch alle Quellen dazu stammen wohl auch aus dieser Zeit. Heutzutage gehört das wohl alles eher ins Land der Mythen...
Zuletzt geändert von dot am 27.04.2013, 22:11, insgesamt 2-mal geändert.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

Ich tue das nicht hauptsächlich wegen verbuggter Hardware. Was mir wesentlich mehr zu denken gibt ist:
Microsoft DirectX SDK Documentation June 2012 hat geschrieben: Compute all timing on a single thread. Computation of timing on multiple threads — for example, with each thread associated with a specific processor — greatly reduces performance of multi-core systems.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: QueryPerformanceCounter in C#

Beitrag von dot »

Da steht nur, dass du nicht in mehreren Threads gleichzeitig Timer auslesen sollst, was imo auch ziemlich einleuchtend ist. Da steht aber nichts von wegen dass du deinen Timer immer auf dem selben Core auslesen sollst... ;)
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: QueryPerformanceCounter in C#

Beitrag von Niki »

Ich verstehe das anders. Für mich geht es darum auf welchem Prozessor der Thread läuft, und das ist nicht immer derselbe wenn man nichts dagegen tut.
Antworten