Autor Beitrag
bbfan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 164



BeitragVerfasst: Di 21.08.07 11:08 
Hallo Leute!

Ich weiss nicht mehr was ich noch machen soll, aber mein Thread ist tierisch langsam.
Folgendes Tuning habe ich bereits gemacht.

Hauptappl. Prozessorzeit erhöht:

ausblenden Delphi-Quelltext
1:
SetPriorityClass(GetCurrentProcess, HIGH_PRIORITY_CLASS);					


Thread Priority erhöht:

ausblenden Delphi-Quelltext
1:
SetThreadPriority(Handle, THREAD_PRIORITY_TIME_CRITICAL);					


Mal benötigt die CPU 10 msec für die "execute" Bereich, dann wieder bis 200msec. Im Schnitt immer so um die 90msec.

Hier der gesamte Thread:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
new(rthreadSpeed);
 rthreadSpeed^.total_rounds:=0;
 rthreadSpeed^.msec:=0;
 while (abbruch.Status=false) do
  begin
   if getThreadPriority(handle)<>THREAD_PRIORITY_TIME_CRITICAL then SetThreadPriority(Handle, THREAD_PRIORITY_TIME_CRITICAL);
   time_begin:=time;
   CapGrabSingleFrameBMP(bmp_live);
   add2MemStream(PIC_PATH + GBL_event_id+'\'+generateUniqueFileName(USER_ID+'_stream.jpg'));
   DecodeTime(time-time_begin, Hour, Min, Sec, MSec);
   rthreadSpeed^.msec:=rthreadSpeed^.msec + ((Sec*1000) + MSec);
   rthreadSpeed^.total_rounds := rthreadSpeed^.total_rounds + 1;
   rthreadSpeed^.last_msec := ((Min * 60 * 1000) + (Sec * 1000) + MSec);
   k:=r_speed_msec - rthreadSpeed^.last_msec;
   if k > 0 then
    begin
     SetThreadPriority(Handle, THREAD_PRIORITY_NORMAL);
     sleep(round(k));
    end;
  end;
  bmp_live.free;
  r_err.free;
  temp_bmp.free;
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Di 21.08.07 11:39 
Die Priorität derart zu erhöhen ist iirc eine sehr ungute Idee. Was macht denn dein Thread genau? Wie und wieoft wird mit dem Hauptthread synchronisiert (denn das dauert recht lange)?

Was machen die Funktionen, die du da aufrufst? Eine Bremse könnte evtl. der MemStream sein. Wenn das ein Memorystream ist, und der "voll" ist, dann muss ggf. komplett im Speicher umkopiert werden.

_________________
We are, we were and will not be.
bbfan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 164



BeitragVerfasst: Di 21.08.07 13:18 
Ich habe festgestellt, dass diese Funktion "CapGrabSingleFrameBMP(bmp_live);" die CPU Zeit frisst.
Diese Funktion grabed ein WebCam Bild in ein TBitmap.
Hier stellte ich fest, dass die Geschwindigkeit auch abhängig von der Hardware ist. Ich habe 2 Webcams. Arbeite ich mit der einen, so können max. 6 Bilder pro Sekunde gegerabt werden. Mit der 2. Wecam schaffe ich 18 Bilder.
Es scheint hier also auch die Hardware eine Rolle zu spielen.

Trozdem benötigt das eine Grabben mal 10msec und dann wieder 100msec. Das verstehe ich nicht.
Ich führe es darauf zurück, dass der Thread mal viel CPU Zeit bekommt, mal weniger.

Eine Sync. wird nicht durchgeführt, da diese hier nicht gebraucht wird.

Ich arbeite nicht mit MemoStream... Ich habe ein TList in der ich TJpegImage Records reinschiebe (Buffer). Der Buffer wird regelmäßig weggeschrieben. Ein Volllaufen des Speichers ist ausgeschlossen.

Ich habe aus der execute Methode alle andere Prodceduren mal ausgeklammert und es ist eindeutig das Grabben des Frame von der WebCam, was die Zeit frist. Und zwar extrem unterschiedlich. Mal dauert es 10msec, dann wieder 100msec. Faktor 10!!!

Die Thread Priority spielt auch eine Rolle. Bei geringer Priorität dauert es noch länge als bei hoher.
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Di 21.08.07 13:49 
Wie Gausi schon sagte ist das Verändern der Prioritäten nur mit Vorsicht zu genießen. Bzw ein Setzen der Prio auf Kritisch hat dort nichts zu suchen. Denn das Einzige was du damit erreichst ist die Stabilität des Systems zu gefährden. Normal sollten nur Kernelkomponentem etc. diese Priorität bekommen. Denn du blockierst damit unter Umständen auch wichtige Teile des Betriebssystems die teilweise selber auch nur auf Hoch laufen. Und wie du ja festgestellt hast bringt es gar nichts.

Aber du ließt von einer Webcam. Die sind externe Hardware und müssen über USB angesprochen werden. Wie du ja selber gesehen hast ist diese auch nicht immer gleich schnell. Es kommt also auch auf die in der Hardware verbauten Teile an und wie viel Traffic sonst noch auf dem USB liegt.

Außerdem speicherst du JPEGs ab, oder? Das Komprimieren eines JPEGs dauert je nach Größe auch einiges an Zeit. Denn das Lesen eines 800x600 großen JPEGs dauert mit der Implementation von Delphi schon knapp 150-200ms.

Bzw wie misst du die Zeit die vergangen ist? Mit GetTickCount? Wenn ja würde ich eher auf den PerformanceCounter setzen. Der kommt direkt vom Prozessor und ist damit wesentlich zuverlässiger und genauer. Siehe QueryPerformanceFrequency und QueryPerformanceCounter.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
bbfan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 164



BeitragVerfasst: Mi 22.08.07 08:48 
Danke für deine Hinweise:

Also die Prozesszeit ermittele ich so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
   time_begin:=time;  
    CapGrabSingleFrameBMP(bmp_live);  
    add2MemStream(PIC_PATH + GBL_event_id+'\'+generateUniqueFileName(USER_ID+'_stream.jpg'));  
    DecodeTime(time-time_begin, Hour, Min, Sec, MSec);  
   rthreadSpeed^.process_time := ((Min * 60 * 1000) + (Sec * 1000) + MSec);


Falscher Weg?

Quasi 2 Zeitmessung über time() und dann subtrahieren...
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Mi 22.08.07 12:29 
Ah, USB - das erklärt einiges.

USB ist kein "direkter" Bus. Es ist ein reiner Master-Slave-Bus. Das heißt: Jedwede Transaktion, die über USB läuft, muß vom Master angestoßen werden. Jede, ohne Ausnahme. Das heißt, selbst wenn deine Webcam ein Bild fertig aufgenommen hat, muß der Master erst fragen: "Hast du was für mich ?".

Diese Master-Abfragen finden prinzipbedingt alle 100ms statt, IIRC. Dein Thread trifft nun manchmal genau den richtigen Zeitpunkt - manchmal auch nicht. So kommen die seltsamen Zeitunterschiede zustande. Daran ist nichts zu rütteln, auch höchstmögliche Thread-Prios werden nichts helfen.

Die interne Uhr dann für Laufzeitermittlungen zu verwenden, ist auch so eine Sache... Ich persönlich benutze aus der JCL die TJCLCounter - die arbeiten Nanosekunden-Genau (RDTSC usw).

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
bbfan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 164



BeitragVerfasst: Fr 24.08.07 08:17 
Ok Vielen Dank für eurer Hilfe und Informationen.