![]() |
Schleife beschleunigen sinnvoll?
Um welchen factor könnte man diese Schleife beschleunigen?
Delphi-Quellcode:
eventuell über ASM und wenn dann wie, wenn es was bringt.
BASS_ChannelGetData(FChannelId, @SpectrumData, BASS_DATA_FFT2048 or BASS_DATA_FFT_INDIVIDUAL);
for i := 1 to 576 do begin p2^ := trunc(SpectrumData[i * 2] * FVisScale); inc(p2); end; Habe den eindruck als wenn BASS_ChannelGetData das ganze etwas ausbremst. gruss |
AW: Schleife beschleunigen sinnvoll?
Die FFT ist mit Sicherheit deutlich langsamer als die Schleife → Bringt nichts, die Schleife zu optimieren.
Ich glaube auch nicht, dass man da überhaupt viel optimieren könnte, außer vielleicht mit speziellen SSE-Befehlen in Assembler. Dann läuft die Schleife vielleicht 4x so schnell, aber das ganze Ding nur 1% schneller. Daher ist es den Aufwand, die höhere Komplexität und die schlechtere Lesbarkeit definitiv nicht wert. Generell hat es aber wenig Sinn, basierend auf Mutmaßungen optimieren zu wollen. Lad dir mal den ![]() |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Mein problem ist halt das bei C# Anwendungen die CPU last rapide in die höhe schnellt. Der einzige Ansatz der hier in frage käme wäre halt die optimierung der IF schleifen der FFT und WaveDaten. Seltsamer weise ist das wiedermal nur in .NET zu verzeichnen. Bei anderen Awnendungen Delphi > Delphi, VB > Delphi usw.. gibt es die probleme nicht. Ich muss halt nun feststellen was dieses problem verursacht meine DLL oder die NET Anwendung selbst. Werde mal testen was das mit dem SamplingProfiler auf sich hat. Danke. gruss |
AW: Schleife beschleunigen sinnvoll?
Zitat:
|
AW: Schleife beschleunigen sinnvoll?
Achso, der Code läuft in einer DLL, die von C# aus benutzt wird? Da kenne ich mich nicht mit aus... weiß auch nicht, ob man den SamplingProfiler da überhaupt benutzen kann, vermutlich nicht.
Aber wenn die Performance nur unter C# schlecht ist, dann wird es wohl kaum an dem Code selber liegen. Also wäre ein C#-Profiler wohl eh besser... |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Zitat:
Zitat:
gruss |
AW: Schleife beschleunigen sinnvoll?
Du könntest höchstens versuchen, den Faktor als Integer (z.b. iVisScale := trunc(FVisScale * 100)) zu setzen und in dem Zielbereich dann mit höheren Werten zu arbeiten. Dann müsstest Du allerdings die daraf basierenden Funktionen zur Weiterverarbeitung ebenfalls umstellen. Es würde dann in der Schleife jedenfalls kein trunc und keine Float-Multiplikation mehr auftauchen. Versuch aber auf jeden Fall zunächst die Laufzeit zu loggen. Es bringt gar nichts eine Funktion die nur 1% der Gesamt-Laufzeit verbaucht um 100% zu beschleunigen.
|
AW: Schleife beschleunigen sinnvoll?
Zitat:
Den anderen vorschlag werde ich mal versuchen sollte sich hier nichts ergeben. Danke. gruss |
AW: Schleife beschleunigen sinnvoll?
Wenn du ein C# Projekt da hast, kann ich für dich auch mal den Profiler drüber laufen lassen. (Den, der in VS2012 eingebaut ist)
Normalerweise ist aber eine unmanaged dll relativ performant bei dem Zeug was darin ausgeführt wird. Lediglich der Aufruf an sich hat etwas overhead. (Also lieber eine Funktion, die viele Parameter entgegen nimmt, als 5 Funktionen die alle nur einen haben) Weitere Ratschläge gibt's auch hier: ![]() |
AW: Schleife beschleunigen sinnvoll?
Wie gesagt die Delphi DLL wenn sie in einer Anwendung mit Delphi geschrieben verwendet wird
und ich anschließend Milk2 im Vollbild laufen lasse hab ich ne last von 7% maximal. Unter NET sind es gut 30%. Das will mir nicht in den kopf das nur hier die auslastung so hoch ist. Das projekt ist Mediaportal ist einfach zu groß um zu schicken ;) Ich hab den Profiler von 2012 drüber gejagt der mir aber nur da sagt was ich schon wußte bzw. die functionen aufgezeigt welche die last verursachen. gruss |
AW: Schleife beschleunigen sinnvoll?
sorry wenn ich nerve ..
Was sagt mir jetzt der Shot? Viel anfangen kann ich jetzt nicht damit. gruss |
AW: Schleife beschleunigen sinnvoll?
Das sagt Dir dass DirectX unter .NET langsam ist ;)
|
AW: Schleife beschleunigen sinnvoll?
Zitat:
Die mscorwks.dll verursacht das problem nur wie soll ich da was fixen wenn überhaupt. gruss |
AW: Schleife beschleunigen sinnvoll?
Das stimmt. Kann man im Profiler nicht einstellen, dass nur eigener Code beobachtet wird (Just my Code)? Du hast ja rechts oben "All Code".
|
AW: Schleife beschleunigen sinnvoll?
Zitat:
Allerdings wird die DLL bass_vis schon angezeigt mit 7,4 samples was auch immer das heist ;) gruss |
AW: Schleife beschleunigen sinnvoll?
Du kannst in den Profiler-Einstellungen definieren ob "Just my Code" aktiviert werden soll und soweit ich weiß auch die Aufruftiefe in von diesen aufgerufenen "Fremdfunktionen" die dann doch noch beachtet werden soll.
|
AW: Schleife beschleunigen sinnvoll?
Zitat:
Hmm also das Bild oben zeigt dir schon Just my Code :) Wenn ich auf den link klicke erst dann wird der ganze angezeigt. gruss |
AW: Schleife beschleunigen sinnvoll?
Bin jetzt mal anders an die Sache herangegangen.
Ich habe im Quelltext alle zugriffe auf meine DLL gesperrt so das kein Plugin gestartet wird bzw. irgendwelche Messagen an dieses gesendet werden kann. Jetzt habe ich festgestellt das der RenderThread innerhalb Mediaportal allein für die hohe CPU auslastung verantwortlich ist. Warum auch immer obwohl er ja jetzt eigentlich nichts mehr zu tun hat. Damit bin ich auf jedenfall sicher das es nichts mit meiner DLL zu tun hat. Aber grübeln tu ich immer noch warum so ein Thread eine so hohe auslastung verursacht. gruss |
AW: Schleife beschleunigen sinnvoll?
Ich weiss das sollte man nicht tun ..
Thread.Sleep(1) aber es wirkt wunder. CPU auslastung liegt nun im VollBild 1920x1200 3-5% wenn Milk2 visualisiert wird. Für den rest sollen die Developer von Mediaportal sich gedanken machen ob sie anstelle des Threads einen Timer verwenden um das Sleep zu umgehen. Auf jeden fall funktioniert es jetzt so wie es soll. gruss |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Das wollte ich vorhin auch fragen, ob du da womöglich ne Schleife while not Terminated ohne Pause drin hast. |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Nicht das ich dir nicht glauben würde.. aber es irritiert etwas wenn man mehrere meinungen von einem Thema erhält und jeder sagt was anderes. Na ja letztendlich funktioniert es so. Was die dann daraus machen lass ich mal dahin gestellt. Auf jedenfall konnte da was nicht stimmen das ein Thread einen Kern zu 100% auslastet. Immer wieder eine Freude anderen Quelltext zu debuggen nur um zu beweisen das es nicht an der eigenen Arbeit(Anwendung) liegt. Maulen können die alle ;) gruss |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Delphi-Quellcode:
und schau auf die CPU-Last.
repeat until true = false;
Delphi-Quellcode:
dürfte den gleichen Effekt haben. Zumindest aus meiner Erfahrung macht jede Schleife ohne ein ProcessMessages, Sleep oder dergleichen keine Pause bei 100% CPU-Last. Ist die CPU-Last in so einer Schleife kleiner, dann ist da eventuell irgendwo eine andere Routine im Aufruf, die doch mal ein Päuschen einlegt (warten auf die Festplatte, laden von Daten aus 'nem Stream von 'nem Server irgendwo im weiten Netz... Dem, der dies da in dem anderen Forum schrieb
while not Terminated
Zitat:
|
AW: Schleife beschleunigen sinnvoll?
Zitat:
Ich wußte halt nur nicht das Thread.Sleep lediglich eine Pause einlegt. Mann kann halt nicht jede Eigenart jeder Sprache kennen ;) gruss |
AW: Schleife beschleunigen sinnvoll?
Sleep im Hauptthread führt dazu, dass die GUI nicht mehr reagiert und sollte daher dort vermieden werden.
In separaten Threads jedoch möchte man ja genau, dass der Thread auch mal schläft. Und deshalb ist es dort auch sinnvoll. |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Zitat:
|
AW: Schleife beschleunigen sinnvoll?
Zitat:
|
AW: Schleife beschleunigen sinnvoll?
Zitat:
Obwohl der zu wartende Thread im grunde mit DirectX nichts am Hut hat. gruss |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Sleep nutzt intern schon das genauere ZwDelayExecution (zumindest unter Windows 8), so dass man bei einer Millisekunde auch nicht viel länger wartet. Um genau zu sein sind es bei mir ca. 0,9 ms pro Aufruf mehr als angegeben, egal ob ich eine Millisekunde angebe oder 100. WaitForSingleObjectEx ist da noch etwas genauer. Da wartet man bei einer Millisekunde Timeout nur 1,6 Millisekunden und bei 100 ms sind es 100,4 ms. Dafür muss man sich erst ein Handle erzeugen, auf das man warten kann. Und wenn man nur ein wenig verzögern will, ist der Unterschied nicht groß. Deshalb ist für mich der Aspekt Plattformunabhängigkeit wichtiger. Gemessen habe ich so:
Delphi-Quellcode:
Genauso mit Sleep und verschiedenen Zeiten.
uses
Diagnostics; var i: Integer; Watch: TStopwatch; Event: THandle; begin Event := CreateEvent(nil, False, False, nil); Watch := TStopwatch.StartNew; for i := 1 to 10000 do WaitForSingleObjectEx(Event, 1, True); ShowMessage(IntToStr(Watch.ElapsedMilliseconds)); CloseHandle(Event); |
AW: Schleife beschleunigen sinnvoll?
Ich meinte, dass man gezielt auf bestimmte Events warten sollte (z.B. „Neue Daten da“ oder „Frame abgeschlossen“), nicht, dass man WaitForSingleObjectEx als Ersatz für Sleep verwenden soll. WaitForSingleObjectEx war auch nur ein Beispiel; wie gesagt, bei 3D-Grafik-Schnittstellen gibt es ähnliche Prinzipien, und auch auf anderen Plattformen als Windows gibt es das, nur weiß ich nicht, wie die Funktionen dort heißen...
|
AW: Schleife beschleunigen sinnvoll?
In allen Threads, in denen ich das bisher benutzt habe, diente es nur dazu, dass nicht die CPU ausgelastet wurde. Da gab es schlicht nichts, auf das ich hätte warten können, da der Thread ja durchaus z.B. pollen sollte. Nur halt nicht so, dass die gesamte CPU Zeit benutzt wird.
Unabhängig davon kann man natürlich auch die Priorität senken um so nur freie Prozessorzeit zu konsumieren, aber das hilft nicht, wenn die Last den Takt erhöht und damit zu höherem Stromverbrauch insbesondere in Laptops führt. |
AW: Schleife beschleunigen sinnvoll?
Polling sollte – meiner Meinung nach – möglichst nur auf unterster Ebene geschehen, also etwa durch einen Treiber. Ausnahmen wären natürlich sowas wie „Server anpingen, um zu prüfen, ob er up ist“. Da tun es dann aber in der Regel auch große Intervalle von 1s und mehr. Das finde ich dann auch wieder in Ordnung, aber sleep(1) ist für mich ein starker Indikator für einen Designfehler. Ist gewissermaßen Symptonbekämpfung statt die Ursache zu beheben...
|
AW: Schleife beschleunigen sinnvoll?
Hmmm. Verstehe das Problem nicht so ganz.
Entweder habe ich verdammt viel zu rechnen und das soll schnell gehen und dann ist eine CPU zu 100% gerade gut genug. Oder ich kann mir Zeit lassen und will daher eine CPU nicht zu 100% auslasten. Dann rechne ich in Häppchen und lasse andere (Prozesse) auch zum Zuge kommen. Dann muss ich das dem OS aber (leider) sagen. Im Allgemeinen spielen viele Threads/Prozesse zusammen und müssen sich synchronisieren, ergo wird man dieses Problem in der Form nicht so oft haben. Und wenn doch, lässt es sich doch imho auf die eingangs genannten zwei Fälle reduzieren. @Namenlozer: Stichwort 'Eventuell Designfehler?' - ACK, mit der Betonung auf 'eventuell'. |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Schnittstellen zu anderen Programmen laufen auch teilweise nur so, dass man wartet bis eine bestimmte Datei beschreibbar ist oder vorhanden ist oder oder... Ob das gutes Design ist, sei mal dahingestellt, aber angebotene Schnittstellen kann man nun einmal nicht immer beeinflussen. Und ohne eine direkte Kommunikation der Programme gibt es auch nicht so viele Möglichkeiten. Eine Druckjobüberwachung funktioniert z.B. meines Wissens auch nur mit Pollen, zumindest habe ich noch keine Möglichkeit gefunden mich benachrichtigen zu lassen, wenn einer fertig ist. Und da gibt es noch viel mehr Gelegenheiten, bei denen du keine andere Möglichkeit hast als zu pollen. |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Aber selbst auf der niedrigsten Stufe bringt das nichts wenn die Schleife ohne unterbrechung läuft. Man muss halt nur die richtige position finden an der man den Thread schlafen legt wenn auch nur eine millisekunde.
Code:
geht!
VisualizationRunning = true;
ThreadStart renderTs = new ThreadStart(this.RunRenderThread); VizRenderThread = new Thread(renderTs); VizRenderThread.Priority = ThreadPriority.AboveNormal; //< Hat keinen einfluss auf die auslastung der CPU VizRenderThread.IsBackground = true; VizRenderThread.Name = "VizRenderer"; VizRenderThread.Start();
Code:
geht nicht!
if (VisualizationRunning)
{ using (Graphics g = Graphics.FromHwnd(Handle)) { // Fixed High CPU mistake Thread.Sleep(1);
Code:
if (VisualizationRunning) { // Fixed High CPU mistake Thread.Sleep(1); using (Graphics g = Graphics.FromHwnd(Handle)) { gruss |
AW: Schleife beschleunigen sinnvoll?
Die Threadpriorität hat natürlich keine Auswirkungen auf deinen Anwendungsfall, denn Du gibst (ohne das sleep) dem OS überhaupt keine Gelegenheit, andere zum Zuge kommen zu lassen. Threads sind kooperativ, d.h. sie müssen 'Bescheid' geben, wann und wo sie unterbrochen werden können. Offensichtlich trifft das auch auf den Prozess zu, obwohl ich dachte, das Windows hier präemptives Multitasking umsetzt.
Aber offensichtlich ist es so: Du und deine Freunde teilen sich eine Pizza. Du hast großen Hunger, also gibst Du dir eine hohe Priorität. Das funktioniert dann, wenn jeder sich reihum einen Haps nimmt (alle einen gleich großen), nur Du darfst jeweils einen großen Bissen nehmen. Logisch: Wenn sich alle eine hohe Priorität geben, ist der Effekt auch = 0. Und bahnbrechend ist der Effekt eh nicht, nur du bekommst eben ein wenig mehr (weil deine Freunde mitspielen und wenig abbeißen). Wenn Du allerdings die Pizza nicht mehr aus der Hand gibst, ist es irrelevant, ob Du eine hohe oder sehr niedrige Priorität hast, weil ja dann das verabredete Prozedere (jeder reihum abbeißen) nicht eingehalten wird. Du ißt sie also ganz alleine auf. Entweder mit kleinen Bissen (niedrige Priorität) oder mit Riesenhapsen (hohe Priorität). Da wir nicht wissen, was Großartiges mit dem 'Graphics g' anstellst, kann man da auch nicht weiter ansetzen. Ach: Wieso ist das eigentlich ein 'high CPU mistake'? Wenn schon ein 'mistake', dann eher von Dir bzw. dem Design. Der Thread rennt endlos ohne Pause und rendert irgend etwas? Was rendert er? Wann ändert sich etwas bei der Darstellung? Reicht es nicht, das Rendern nur dann anzuwerfen, wenn es etwas *Neues* zu rendern gibt, d.h. wenn sich der Output ändern wird? Reicht es nicht, nur z.B. 20x pro Sekunde zu Rendern? |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Er schickt also die aktuelle position im Stream das StreamHandle die gebufferten Wasapi Samples etwaige änderungen der Bildgröße usw... Alle 20x pro Sek. reicht da bei weitem nicht aus schließlich will ich nicht mit 10Frames in der sekunde rendern. Das sollte schon in realzeit geschehen. Denn ein Beaterkennung die 5 Sekunden später auftritt als sie eigentlich sollte ist sinnlos. Ist also nicht nur eine frage des Gehörs sondern auch der Augen. Ist wie mit deiner Pizza! Man isst nicht nur sondern schmeckt auch noch. Zitat:
Ah jo mein englisch ist halt unter der Gürtellinie hätte auch schreiben können 'high CPU Usage' wenn es dir mehr zusagt. Zitat:
Man hätte hier nicht sleepMS definieren sollen sondern damit den Thread warten lassen.. Warum nicht anstelle von
Code:
int sleepMS = RenderVisualization(g);
Code:
Somit hätte man auch den crash entgegenwirken können wenn beim beenden der Anwendung
Thread.Sleep(RenderVisualization(g));
die Form nicht mehr existiert und dann versucht 'g' zu initialisieren. aber das darf jetzt nicht mehr mein problem sein. gruss |
AW: Schleife beschleunigen sinnvoll?
Zitat:
Solange man aber nicht kurz wartet und einfach nur alles nimmt was man bekommen kann, wird die CPU auch ausgelastet solange niemand anderes sie braucht. |
AW: Schleife beschleunigen sinnvoll?
Gibt es nicht doch noch ne bessere alternative als Tread.Sleep(1)
Man mag es nicht glauben aber selbst die 1 Millisekunde blockiert schon das rendern. Also für C#.. wenn da jemand was hat wüde mich das freun ;) gruss |
AW: Schleife beschleunigen sinnvoll?
Zitat:
|
AW: Schleife beschleunigen sinnvoll?
Zitat:
Ich glaube das ich für das problem einen Multimediatimer benötige da dieser auch im nano bereich arbeitet. Die 1 Millisekunde ist einfach noch zu viel. Beim Thread ohne Pause ist es zu schnell so das andere prozesse dadurch behindert werden. Aber diese geschwindigkeit wäre korrekt wenn das blockieren nicht wäre. Das ist mein problem ;) gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 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