Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Timing im µs-Bereich
Tobias1 - Mi 01.03.06 13:19
Titel: Timing im µs-Bereich
Hi,
wie kann man bestimmte Befehle im µs-Bereich timen (Es geht um das An- und Ausschalten einer Schnittstelle).
Bis 1 ms ist das ja alles kein Problem (mit dem Timer).
Vielen Dank schonmal.
Christian S. - Mi 01.03.06 13:22
Hallo!
Das dürfte auch bei 1ms bereits ein Problem sein. Soweit ich weiß, ist es unter Windows nicht möglich, Zeiten von weniger als ca. 20ms wirklich zu garantieren. Such aber mal im Forum, IIRC gab es da schonmal ein Topic zu.
Grüße
Christian
Spaceguide - Mi 01.03.06 13:25
Also garantieren kann man unter Windows überhaupt nichts, nichtmal 20ms. Windows ist nunmal kein Echtzeitbetriebssystem.
Christian S. - Mi 01.03.06 13:28
Das ist schon richtig, habe ich auch nicht behauptet. Wenn die Zeiten größer werden, erhält man aber zum einen eine größere Sicherheit und meistens werden Abweichungen dann unwichtiger. Obs nun 200ms oder 201ms sind, wird wohl meist im Bereich der Toleranz sein ;-)
Spaceguide - Mi 01.03.06 13:34
Wenn Windows macht ordentlich zu swappen anfängt, dann kann ein System mal für ein paar Sekunden stehen, aber zum Thema zurück: Verwende mal statt des TTimers z.B. einen Threaded-Timer, wie es ihn bei
http://www.carlosb.com/ gibt. Der ist im allgemeinen genauer.
Tobias1 - Mi 01.03.06 13:35
Könnte mir vielleicht der QueryPerformanceCounter helfen, oder ist der genauso ungenau?
Allesquarks - Mi 01.03.06 13:44
Das Problem ist viel allgemeiner: Bei heutigen CPU können wärend dieser Frist gerade einmal Befehle im Tausender-Bereich abgearbeitet werden können. Das wird schon kritisch, in diesen paar tausend (ca 1-3 evt. nen bischen mehr, wenn alle Pipelines arbeiten) Befehlen den Scheduler sowie die anderen wichtigen Systemdienste zum laufen zubringen, die Message zu erzeugen und dann wahrscheinlich auch noch nen Contextswitch vom Protected in den Real-Mode und zurück. Wenn du das wirklich brauchst, hol dir ein Gerät, was extern 1 mikrosec timed und dann über nen Buffer gelesen werden kann.
Bzw. für die Essentialisten: Mach dir ne bootbare CD und mach dein Programm direkt ausführbar (nicht mit Delphi), geht dann nen Bischen in Richtung Betriebssytem, denn dann hast du die volle Kontrolle über deinen Computer über sämtliche Uhren etc. und niemand kann dir da dazwischenfunken. Problem: Keine Systemdienste Festplatten etc. WÜrde ich auf gar keinen Fall selber machen. Aber vielleicht gibst da was im Internet
Tobias1 - Mi 01.03.06 13:52
Das heißt die QueryPerformance Methode ist auch zu ungenau?
sonst könnte man es so machen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| var a, b, c, d: Int64; begin QueryPerformanceFrequency(a); QueryPerformanceCounter(b); repeat QueryPerformanceCounter(d); until ((d-b)*1000000/a) > 133 ; |
BenBE - Mi 01.03.06 14:18
Eine QPC-Abfrage dauert bei mir zwischen 20 und 200 Zyklen (auf 1,4 GHz)... Das ist schon zu ungenau für eine wirkliche Messung von einer Microseunde. Denn nicht jede CPU löst Dir QPC auf ihre Taktfrequenz auf. Die meisten Intels nämlich nur auf ~3 MHz ...
BTW: Deine Prüfbedingung ist viel zu Umfangreich. Divisionen in einer Schleife sindzu vermeiden!!!
Tastaro - Mi 01.03.06 14:52
Also 1ms ist kein Problem. Auch unter Windows nicht.
Wenn man
Delphi-Quelltext
1: 2:
| SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL); SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS); |
verwendet, dann macht das Betriebssystem keinen Zapp mehr.
Allerdings ist das nur eine Lösung, wenn man für einen begrenzten Zeitraum Echtzeit braucht.
1us wird nicht gehen. Da brauchst du, wie schon erwähnt, was externes.
Beste Grüße
Tastaro
Horst_H - Mi 01.03.06 15:15
Hallo,
um Taktzahlen bei einem Pentium aufwaerts zu stoppen kann man dies hier:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| var T1,T0 : int64;
procedure Zeit(var T:int64);Assembler; asm MOV ECX,EAX dw 310Fh mov Dword Ptr [ECX], eax mov Dword Ptr [ECX+4], edx end;
begin Zeit(t0); Zeit(t1); writeln(t1-t0,' CPU-Takte'); end; |
benutzen.
Bei mir bei dauert dies ca 35..44 Takte fuer diese beiden Aufrufe.
Damit kannst genauer messen, aber nicht genauer arbeiten.
Der Port-Zugriff(Com,Lpt z. B. Port[LPTAdresse] := blabla)) ist immer elend langsam, 1000 Takte (ca. 0.5*10^-6 Sekunden)verschwinden wie nichts ,auch unter DOS statt Windows.
Gruss Horst
BenBE - Mi 01.03.06 15:24
@Horst: Bei ASM müssen für Prozeduren nur EBP, ESP, EBX, EDI und ESI erhalten bleiben.
Das PUSH ECX und POP ECX kann also raus.
//Edit: Ergänzung: Für Funktionen müsstest Du EAX erhalten für das Funktionsergebnis, wobei dieses bei Int64 BeRef übergeben wird IIRC.
beastofchaos - Sa 08.01.11 20:53
Das Thema ist sehr alt, aber ich möchte nebenbei was vorschlagen, was da vll doch funktioniert:
Bevor ich Timer kennen gelernt habe ( kann Delphi seit 1 Jahr ), hab ich einfach mal eine "for i=0 to 1000000"-Schleife gemacht, um eine Pause einzufügen. Wenn ich mich recht entsinne, dann sind 1.000.000 ~1 Sekunde, womit eine "for i=0 to 1"-Schleife mit einer Geschwindigkeit von eine Mikrosekunde arbeitet möglicherweise.
Grüße, beast :p
Teekeks - Sa 08.01.11 21:28
Gut und jetzt nimm eine CPU die doppelt so schnell ist wie deine jetzige: was fällt auf?
glotzer - Sa 08.01.11 21:32
ich würd dafür kein windows hernehmen sondern einfach ein realtime betriebsystem das dafür gedacht is sowas zu machen
jaenicke - Sa 08.01.11 21:35
Keine Ahnung und dann auch noch uralte Threads ausgraben, das hab ich gern... :roll:
Delete - So 09.01.11 00:39
Möglicherweise um diese Zeit 19:53 Uhr schon besoffen...
bummi - So 09.01.11 01:13
@hathor
charmant wie immer....
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!