AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi exakte Zeitmessungen auf Multiprozessoren
Thema durchsuchen
Ansicht
Themen-Optionen

exakte Zeitmessungen auf Multiprozessoren

Ein Thema von negaH · begonnen am 29. Sep 2006 · letzter Beitrag vom 19. Jul 2011
Antwort Antwort
Seite 2 von 3     12 3      
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.058 Beiträge
 
Delphi XE2 Professional
 
#11

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 30. Sep 2006, 19:49
@Hagen

Zitat:
Sollte QueryPerformanceFrequency() aber wie auf meinem P4 nur ca. 3.6MHz groß sein, die CPU aber mit 1500MHz getaktet werden , so sollte man ca. 3.6 / 1500 * 2 = 4.8 Millisekundewn lang messen. Länger macht keinen Sinn da die maximale Genauigkeit damit schon erreicht wurde.
Hagen,
ja du hast Recht. Habs noch mal geprüft mit SleepTimes von 5 ms um 5 steigend bis 200.
Die Differenzen sind vernachlässigbar.
Da hab ich wohl seinerzeit irgendwie verrannt.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#12

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 30. Sep 2006, 21:42
Die einzigste zeitkritische Operation ist wenn man RDTSC und QueryPerformanceCounter aufruft. Sollte exakt dazwischen ein Taskswitch auftreten haben wir eine Messungenauigkeit. Man könnte das mit einer höheren Threadpriorität versuchen, ist aber im Grunde sinnlos Der Taskswitch könnte ja zu einem ähnlich priorisiertem Task erfolgen, ergo mit höherer Priorität verhindert man nicht den Switch.

Clever ist es einfach vor diesen beiden Aufrufen ein Sleep(0) aufzurufen. Man erzwingt also einen frühzeitgen Taskswitch wenn einer ansteht und nach dem Sleep() ist die Wahrscheinlichkeit enorm hoch das unser Thread erstmal eine minimale Zeitscheibe von ca. 20ms zur Verfügung hat.

In meinem Code verzichte ich also auf Threadprioritäten usw., benutzte nur ein Sleep(0) vor dem Aufruf von RDTSC und QPC, und mache diese Berechnungen exakt 3 mal nacheinander, bzw. so lange bis bei den letzten 3 Messungen mindestens 2 identische Resultate liefern.

Denn im Grunde müsste man wirklich in den Kernelmodus um per CLI/STI auch IRQs unterdrücken zu können. wie's Olliver schon sagte.

Gruß Hagen
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#13

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 1. Okt 2006, 00:26
Zitat von negaH:
Die einzigste zeitkritische Operation ist wenn man RDTSC und QueryPerformanceCounter aufruft. Sollte exakt dazwischen ein Taskswitch auftreten haben wir eine Messungenauigkeit. Man könnte das mit einer höheren Threadpriorität versuchen, ist aber im Grunde sinnlos Der Taskswitch könnte ja zu einem ähnlich priorisiertem Task erfolgen, ergo mit höherer Priorität verhindert man nicht den Switch.
Da kann dir der nächste "nette" Treiber schon ein Schnippchen schlagen. Die Threadprioritäten haben zwar zur Errechnung des Thread-Quantums eine Bewandnis, aber das juckt mal nen Treiber oder dessen DPC oder ISR garnix. Dein Usermode-Code läuft eben mal nur auf IRQL PASSIVE_LEVEL und im Falle eines APCs ein Level höher, aber diese beiden sind, wie man so schön sagt, unterbrechbar. Kommt also Code mit einem höheren IRQL (nicht verwechseln mit IRQs!!!), wird dein Code mal eben angehalten bis der andere fertig hat
(Das wären bspw. Geräte-IRQLs - auch nicht zu verwechseln mit IRQs - wo dann die ISRs - Interrupt Service Routines - laufen, siehe dein Kommentar zu CLI/STI.)

Zitat von negaH:
Denn im Grunde müsste man wirklich in den Kernelmodus um per CLI/STI auch IRQs unterdrücken zu können. wie's Olliver schon sagte.
Naja, Spinlock halten reicht schon, weil da nix anderes in dem Moment "ran darf". Ist dann halt bloß auf einem Prozessor und du darfst keinen ausgelagerten Speicher "anfassen" - ansonsten sagt dir Windows im stilisch ansprechenden himmelblauen Look: KMODE_EXCEPTION_NOT_HANDLED oder KERNEL_MODE_EXCEPTION_NOT_HANDLED oder (am wahrscheinlichsten) der allseits beliebte IRQL_NOT_LESS_OR_EQUAL.

Nachtrag: Übrigens, wenn ich mal Zeit finde, könnten wir das mal versuchen. Mich interessiert das eigentlich mal von der Seite her inwieweit das machbar ist. Man könnte ja eine ISR für die Tastatur einrichten, die dann den Treiber ggf. unterbrechen darf.
  Mit Zitat antworten Zitat
supermuckl

Registriert seit: 1. Feb 2003
1.340 Beiträge
 
FreePascal / Lazarus
 
#14

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 1. Okt 2006, 04:56
könnte man denn (jetzt mal von der highskilligen geschichte abgesehen) eine einfachere klasse erstellen, die ansatzweise genauer ist, als die gettickcount methode ?

also mit queryperformance timers, die dann halt wie schon hagen sagt, 3 mal hintereinander kalibriert werden und das beste genommen wird mit sleep(0) davor damit der prozess net auf nem anderen kern geswitcht wird, solange gecountet wird

geht das?

ich hab da net so viel plan von, bräuchte aber auch eine relativ genaue zeitmessung.

ich hab nen proggi, das pings checken soll (und das auch bei multikern-prozessoren ansatzweise genau gehen soll und nicht andauernd 4er pings anzeigen soll, obwol minimal 10 drin sind oder sogar negative werte

könnte da mal jemand ran gehen?? wäre echt extrem hilfreich.
Das echte Leben ist was für Leute...
... die im Internet keine Freunde finden!
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#15

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 1. Okt 2006, 13:16
QueryPerformanceCounter() ist absolut exakt, laut Microsoft, wenn die dummen BIOS Programmierer nichts falsch gemacht haben. Aber was interessiert mich das BIOS wenn ich als Programmierer das Microsoft API benutze.

Man kann die Auflösung von GetTickCount() ins Unendliche erhöhen, man muß nur unendlich viele Messungen durchführen, deren Resultate akkumulieren und damit einen Mittelwert berechnen. Das geht defakto mit jedem Messverfahren.
Praktisch gesehen ist das aber alles Theorie denn wir haben nicht unendlich viel Zeit.

Nein, meiner Meinung nach ist es Aufgabe jedes OS eine relativ genaue Zeitbasis zur Verfügung zu stellen. Aber exakt das ist mit den neueren CPUs/BIOSen/OSen wohl nicht mehr gegeben.

Ich habe meine Routinen auf GetTickCount() umgeschrieben, da mir im Grunde dessen Auflösung fast ausreicht. Man muß halt dann sehr schnelle Routinen mehrfach ausmessen und den GetTickCount() Wert eben nach der Berechnung dividieren.

Davon abgesehen wird man sich, selbst mit einer höchstgenauen Zeitbasis, die Frage gefallen lassen müssen, wie effektiv genau nun die gemessenen Werte sein können, wenn Treiber, Taskmanagement etc.pp. sowieso diese Messungen verfälschen werden.

Anders ausgedrückt: wie Olli es schon andeutete bekommen wir nur dann eine exakte Messung mit einer hochgenauen Zeitbasis, wenn wir sicherstellen können das die auszumessende Funktion auch wirklich die einzigste Funktion ist die wir ausmessen. Das können wir nur wenn wir alle OS/BIOS/Hardware Funktionen die dazwischen funken könnten, deaktivieren. Es reicht also noch nichtmal wenn wir unsere Funktion auf Ring0 mit höchster Priorität ausführen, denn die Hardware mit ihren intelligenten Sub-Controlern (Noth/South Brige, USB, DMA, Speicher, Cache usw. usf.) wird auch dazwischen funken.

Wenn wir das alles geschafft haben auszuschalten, dann bleibt das Problem der CPUs. Denn heutige CPUs sind unberechenbar in ihren Taktzyklen die sie benötigen für den Machinencode. Es ist eben nicht mehr so das ein OpCode wie ADD EAX,EAX exakt X Takte benötigt, sondern je nach Pipline/Cache etc. Status kann dies stark variieren.


@Oliver:
Ja, interessant wäre es durchaus mal sowas zu programmieren. ABER! es verstösst dann gegen meine jetzige Grundregel -> "vermeide unnötigen Streß in der Programmierng indem du den Mist der anderen Coder nicht versuchst besser zu machen !"
Besonders weil man Jahre damit verbringen kann, und in diesen Jahren haben diese Coder/Marketingleute schon wieder 5 neuere Systeme auf den Markt gebracht. Man kommt, ob man es will oder nicht, also immer in Verzug, und rennt diesen "aktuellen Trends und Modeerscheinungen" quasi immer mehr hinterher.

Ergo: interessant wäre es, aber es ist Zeitverschendung aus meiner Sicht.

[edit]
Man könnte also mit QueryPerformanceCounter() eine bessere Genauigkeit als GetTickCount() erreichen, das ist fakt. Die Frage ist nur wie unserere "Komponnente" den WorstCase (Fall, ups doppelt gemoppelt) das der QPC falsche Werte liefert, detektieren kann. In diesem Moment müsste unserere "Komponente" das erkennen können und auf einen anderen Timer ausweichen. Leider gibt es eben keinen exakten Weg genau das zu machen. Eine Sache wie mit GetTickCount() den QPC zu verfizieren ist für mich eine grauenhafte Vorstellung, man kann den Teufel nicht mit dem Belzebub austreiben
Ergo: gehe ich pragmatisch vor, GetTickCount(), und mehr geht nicht.
[/edit]

Gruß Hagen
  Mit Zitat antworten Zitat
supermuckl

Registriert seit: 1. Feb 2003
1.340 Beiträge
 
FreePascal / Lazarus
 
#16

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 2. Okt 2006, 03:50
hmm klingt alles logisch aber ich will doch mal meine probleme darstellen, die ich bekommen würde, wenn ich getickcount in meinem projekt verwenden würde:
Hmm klingt alles logisch, aber ich woll doch mal meine Probleme darstellen, die ich bekommen würde, wenn ich GetTickcount in meinem Projekt verwenden würde, anstatt das mit dem QueryPerformanceCounter Dingens zu berechnen:

Also es geht um das Programm "miniAdmin2", das einen Client für Call of Duty Server für die "Newbies" und "Admins" sein soll.
Es ist ziemlich belieb in der Community und deshalb bemühe ich mich auch im Vorfeld, "Falschanzeigen" im Programm zu vermeiden.
Und da sind wir auch schon beim Problem.
Die Server, die ich da anlegen kann, werden tabellarisch dargestell und erhalten in der Spalte "Ping" immer den aktuellen Ping, vom User zum Server, der sich jede Sekunde akualisiert.

Wenn ich jetzt jetzt die Methode "PerformanceCounter" benutze, sind die Pings in ihrer Auflösung etwa millisekundengenau, was schonmal ziemlich gut aussieht.
Allerdings muss ich, wie gesagt, negative Werte rausfiltern und damit leben, das mir der Ping ab und zu, zu wenig anzeigt.
Zum Beispiel hat ein Server einen Ping von durchschnittlich 15ms und dann auf einmal 4ms und weniger
Das verwirrt die User eventuell total und dann gibts Fragen über Fragen....

Wenn ich jezt die Methode "GetTickCount" benutze, sind die negativen Werte nicht vorhanden und die Pings sind annähernd real.
Allerdings ist die Zeitauflösung je nach Windows und PC etwas grob, was zu pings von 0 oder 16 oder sonstigen "eingerasteten" Messwerten führt.
Damit kann ich also noch weniger leben, da die Server dann sehr unreale Pings haben (obwohl das schon näher hinkommt)
aber wenn ich jetzt 10 Serve untereinander habe und 5 davon immer den gleichen Ping haben ( z.b. alle 16ms) dann sieht das ziemlich blöd aus
Was ich jetzt machen könnte, ist einen Pauschalwert vom Ping abziehen und noch nen gerundeten Wert von 1-2 ms dazu addieren. Das wäre dann schöne Statistikfälschung, sieht aber geil aus *g*

Ich hoffe ihr wisst jetzt was ich meine und ob man was dagegen tun kann weis ich leider nicht
Das echte Leben ist was für Leute...
... die im Internet keine Freunde finden!
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#17

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 2. Okt 2006, 08:30
Wenn ich das richtig sehe, hast Du einzelne Ausreißer nach oben oder unten. Das ist doch kein echtes Problem, zeige einfach den Mittelwert der letzten 4-5 Pings an und Du bist das Problem los. Du kannst Dir dann noch ein Intervall definieren an Werten, die Deinem Ermessen nach im "grünen" Bereich liegen und alle Werte, die nicht darin ligen, klassifizierst Du als Ausreißer und nimmst sie mit schwächerem Gewicht in die Wertung ein.

Gerade was Pings angeht, kommt dieser Wert in meinen Augen der Realität schon etwas näher, weil ein einzeler Ping alleine für sich genommen naturgemäß schwankt.

Nur: Wenn Dir Millisekunden reichen ... warum nimmst Du dann nicht GetTickCount() ? Dann hast Du einen Zähler am Wickel, der nichts mit CPU und BIOS zutun hat - zumindest nicht so direkt, wie dies hier mit den anderen Methoden der Fall ist.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#18

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 2. Okt 2006, 09:50
Hallo,
Zitat von Daniel:
Nur: Wenn Dir Millisekunden reichen ... warum nimmst Du dann nicht GetTickCount() ? Dann hast Du einen Zähler am Wickel, der nichts mit CPU und BIOS zutun hat - zumindest nicht so direkt, wie dies hier mit den anderen Methoden der Fall ist.
Vermutlich, weil GetTickCount, wie er oben schrieb, eine geringere Auflösung hat, als Millisekunden.

Gruß
xaromz
I am a leaf on the wind - watch how I soar
  Mit Zitat antworten Zitat
supermuckl

Registriert seit: 1. Feb 2003
1.340 Beiträge
 
FreePascal / Lazarus
 
#19

Re: exakte Zeitmessungen auf Multiprozessoren

  Alt 2. Okt 2006, 11:11
Dann scheint wohl die einzige Möglichkeit, einen Mittelwert über 5 Pings zu ziehen :/

Eigentlich sollten dann aber auch andere Programme, die solche Zeitabstände messen, probleme haben ?!
Ist es noch irgendjemand anderst aufgefallen bei irgend einem Programm?
Das echte Leben ist was für Leute...
... die im Internet keine Freunde finden!
  Mit Zitat antworten Zitat
Benutzerbild von TERWI
TERWI

Registriert seit: 29. Mär 2008
Ort: D-49626
381 Beiträge
 
Delphi 11 Alexandria
 
#20

AW: exakte Zeitmessungen auf Multiprozessoren

  Alt 18. Jul 2011, 09:48
Ich buddel diesen Fred mal wieder aus weil er hier den Nagel gennau auf den Kopf trifft
und endlich mal ne Antwort auf supermuckl's letzte Frage kommt.

Vorab gesagt: Ich brauche zwingend eine Routine, welche Zeitabstände <= ca. 200-250µS (mükro, NICHT milli Sekunden !) messen kann. besser noch kürzer.
QPC eignet sich im Prinzip hervorragend - wäre da nur nicht dieses lästige, zufällige hin- und herschalten zwischen den CPU's.

Bei mir z.B. laufen die Zeitunterschiede der CPU's mit der Laufzeit immer mehr auseinander, so das man spätetes nach 1 Stunde Laufzeit nur noch völlig 'beknackte' Negativ- wie auch Positiv-Werte bekommt.

Völligst untauglich.
Und andere Timer kommen leider nicht in Frage, weil die Auflösung zu klein ist.

Hatte dazu schon einen anderen Fred aufgemacht.
Diesen hab ich nur aus o.g. Grund mal weder hochgeholt, weil das Problem an sich hier sehr gut beschrieben ist.
Nur noch keine Lösung in Sicht ?!

Wo diskutieren wir ggf. weiter - in diesem Fred oder in dem anderen Fred ?

Geändert von TERWI (18. Jul 2011 um 09:51 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:17 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz