Source Code mit Nutzung con Com-Objejten deutlich langsmer im Thread

  • VB.NET
  • .NET (FX) 4.0

Es gibt 96 Antworten in diesem Thema. Der letzte Beitrag () ist von Tukuan.

    kann man bestimmt was parallelisieren, aber vorrangig wäre glaub mal CalculateFFT() anzugugge, ob da nicht iwelche Performance-Böcke geschossen sind.

    Auch fragwürdig, ob für jeden ChannelName dasselbe SourceFile immer wieder neu geöffnet und geclosed wern muss.
    Aber habich richtig verstanden, dass 6 ChannelNames existieren?
    ich versteh nicht, warum alle das Problem mit STA und MTA ignorieren, @hal2000 hats doch extra geschrieben
    einfach mal einen STA-Thread erstellen und darin ausführen lassen, dann solltest im Prinzip dasselbe haben wie in der GUI, nur dass die GUI nicht einfriert:
    msdn.microsoft.com/de-de/libra…tmentstate(v=vs.110).aspx
    Danach kann man nach sonstigen Optimierungen gucken(Wie z.B. das selbst implementieren der FFT dürfte genügend SourceCodes dazu geben)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Ignorieren ist in meim Fall nicht ganz richtig. Ich kann halt garnix zu sagen, deshalb sag ich nix dazu. Aber ich würd bestimmt drauf zurückkommen, wenn sich Probleme auftun.
    Man kann nicht alles gleichzeitig machen, und Nebenläufigkeit gehört zu dem letzten, was anzufassen ist, und ich wäre noch dabei, zu gucken, ob durch einfach saubereres coden was verbessert werden kann.
    Messung per Consol-Ausgabe mit Stopwatch Zeiten
    Berechnung aufgerufen durch
    Zeit in ms
    Start from GUI - Run 1
    143805
    Start from GUI - Run 2
    139227
    Start from Thread - highest priority
    195576
    Start from Thread - normal
    187563
    Start from Thread - lowest priority
    189448
    Ich habe noch mal die Berechnung aus der GUI und per Thread mit den jeweiligen Prioritäten durchführen lassen. Diese hat (in diesem Fall) keinen Einfluss auf die Rechenzeit.
    Ist die Prozedur

    Tukuan schrieb:

    CalculateFFT()
    Dein Code oder nutzt Du sie nur?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Die sieht so aus...

    VB.NET-Quellcode

    1. Private Function CalculateFFT(ByVal MyFamos As ImcFamosLib.Famos,
    2. ByVal RawChannel As ImcCoreLib.DChannel,
    3. ByVal deltaT As Double,
    4. ByVal Samples As Integer) As ImcCoreLib.DChannel
    5. Dim xDelta As Double = 1 / (Samples / deltaT)
    6. Dim Famos_Uref As New ImcCoreLib.DChannel
    7. Dim Famos_Channel As New ImcCoreLib.DChannel
    8. Famos_Uref = MyFamos.Edit.Ramp(0, xDelta, Samples)
    9. Famos_Channel = MyFamos.Misc.IPol3(RawChannel, 1)
    10. Famos_Channel = MyFamos.Misc.ResampleRef(Famos_Channel, Famos_Uref)
    11. Famos_Channel = MyFamos.Spec.FFTa(Famos_Channel)
    12. Return Famos_Channel 'MyFamos.Spec.FFTa(Famos_Channel)
    13. End Function
    hat sicher keine Auswirkung auf die Performance, wohl aber auf die Resourcen:

    VB.NET-Quellcode

    1. Private Function CalculateFFT(ByVal MyFamos As ImcFamosLib.Famos,
    2. ByVal RawChannel As ImcCoreLib.DChannel,
    3. ByVal deltaT As Double,
    4. ByVal Samples As Integer) As ImcCoreLib.DChannel
    5. Dim xDelta As Double = deltaT / Samples
    6. Dim Famos_Uref = MyFamos.Edit.Ramp(0, xDelta, Samples)
    7. Dim Famos_Channel = MyFamos.Misc.IPol3(RawChannel, 1)
    8. Famos_Channel = MyFamos.Misc.ResampleRef(Famos_Channel, Famos_Uref)
    9. Return MyFamos.Spec.FFTa(Famos_Channel)
    10. End Function
    recherchiere mal, was das Schlüsselwort New in vb.net bedeutet, und warum es hier nix verloren hat.
    Vergleichbare New-Fehler finden sich auch im anneren Code.
    Auch ist die Resourcenbereinigung von Com-Objekten eine wissenschaftliche Wissenschaft. Bei dir entstehen (selbst bei Vermeidung üflüssiger News) tausende unaufgeräumter DChannel-Instanzen - evtl. wird das auch noch Ärger machen.

    Tukuan schrieb:

    VB.NET-Quellcode

    1. Famos_Channel = MyFamos.Misc.IPol3(RawChannel, 1)
    2. Famos_Channel = MyFamos.Misc.ResampleRef(Famos_Channel, Famos_Uref)
    3. Famos_Channel = MyFamos.Spec.FFTa(Famos_Channel)
    Ich suche die harten Rechen-Routinen, nur da kann man was machen, wo ein For oder ein For Each steht.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ErfinderDesRades schrieb:

    Vergleichbare New-Fehler finden sich auch im anneren Code.

    Ja, da hast du recht. Habe mich schon mal mit der Instanzierung von Objekten befasst. Da muss kein New hin. Muss wohl noch mal genauer durchgehen, wann ein New wirklich sein muss und wann nicht...
    Auch ist die Resourcenbereinigung von Com-Objekten eine wissenschaftliche Wissenschaft. Bei dir entstehen (selbst bei Vermeidung üflüssiger News) tausende unaufgeräumter DChannel-Instanzen - evtl. wird das auch noch Ärger machen.

    Kannst du mir einen Tip geben, wie man die wieder aufräumt?
    Auf

    VB.NET-Quellcode

    1. Nothing
    setzen?

    Ich suche die harten Rechen-Routinen, nur da kann man was machen, wo ein For oder ein For Each steht.

    Werde mir mal anschauen, was da am längsten dauert. Aber da die Ergebnisse aufeinander aufbauen, bringt eine parallelisierung hier wohl nichts...

    Messung mit STA/MSA:
    ### Start from Tread STA - Highest: 187314 - finished
    ### Start from Tread MTA - Highest: 180648 - finished

    Das hat also nichts gebracht.

    Tukuan schrieb:

    Aber da die Ergebnisse aufeinander aufbauen,
    muss das mit Sorgfalt organisiert werden.
    Ggf. muss das vollständig umgeschrieben werden.
    ---
    Irgendwo sehe ich da 5 FFTs unmittelbar nacheinander, das lässt sich wohl einfach parallelisieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    wann ein New da hin muss
    New heisst New, weil damit ein neues (engl: new) Objekt erstellt wird.

    VB.NET-Quellcode

    1. dim bla as new DChannel
    nun ist ein neues DChannel in der Variable bla angelegt.
    Was ühaupt keinen Sinn hat, denn als nächstes wird eine Function aufgerufen, die ein DChannel-Objekt zurückgibt:.

    VB.NET-Quellcode

    1. bla = MyFamos.Misc.IPol3(RawChannel, 1)
    Wo ist nu das DChannel-Objekt, was vorher in bla war?
    Richtig - es ist weg.
    Macht auch nix - hat eh niemand gebraucht.
    Warum aber dann erstmal erstellen mit New?
    Das mit einem STA-Thread wird wohl nicht funktionieren, da du die Objekte nicht in diesem erstellst, oder auch aus dem GUI Thread heraus verwendest(eins von beidem).
    Denn dann richtet .Net eine extra Schnittstelle ein um den Zugriff aus mehreren Threads zu ermöglichen. STA bedeutet ja eigt. dass nur Zugriff aus einem Thread heraus möglich ist. Wenn du nun versuchst aus mehreren drauf zuzugreifen haut .Net eine Schnittstelle dazwischen, welche MTA ist und wiederum synchron auf das STA-Com-Objekt zugreif, das kostet Zeit.

    Also stelle sicher, dass alles nur in diesem einen Thread passiert, was mit den COM-Objekten zu tun hat, angefangen bei der Erstellung/Zuweisung
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Eine andere Frage jedoch. Wie greifst du auf die COM-Objekte zu?


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „thefiloe“ ()

    Und noch eine andere Frage, die sich mir nach dem Lesen des ganzen Threads stellt: warum keinen neuen PC?
    Mal im Ernst, das ist scheinbar kein privates Projekt und wenn es zeitlich an der Verarbeitung etwas zu optimieren gibt, was richtig rein haut, dann erschlag doch das Problem mit einem schnellen PC !
    Das sollte Eurer Budget doch hergeben?
    Und genau das ist der Grund warum man für ein neues Spiel jedes Jahr nen neuen Rechner braucht, oder für 5 Jahre nen wahnsinnig teuren Rechner kaufen muss. Weil heutige Hardware gibt es ja her. Wenn jukt es da, ob man sehr viel mehr optimieren könnte(was denk ich in viele Fällen zu noch krasseren Spielen auf heutiger Hardware führen könnte)...
    Und warum hat man wohl die FourrierTransformation entwickelt, sicher nicht dass man nachher hingeht und alle möglicen Frequenzen versucht zu mischen, bis es mit dem Signal übereinstimmt, weil ein Supercomputer könnte das ja auch durchhauen :D
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    jvbsl schrieb:

    Und genau das ist der Grund warum man für ein neues Spiel jedes Jahr nen neuen Rechner braucht, oder für 5 Jahre nen wahnsinnig teuren Rechner kaufen muss.

    Ich glaube, hier liegt der Fall ein wenig anders.
    Der TE hat sündhaft teure Mess-Hardware und eine hoffnungslos veraltete Schnittstelle.
    Da bietet es sich m.M. nach an, über die auswertende Hardware nachzudenken.
    Wir sprechen hier von ein paar hundert Euros.
    Lässt sich der TE sein Optimierungsgrübeln auf Arbeit bezahlen, kommen wir auf ein paar tausend Euros mit weniger Aussicht auf den erwünschten Schub.

    Nunja klar kann man da mit neuer Hardware etwas ausrichten, aber wenn eine grundsätzliche Softwarefehlimplementation vorliegt, dann sollte das so oder so geregelt werden.
    Und von wegen weniger Aussicht auf erwünschten Schub? Der erwünschte Schub ist erstmal so schnell wie im GUI Thread, d.h. die Hardware ansich schafft das locker weg. Es ist somit eindeutig ein Softwareproblem
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Bevor ich irgendwelche Gedankenexperimente anstelle, was das Problem vielleicht sein könnte, suche ich das Problem. Das ist jetzt das wichtigste - die Lösung ergibt sich meistens von ganz alleine. Es ist bisher nicht bekannt, ob der Flaschenhals in der Komponente, bei deren Schnittstelle, bei der Ansteuerung oder im Benutzercode liegt. Wenn ein Algorithmus ineffizient ist, hilft auch kein neuer Rechner (selten so gelacht - sorry; Stichwort Laufzeitkomplexität).

    Visual Studio hat (nur in der Ultimate-Version?) einen Profiler. Der analysiert einen Programmdurchlauf und zeigt dann genau, wo es klemmt. Notfalls kann er für jede einzelne Zeile anzeigen, wie schnell oder langsam sie ausgeführt wurde (und oft auch warum).

    Vorschlag: Starte eine "Neue Leistungssitzung" in Visual Studio (Menü Analysieren --> Profiler) und lass das Programm einmal durchlaufen. Vergleiche den Bericht mit der "schnellen" Variante, die aber den GUI-Thread blockiert. Das eigentliche Problem sollte im Unterschied zwischen diesen beiden Berichten zu finden sein.
    Gruß
    hal2000

    simpelSoft schrieb:

    erschlag doch das Problem mit einem schnellen PC !
    Das sollte Eurer Budget doch hergeben?

    Das behebt doch nicht das Problem. Natürlich kann man die Berechnung in der Zeit durchführen, wenn man ordentlich Rechenpower hat. Aber das ist wie Korken unter Wasser duckern. Problem wech. Oh... doch wieder da. Und außerdem hat man vielleicht ja mal den Anspruch bzw. die Anforderung, das Projekt nachher auf einen low-Budget Rechner laufen zu lassen.

    jvbsl schrieb:

    Es ist somit eindeutig ein Softwareproblem

    Genau. Jemand hat's verstanden. Ich habe wohl irgendwie Designfehler mit dem Umgang von Com-Objekten gemacht.
    Leider habe ich das Tool:
    Vorschlag: Starte eine "Neue Leistungssitzung" in Visual Studio (Menü Analysieren --> Profiler)

    nicht.

    thefiloe schrieb:

    Wie greifst du auf die COM-Objekte zu?

    Verstehe die Frage nicht so ganz... Aber wenn ich mir die ganzen anderen Kommentate so anschaue (dafür übrigens ein GANZ GROSSES DANKE SCHÖN) liegt es wohl darin, dass ich auch von der GUI auf die Com-Schnittstelle zugreife.
    Versuche es mal zu beschreiben:
    Die Com-Schittstelle handelt zum einen das Dateimanagment mit dem Dateityp sowie die Rechenoperationen.
    Ab und an benötige ich "nur" kurz mal eine kleine Inforamtion (Anzahl der Datenpunkte in einer Datei). Also Öffne ich kurz ne Datei schaue nach und verwende das Benötigte. Das passiert dann dort wo ich es brauche - manchmal sicherlich auch durch die GUI.
    Wenn ich es richtig verstanden habe, ist somit der STA-Weg gar nicht mehr möglich - und zwar für ALLE weiteren Verwendungen der Com-Schittstelle.
    Falls das nicht stimmen sollte: Alle in den Sourcen verwendetet Objekte sind im Thread erstellt.

    @ Erfinder des Rades

    Das mit dem New habe ich verstanden

    VB.NET-Quellcode

    1. 'so nicht - ist nicht gut
    2. Dim FamosUref As New ImcCoreLib.DChannel
    3. FamosUref = MyFamos.Edit.Ramp(0, xDelta, Samples)
    4. 'sondern so - ist viel besser
    5. Dim FamosUref2 As ImcCoreLib.DChannel = MyFamos.Edit.Ramp(0, xDelta, Samples)

    Ich werde es umbauen - versprochen :)
    Aber wie räumt man richt auf?
    Das ist mir noch nicht klar. Soll ich die Objekte mit "Vernichten" Nothing?

    Da COM-Schnittstellen uralt sind und überhaupt nicht mehr verwendet werden: Was ist denn heute Stand der Technik? Ich muss mich mal mit dem Hersteller von der Software unterhalten.