Autor Beitrag
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 19.04.03 10:24 
Habe ein relativ rechenintensives Programm geschrieben. (Durchtesten von allen möglichen Kombinationen). Bisher ist es so, dass ich einen Timer eingebaut habe, d.h. wenn nach 2 Sekunden keine "bessere" Kombination gefunden wurde, wird mit der Suche abgebrochen.

Problem: Wenn andere cpu-zeit fressende Programme gleichzeitig laufen (SETI@home, mp3 kodieren o.ä.), dann ist das natürlich relativ sinnfrei, das mit nem normalen timer zu machen. Gibt es ne Komponente "CPU-Timer", die mitzählt, wieviel RECHENzeit vergangen ist? Also wieviel Zeit mein Programm zur Berechnung hatte?
Und wenn nicht, wie kann ich mir die basteln?

_________________
We are, we were and will not be.
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Sa 19.04.03 10:32 
Also, was wilslt du? Die komplette Zeit? Versuch GetTickCount() oder etwas genauer wäre QueryPerformanceCounter().

Wenn du aber wissen willst, wieviel CPU-Zeit deinProg verbraten hat, dann brauchst du erstmal Windows NT. Dann GetProcessTimes() aufrufen (erster Parameter = GetCurrentProcess()). Deine Zeit ist dann UserTime + KernelTime. In FileTime, also 100ns-Schritte seit dem 01.01.1601. So geht's:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
var
  fCreationTime, fExitTime: TFileTime;
  fKernelTime, fUserTime: TFileTime;
  T1, T2, T3, T4: Int64;
  UsageTime: Double;
begin
  GetProcessTimes(GetCurrentProcess, fCreationTime, fExitTime, fKernelTime, fUserTime);
  T1 := Int64(fLastUserTime.dwLowDateTime) Or (Int64(fLastUserTime.dwHighDateTime) Shl 32);
  T2 := Int64(fActualUserTime.dwLowDateTime) Or (Int64(fActualUserTime.dwHighDateTime) Shl 32);
  T3 := Int64(fLastKernelTime.dwLowDateTime) Or (Int64(fLastKernelTime.dwHighDateTime) Shl 32);
  T4 := Int64(fActualKernelTime.dwLowDateTime) Or (Int64(fActualKernelTime.dwHighDateTime) Shl 32);

  UsageTime := ((T2 - T1) + (T4 - T3)) / (1000 * 1000 * 10); 
end;


Usage Time ist dann die Zeit (in Sekunden), in der dein Prozess deine CPU gestresst hat. Um nun rauszufinden, wie lange er nur dür deinen Algo gebraucht hat, muss du UsageTime 2mal ausrechnen, davor und danach, und dann beide subtrahieren.

Noch fragen? Ich hoffe, das war, was du woltlest.

_________________
Life is a bad adventure, but the graphic is really good!
Gausi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 19.04.03 12:48 
Zitat:
Ich hoffe, das war, was du wolltest.

ja und nein :?
getTickcount und QueryPerformanceCounter bringen mir nix, wenn ich das richtig verstanden habe. Die Zeit, die das System schon läuft, ist für meine Zwecke absolut uninteressant. Auch die Differenz dieser Zeit zwischen AlgorithmusStart und -Ende, da reichen mir nämlich die Millisekunden von TTimer.

Und das man zum messen der CPU-Zeit, die mein Programm verbrät, WindowsNT oder 2000Prof / XP haben muss, stellt mich auch nicht wirklich zufrieden.
Unter Win95/98 können doch auch schon mehrere Anwendungen "gleichzeitig" laufen, dann muss es da doch auch ne Möglichkeit geben, rauszufinden, welcher prozess wieviel Zeit verbrät...
Aber: wenn ich deinen Code in nen try..except Block packe, müßte das Programm doch auch auf Win95 laufen, oder?

_________________
We are, we were and will not be.
Raphael O.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1596


VS 2013
BeitragVerfasst: Sa 19.04.03 12:52 
laufen schon, aber net funktionieren ;)
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Sa 19.04.03 12:54 
Nun denn, sage er mir, was er genau wolle :wink:



Ich habe nämlich noch nicht so recht verstanden was du KONKRET willst.

_________________
Life is a bad adventure, but the graphic is really good!
Raphael O.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1596


VS 2013
BeitragVerfasst: Sa 19.04.03 13:11 
Gausi hat folgendes geschrieben:
Gibt es ne Komponente "CPU-Timer", die mitzählt, wieviel RECHENzeit vergangen ist? Also wieviel Zeit mein Programm zur Berechnung hatte?


@Gausi: wenn du die Kombinationen durchtestest, dann kannste doch mit ner Variable mitzählen, wieviele es bisher waren und dann bei einer bestimmten Höhe aufhören...
Gausi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 19.04.03 17:24 
@Fiji-Fighter: Ja, daran habe ich auch schon gedacht. Ist aber nicht eine sooo schöne Lösung, da man dann natürlich keinen direkten Vorteil mehr hat, wenn man nen schnelleren Rechner hat. Es sei denn, man gibt ne höhere Abbruchschranke an.

@ Andreas Pfau: Also. Ich wollte das wissen, was du in deinem zweiten Vorschlag beschreibst. Ich will wissen, wieviel CPU-Zeit zur Berechnung draufgeht.
Bisher starte ich bei Beginn der Berechnung einen Timer und setze als OnTimer Ereignis den Abbruch der Berechnung, d.h ich setze da eine "Weitermachen-Variable" auf false.
Der timer zählt aber ja auch die Zeit mit, in der Seti Signale analysiert, oder ein audiograbber mp3s codiert, oder die Zeit die eMule für seine Berechnungen braucht oder Unreal2 oder CorelDraw für Texturberechnungen oder sonst irgendwas. Diese Zeit möchte ich aber eigentlich nicht mitzählen.
Das würde wohl mit GetProcessTimes() gehen, aber eben nicht auf "älteren" Windows-Versionen. Und ich möchte die Systemvorraussetzungen so gering wie möglich halten.

Ich hoffe, das ist jetzt etwas klarer geworden.

_________________
We are, we were and will not be.
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Sa 19.04.03 20:36 
Puh... da bin ich überfragt.... so was kenne ich nicht. Das ist halt der Nachteil von GetProcessTimes().

_________________
Life is a bad adventure, but the graphic is really good!
Stefan-M
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29



BeitragVerfasst: Di 22.04.03 13:12 
Dann probier es doch mal mit

ausblenden Quelltext
1:
GetThreadTimes(hThread, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);					


guck dazu nochmal in msdn.microsoft.com/l...e/getthreadtimes.asp nach

Gruß
Stefan
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Di 22.04.03 16:14 
:mahn:
Zitat:
Requirements

Client: Included in Windows XP, Windows 2000 Professional, and Windows NT Workstation 3.5 and later.
Server: Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server 3.5 and later.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.


Das Problem leigt doch ALLEIN darin, dass GetProcessTimes() nur unter NT funzt... Bei GetThreadTimes() ist das genauso!

Aber ich muss dir trotzdem rechtgeben, denn für diesen Zweck könnte GetThreadTimes() besser sein, zumindest wenn er's mit multithreading implementiert.

_________________
Life is a bad adventure, but the graphic is really good!
Gausi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Di 22.04.03 21:52 
@ Andreas
ne, ich hab nur einen Thread am laufen, von daher würde dein erster Vorschlag mit getprocesstimes also ausreichen.

-----
Muss mal überlegen, ob ich das noch implementiere, scheinbar geht das mit Win98 oder früher wirklich nicht. Hab gehört, dass sich frühere Windowsversionen nicht um die CPU-Zeit Zuteilung kümmern. Wenn was frei ist, nimmt sich ein Prozess soviel er braucht, und blockiert damit ggf das komplette System.
Und etwas einzubauen, was auf vielen Rechnern nix bringt, seh ich auch nicht ein. Dann haben eben die, die andere Programme gleichzeitig laufen lassen, einfach Pech gehabt. :P

_________________
We are, we were and will not be.
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Di 22.04.03 22:18 
Nun, es gibt noch eine Triviallössung, aber schnall dich an, die ist furchtbar Trivial: Die Threadpriorität auf Realtime setzen, denn dann nimmt dein Timer GARANTIERT keine anderen Threads auf :wink:

Aber wenn du das machst, dann Rede ich nicht mher mit dir (nicht so gemeint), denn dann kann sein, gar nix geht mehr. GAR NIX, sogar, wenn dien Prog absolut Fehlerfrei ist. Ich würde das höchstens zur Analyse nehmen, nicht für den "Alltagsgebrauch".

_________________
Life is a bad adventure, but the graphic is really good!
SpeedyGTD
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Mo 05.05.03 01:16 
mal so ne dumm frage dazu, wie kann man die Prio denn verändern?
bzw wie kann ich die auf Realtime setzen?

_________________
...hab ich vergessen ;)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 05.05.03 01:57 
SetPriorityClass
Zitat:

The SetPriorityClass function sets the priority class for the specified process. This value together with the priority value of each thread of the process determines each thread's base priority level.
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Mo 05.05.03 12:52 
Prozesspriorität (betrifft die gesamte Anwendung):
ausblenden Quelltext
1:
SetPriorityClass(GetCurrentProcess, Realtime_Priority_Class);					


Threatprioritätä (betrifft nur den aktuellen Thread):
ausblenden Quelltext
1:
SetThreadPriority(GetCurrentThread, Thread_Priority_Time_Critical);					


die Konstanten stelle je den höchsten Wert dar. WinAPI-Hilfe für mehr Konstanten.

_________________
Life is a bad adventure, but the graphic is really good!
SpeedyGTD
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Mo 05.05.03 18:20 
hehe cool das geht sogar, nur hab ich jetzt die vorhergesagten Systemabstürze ;) aber das macht nix, das Prog iss für meinen Bruder :twisted: der wird schon merken wenn sein System immer einfriert wenn er das Programm schliessen will :D

_________________
...hab ich vergessen ;)
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Mo 05.05.03 19:05 
Soll ich dir verraten, WARUM dein Prog allles einfriert, obwohl KEINERLEI Fehler vorliegen? Dein Prog hat nun eine höhere Priorität als das Windows-Kernel, somit wird Windows blockiert (!), und ohne Windows läuft auch dein Prog nicht. Daher sollte man so was nur für KURZE Abweisungen verwenden, und auch dann nur, wenn unbedingt nötig, wenn du z.B. wissen willst, wie schnell ein Befehl in 'ner Schleife abläuft (dein Beispiel).

Priorität immer nur MAXIMAL 2 Stufen über normal, am besten nur eine Stufe. außerdem würde ich es bei mehreren Thread über die Threadpriorität regeln, nicht über die Prozesspriorität.

Wenn dir so was mal passiert: vorne am PC ist so eine kleine Taste, nimm' nen Kuli... :wink:

_________________
Life is a bad adventure, but the graphic is really good!
SpeedyGTD
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 89



BeitragVerfasst: Mo 05.05.03 21:12 
Zitat:
Soll ich dir verraten, WARUM dein Prog allles einfriert, obwohl KEINERLEI Fehler vorliegen? Dein Prog hat nun eine höhere Priorität als das Windows-Kernel, somit wird Windows blockiert (!)
:D jepp iss mir bekannt war auch mit diesem Satz schon beschrieben
Zitat:
nur hab ich jetzt die vorhergesagten Systemabstürze ;) aber das macht nix.....
wenn sein System immer einfriert wenn er das Programm schliessen will :D
des Prob iss auserdem indem gelöst das ich die Process Prio. beim beenden auf normal stelle :wink:

_________________
...hab ich vergessen ;)
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Di 06.05.03 15:06 
Aha, dann is' ja alles OK :D

_________________
Life is a bad adventure, but the graphic is really good!