![]() |
Rechnerauslastung
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:
Danke für die Hilfe und Gruß
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; Jürgen |
AW: Rechnerauslastung
.. 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 |
AW: Rechnerauslastung
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. |
AW: Rechnerauslastung
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 |
AW: Rechnerauslastung
Zitat:
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. |
AW: Rechnerauslastung
Zitat:
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. |
AW: Rechnerauslastung
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. |
AW: Rechnerauslastung
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:
That is wrong. Zitat:
That is wrong. Zitat:
That is wrong on every imaginable level. Zitat:
That is wrong. Zitat:
Zitat:
Zitat:
Zitat:
Code:
This callback doesn't make sense and wrong, let me break it for you:
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 ; 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 ![]() 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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz