Performance Managed-Code Homogener Datenfluss



  • Durch den GC verursachte Ruckler bei der Datenübertragung gibt es heute eigentlich nicht mehr. Ich vergleiche seit über 10 Jahren die .net und C++ Varianten von diversen Protokollen auf unseren Industrie-PCs. Das war mal zu Zeiten von .net 1.x so. Unter 2.x war es schon fast nicht mehr da und seit 3.x ist im Zeitverhalten kein Unterschied zu sehen.

    Die .net Varianten brauchen minimal (einstelliger Prozentbereich) mehr CPU-Zeit. Nur der Speicherververbrauch der managed Varianten ist signifikant größer, weil sich .net da immer etwas vorhält.



  • Ja 2Mb/s ist jetzt vll. nich sehr viel... da habt ihr recht Es ginge ehr darum, die 2 Mb Banbreite auf Dauer über mehrere Stunden Konstant zu gewährleisten.

    Der Bekannte ist da eben etwas, old-school unterwegs, und arbeitet viel mit mircocontroller und auch auf alten C++ standarts in der desktopanwendungs entwicklung!

    Ich hätte Ihn nur mal gern überzeugen wollen, dass es mit .NET oder Java gehen müsste.

    Wollte hier aber gern nochmal Meinungen einholen;)

    Danke;) 😃



  • @nn
    Dass aus deinen Aufzeichnungen kein Unterschied erkennbar ist glaube ich dir. Das sagt nur nicht sonderlich viel. Es sagt nur dass es bei deinen/euren Anwendungen keinen relevanten Unterschied gibt.
    Daher wäre es interessant zu wissen ab welchem Delay bei diesen Anwendungen ein Unterschied auffallen würde.
    (Und natürlich wie viel RAM eure Prozesse brauchen.)

    @NullBockException
    Was man machen kann:
    * Die Anwendung auf geringen Speicherverbrauch optimieren. Je weniger Speicher die Anwendung braucht, desto schneller läuft eine Collection.
    * Wenige grössere Objekte (z.B. Arrays) gegenüber vielen kleinen Objekten vorziehen. Denn je mehr (nicht-Garbage) Objekte es gibt, desto länger braucht eine Collection.
    * Allokationen vermeiden (=Objekte recyclen). Denn je mehr Objekte neu erzeugt werden, desto öfter werden Collections gemacht.
    * Die .NET Framework 4.5 Runtime verwenden. Ab .NET 4.5 machen sowohl der workstation GC als auch der server GC "concurrent collections", was die Zeit für die alle Threads angehalten werden stark verkürzt.

    ----

    Die Frage ist, wie SeppJ und cooky451 schon geschrieben haben, wie lange die Aussetzer maximal sein dürfen, bevor das Programm ein Problem bekommt. Wenn pro Sekunde 1000 Werte reinkommen, und jeder muss sofort angenommen werden, dann hast du wohl überhaupt nur mit einem eigenen Treiber eine Chance. Wenn aber pro Sekunde 1000 Werte reinkommen, und es gibt bereits (von der Hardware oder von einem Treiber) einen Puffer der z.B. 100 solcher Werte halten kann, dann wirst du vermutlich auch mit C# kein Problem bekommen.
    Es sei denn du müsstest die Werte verarbeiten und innerhalb einer bestimmten Zeit wieder rausschicken.

    ps:
    Hier ein Artikel zu dem Thema
    http://blogs.msdn.com/b/dotnet/archive/2012/07/20/the-net-framework-4-5-includes-new-garbage-collector-enhancements-for-client-and-server-apps.aspx
    Interessant finde ich dabei dass hier Zahlen im Bereich 0,5 bis viele Sekunden erwähnt werden wenn es um Applikationen mit hohem Speicherverbrauch geht. Man sollte sich also keinesfalls darauf verlassen dass es "eh kein Problem machen wird", sondern auf jeden Fall darauf achten dass die Applikation möglichst wenig Speicher braucht.

    pps:
    Hier noch ein interessanter Artikel zu dem Thema:
    http://mattwarren.org/2014/06/18/measuring-the-impact-of-the-net-garbage-collector/



  • hustbaer schrieb:

    @nn
    Dass aus deinen Aufzeichnungen kein Unterschied erkennbar ist glaube ich dir. Das sagt nur nicht sonderlich viel. Es sagt nur dass es bei deinen/euren Anwendungen keinen relevanten Unterschied gibt.

    Das ist richtig. Die Tests sind aber schon soweit heruntergebrochen, dass nur das Einlesen der Daten und der Handshake mit der Quelle berücksichtigt werden.

    Daraus kann man schon extrapolieren (und teilweise simulieren), dass bei steigenden Datenraten, höherer Rechnerauslastung oder auf beschränkten Embedded Systemen die managed Variante früher in Schwierigkeiten käme.

    Aber sie zeigen auch, dass die Unterschiede auf dem Weg von .net 1.x bis 4.x deutlich kleiner geworden sind und für viele Anwendungsfälle keine Rolle mehr spielen.



  • Danke für die Infos und Links!

    Das "Echtzeit" Oszi, welche die letzen X Werte anzeigen soll, würde ich in WPF umsetzen, und ich denke da wird es schwierig, speicher zu sparen.. !?!?



  • NullBockException schrieb:

    Das "Echtzeit" Oszi, welche die letzen X Werte anzeigen soll, würde ich in WPF umsetzen, und ich denke da wird es schwierig, speicher zu sparen.. !?!?

    Wenn es nur um die Anzeige geht -- wo ist dann überhaupt das Problem?
    Dann gehen halt ab und an mal ein paar Samples verloren.

    Ansonsten kannst du natürlich auch die Anwendung in zwei Prozesse splitten: einen der die Daten erfasst und einen für die GUI. Der Prozess der die Datenerfassung macht kann dann entweder überhaupt gleich in C++ (oder einer anderen "unmanaged" Sprache) geschrieben sein, oder halt in C# mit möglichst geringem Speicherverbrauch und möglichst geringer Allokationsfrequenz.
    Den GUI Teil kannst du dann machen wie du magst. Die beiden Prozesse können dann z.B. einfach über TCP/IP miteinander kommunizieren.



  • nn schrieb:

    Daraus kann man schon extrapolieren (und teilweise simulieren), dass bei steigenden Datenraten, höherer Rechnerauslastung oder auf beschränkten Embedded Systemen die managed Variante früher in Schwierigkeiten käme.

    Ja, damit kann ich mich schon eher anfreunden als mit dem (mMn. viel zu optimistischen, und viel zu absolut formulierten) "durch den GC verursachte Ruckler bei der Datenübertragung gibt es heute eigentlich nicht mehr" 😉



  • das hat eigentlich nicht soviel mit der datenmenge zu tun, ob 2MB oder 200MB ist gleich, wenn die allokationsanzahl und deren verhaeltnis gleich ist. was der GC verursacht haengt dann auch eher davon ab wieviele allokationen vorhanden sind und wie die verteil sind und auf welche weise der GC die wie oft aufloest.

    Kumpel von mir der mit Java server bastelt meinte zu mir, dass sie ein einmal aufgesetztes system fast nie mehr updaten, weil auch eine verbesserte VM eigenschaften haben kann die der kunde dann als stoerend erkennt. die 100 anderen verbesserungen werden hingegen nicht bzw kaum wahrgenommen, nur wenn irgendwo lags auftauchen oder sowas. (was natuerlich schlecht ist weil auch sicherheitsfixes nicht mehr fuer 5jahre alte JVM gebracht werden). Und da die VM bzw der GC eine blackbox sind und falls etwas verschlimmbessert wird, haben die keinen einfluss auf das interna der blackbox.

    ich denke das ist also eher ein quality of service und kein "ist die GC gut genug". die frage ist dann "kannst du garantieren dass die GC nie stoert und dass falls es probleme gibt damit du alle selbst loest ohne mit den schultern zucken zu muessen weil es 'nicht deine schuld' ist?"

    dasselbe argument gibt es auch bei realtime OS, die sind nicht schneller oder besser oder ...
    sie garantieren dir nur gewisses verhalten, wenn nicht, dann ist es ein bug und wird gefixt. deswegen kannst du eine VM nutzen um simkarten zu betreiben und wenn dann etwas schiefgeht zucken ein paar leute mit den schultern, schieben den schwarzen peter hin und her, nehmen ein anderes system und fertig. fuer ein airbag system wird hingegen wohl kaum jemand dasselbe minimalistische VM'chen nehmen, obwohl es theoretisch ginge.

    die frage ist also nicht wieviel MB, sondern wie wichtig ist es dass diese daten stabil transferiert werden. Stirbt jemand? verliert man einmalige erkenntnisse? bricht ein video ab?



  • hustbaer schrieb:

    mMn. viel zu optimistischen, und viel zu absolut formulierten

    Ja, es ist etwas zu absolut formuliert. Allerdings ist es in der Tat so, dass z.B. das ständige Anlegen neuer structs beim Einlesen von Binärdaten (mit Marshal.PtrToStructure) früher eine typische Quelle von Rucklern war.

    Heute sehe ich z.B. Beispielprogramme für Laserscanner, die Daten über Gigabit Ethernet liefern, die PtrToStructure mit einer irren Frequenz aufrufen. Und da ruckelt nichts mehr



  • Doch doch, das ruckelt schon noch. Nur halt weniger. Wenn der managed heap mal gross genug wird dann merkt man das auch immer noch.



  • Glaube ich Dir. Deswegen bleiben wir bei sowas auch bei C++.

    Aber die mehrere Sekunden dauernden Aussetzer, bei Konsolenanwendungen, die laut Taskmanager 20 MB belegen, die sind mittlerweile weg.


Anmelden zum Antworten