AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Rechnerauslastung

Ein Thema von juelin · begonnen am 11. Jun 2024 · letzter Beitrag vom 11. Jun 2024
Antwort Antwort
juelin

Registriert seit: 9. Mai 2006
Ort: Mannheim
141 Beiträge
 
Delphi XE5 Professional
 
#1

Rechnerauslastung

  Alt 11. Jun 2024, 10:30
Hallo liebe Delphigemeinde,
ich habe ein Programm gemacht, welches Daten von der Soundkarte holt und diese bearbeitet.
Da ich die Daten sehr schnell brauche rufe ich im Mainthread alle 8 ms einen Routine auf, welche die Daten bereit stellt
und einen zweiten Thread zur verarbeitung von den Daten startet.
Das ganze soll so 10-15 Minuten laufen.
Das sind 112500 Threads die ich in 15 Minuten starte.
Die Routine die die Daten verarbeitet läuft ca. 200ms.
Das bedeutet, das nach 15 Minuten noch 112050 Threads laufen.
Das das den Rechner ordentlich belastet brauche ich wohl nicht erwähnen.
Nun zu meinem Problem:
Im Maintrhread habe ich eine Menüleist, mit der ich den Vorgang starte und stoppe.
Aber wenn das Programm mit den Threads läuft kann man die Menüleiste nicht mehr bedienen.
Hat da jemand eine Idee?
Anbei die Routine die die Threads startet (alle 8 ms).
Delphi-Quellcode:
function RecordingCallback(Handle: HRecord; buffer: Pointer; length: DWord; user: Pointer): boolean; stdcall;
  var rueck: Boolean;
  var x1: integer;
  var x2: Cardinal;
  var ThreadHandle: THandle;
  var ThreadId: DWORD;
  var test7: PAnsiChar;
  var test8: integer;
  var test9: PAnsiChar;
begin
  rueck:=False;
  if Length > 0 then
  begin
    x2:=WaveStream.Write(buffer^,length);
    THreadNum:=Threadnum+1;
    rueck:=True;
    BASS_ChannelGetData(ChannelInput, @FFTData0, BASS_DATA_FFT4096);
    GetMem(test9, 8192);
    test7:=@FFTData0;
    for test8:=0 to 8191 do
    begin
      test9[test8]:=test7[test8];
    end;
    adresse:=test9;
    ThreadHandle:=BeginThread(nil, 0, TFNThreadStartRoutine(@Berechnen), nil, 0, ThreadId);
    if ThreadHandle <> 0 then CloseHandle(ThreadHandle);
  end;
  Result:=rueck;
end;
Danke für die Hilfe und Gruß
Jürgen
Jürgen Linder
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.765 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Rechnerauslastung

  Alt 11. Jun 2024, 10:37
.. so viele Threads halte ich für kontraproduktiv, da geht ja viel Zeit für die Verwaltung der Threads drauf.

Wieviele Kerne hat denn dein Rechner?
Pro Kern würde ich nur max 4 Threads starten.

Viele Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
639 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Rechnerauslastung

  Alt 11. Jun 2024, 11:49
Was spricht dagegen die Daten erstmal alle in einen Puffer zu schreiben und schön gemütlich mit einer Hand voll Threads zu verarbeiten. Da bist Du schneller als wenn du dein System mit tausenden Threads killst.
Es ist doch eh ein langer Strom. Den kannst Du dann später zerlegen wie Du ihn brauchst. Ohne Zeitdruck.
Alles wird viel entspannter. Du bekommst eh keinen Thread dazu genau alle 8ms irgendwas zu machen.
Auf deinen Testrechner, wo Delphi drauf ist, mag das klappen, weil Delphi das Zeitverhalten von Windows ändert. Auf anderen PC klappt das nicht.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
TomyN

Registriert seit: 8. Nov 2006
Ort: Bayreuth
211 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Rechnerauslastung

  Alt 11. Jun 2024, 11:52
Hi,

die Threads sind doch dann auch schnell fertig, oder?
Ich mache es beim Audioinput immer so, dass es einen Thread gibt, der die Daten in einen internen (Ring-)Speicher ablegt und einen zweiten, der über einen Event informiert wird, wenn neue Daten da sind und sich dann um die Auswertung kümmert.

Tomy
Thomas Neumann
Meine Projekte
www.satlive.audio
www.levelcheck.de
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.632 Beiträge
 
#5

AW: Rechnerauslastung

  Alt 11. Jun 2024, 12:49
Pro Kern würde ich nur max 4 Threads starten.
Warum das? Du zwingst damit drei 3 Deiner Threads, auf den vierten zu warten. Das bedeutet, selbst wenn der vierte vorzeitig fertig wird, terminiert der Thread und verwirft den Rest seiner Rechenzeit, die dann an einen anderen Prozess geht.
Und da der OS-Scheduler darauf achtet, die CPU-Ressourcen gleichmäßig auf die Prozesse (nicht Threads) zu verteilen, bekommen im gleichen Zeitraum acht Threads genau so viel Rechenzeit wie vier. Mit dem Unterschied, dass der Code in den restlichen vier solange blockiert ist und nicht abgearbeitet werden kann. Du bist also sogar langsamer wenn Du auch nur einen Thread zu viel erstellst.

Ideal ist genau ein einziger (lauffähiger) Thread pro Kern. Lauffähig heißt, er blockiert nicht wegen irgendwelchem I/O. Also wenn I/O, dann asynchrone APIs benutzen, damit nichts blockiert.

Jeder dieser Threads arbeitet in einer Endlosschleife Aufgaben ab, die über eine Queue synchronisiert werden. So kann man das Quantum (die CPU-Zeitscheibe, die der Thread zugeordnet bekommt), maximal ausnutzen. Im perfekten Fall sind alle physischen Kerne also mit Deinen Threads beschäftigt, und keiner Deiner Threads ist blockiert - somit bekommt man nur so die ideale Ressourcenauslastung hin.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.039 Beiträge
 
Delphi 2009 Professional
 
#6

AW: Rechnerauslastung

  Alt 11. Jun 2024, 14:57
Ideal ist genau ein einziger (lauffähiger) Thread pro Kern.
Eben. Es gibt schon einen Grund, warum andere Programme nur so viele Threads erlauben, wie man CPU-Threads hat. 7-Zip LZMA2 zum Beispiel.

Außerdem muss man bei Threads mit Speicheranforderungen aufpassen. Zu viele SetLength oder ähnliches im Thread, schon läuft das Ding so schnell wie ohne.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.529 Beiträge
 
Delphi 12 Athens
 
#7

AW: Rechnerauslastung

  Alt 11. Jun 2024, 17:22
FastMM kann 3 Speicheranfragen gleichzeitig, je BlockGröße.

Aber Ändern und Freigeben, das geht natürlich gezielt auf einen bestimmte Gruppe und da kann dann nur ein thread gleichzeitig.


Die Anderen müssen dann warten.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
267 Beiträge
 
#8

AW: Rechnerauslastung

  Alt 11. Jun 2024, 18:54
Hi, again !

I said in earlier post that will be my last about this, now my blood is boiling and i can't see this and see no one correcting you post #1, so i will comment here trying to correct few problems in your post, and again this will be my last about this subject, as you either don't understand me or not interested even in asking.

Sorry, i will put it as it, and that is every single line you wrote is wrong or have a misunderstanding and need an essay to explain.

Zitat:
Since I need the data very quickly, I call a routine in the main thread every 8 ms, which provides the data
Right, it should be handled and processed quickly, but how on earth are you calling a routine every 8ms !??, if that happen then you are tearing the sound card driver along with OS kernel a new ....
That is wrong.

Zitat:
and starts a second thread to process the data.
Why on earth you need a new thread for each 8ms buffer,
That is wrong.

Zitat:
The whole thing should run for around 10-15 minutes.
That's 112,500 threads that I start in 15 minutes.
WHAAAAATTT !
That is wrong on every imaginable level.

Zitat:
The routine that processes the data runs for around 200 ms.
How and what the hell this process that takes 8ms of samples sound data, and need 200ms, i am can't find any scenario for that be logical or correct, heck 8ms you might calculate its DFT with pen and paper and will not takes time much time, (sarcasm sorry) , but for real, the only thing i can make sense of, this 200ms process is drawing pixel on a GUI somewhere and utilizing TCriticalSection.
That is wrong.

Zitat:
This means that after 15 minutes 112,050 threads are still running.
That is wrong and should be considered as unthinkable.

Zitat:
I don't need to mention that this puts a lot of strain on the computer.
Strain is not the word, unsoldering every transistor and capacitor in your PC is more accurate description.

Zitat:
Now to my problem:
correction, problem -> problems

Zitat:
Does anyone have an idea?
Some might have, but you need to ask the right question.

Code:
function RecordingCallback( Handle : HRecord; buffer: Pointer; length: DWord; user: Pointer): boolean; stdcall ;
  var back: Boolean;
  var x1: integer;
  var x2:Cardinal;
  var ThreadHandle: THandle;
  var ThreadId: DWORD;
  var test7: PAnsiChar;
  var test8: integer;
  var test9: PAnsiChar;
begin
  back:=False;
  if Length > 0 then
  begin
    x2:=WaveStream. Write (buffer^,length);
    THreadNum:=Threadnum+1;
    back:=True;
    BASS_ChannelGetData(ChannelInput, @FFTData0, BASS_DATA_FFT4096);
    GetMem(test9, 8192);
    test7:=@FFTData0;
    for test8:=0 to 8191 do
    begin
      test9[test8]:=test7[test8];
    end ;
    address:=test9;
    ThreadHandle:=BeginThread( nil , 0, TFNThreadStartRoutine(@Calculate), nil , 0, ThreadId);
    if ThreadHandle <> 0 then CloseHandle(ThreadHandle);
  end ;
  Result:=back;
end ;
This callback doesn't make sense and wrong, let me break it for you:
The RecordingCallback receive length parameter and you are copying the data into some stream, then call BASS_ChannelGetData and handling the real length returned form it !!
Calling GetMem for 8kb, where did you get that length from ?!!! yes i see BASS_DATA_FFT4096 but that is not right at all, you should check what exactly are you getting.
I will assume you read http://bass.radio42.com/help/html/a1...fdf21bd463.htm and do understand returned bit(band) values.
As i remember NOAA and remember how it should processed, the process of the returned value from calculated DFT using FFT, is and as always get the logarithm of the value to get the amplitude.
"for test8:=0 to 8191 do" just use Move()

BeginThread is my favorite method to background threading, but that is wrong, very very wrong !
shouldn't be some data or pointer to data to pass to that thread !?? how it will know what to do.

Dear juelin, please don't be offended or takes this the wrong way, clearly you asked about this subject and you are trying to solve it, and i respect that so much, yes one should do it himself, but i suggested and pointed in different threads, and either you didn't understand my English (heck i am barely understand myself) or you are not interested in my solution as you didn't comment by a simple why or other questions.

For the last time and as i reminder i mentioned (i think in this forum) that VCP from LakeOfSoft way better than BASS when it comes to Delphi, it has DFT using FFT, and even support complex numbers and inverse, and on top of that all, it calibrated, i took time and made a video showing the bands with %100 Delphi code and it with full spectrum, also VCP comes with full multithread handling, so 0 work from you side on that, from the video i expected you go and just replace or just play with TunadspFFTControl, and see were and how it does the drawing and you will have you data (sorry i mean pixels)


Sorry again if i sound like retarded but i really tried to help and seeing all that wrong approach in one post is .... well trying to help last time.

One last thing on how to do it
that call back should only push the data in a buffer, this buffer will be FIFO (first in first out) and all you need is one thread (only one) check when there is data at specific count to perform the needed FFT width, and perform the DFT then process the pixels then push them into another FIFO buffer, and that is it !!..
you need a timer to copy the pixel to an image or simply redraw the image if you are putting the pixels directly on the image.

Sorry one more time, and if the admin or anyone see this post is offending or violate a policy then please delete it.
Kas
  Mit Zitat antworten Zitat
Antwort Antwort

 

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 03:09 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