Ich schreibe eine weiche Echtzeitanwendung in C #. Bestimmte Aufgaben, wie das Beantworten von Hardwareanfragen, die von einem Netzwerk eingehen, müssen innerhalb einer bestimmten Anzahl von Millisekunden abgeschlossen sein. Dies ist jedoch nicht zu 100% geschäftskritisch (dh wir können es tolerieren, dass es die meiste Zeit pünktlich ist, und 1% ist unerwünscht, aber kein Fehler), daher der "weiche" Teil.
Jetzt ist mir klar, dass C # eine verwaltete Sprache ist und verwaltete Sprachen nicht besonders für Echtzeitanwendungen geeignet sind. Die Geschwindigkeit, mit der wir Dinge in C # erledigen können, sowie die Sprachfunktionen wie Reflexion und Speicherverwaltung erleichtern die Erstellung dieser Anwendung jedoch erheblich.
Gibt es Optimierungen oder Entwurfsstrategien, mit denen der Overhead reduziert und der Determinismus erhöht werden kann? Idealerweise hätte ich folgende Ziele
- Verzögern Sie die Speicherbereinigung, bis sie "sicher" ist.
- Lassen Sie den Garbage Collector arbeiten, ohne die Echtzeitprozesse zu beeinträchtigen
- Thread- / Prozessprioritäten für verschiedene Aufgaben
Gibt es Möglichkeiten, dies in C # zu tun, und gibt es andere Dinge, auf die Sie in Bezug auf Echtzeit bei der Verwendung von C # achten müssen?
Das Plattformziel für die Anwendung ist .NET 4.0-Clientprofil unter Windows 7 64-Bit mit. Ich habe es derzeit auf Client-Profil eingestellt, aber dies war nur die Standardoption und wurde aus einem bestimmten Grund nicht ausgewählt.
quelle
Antworten:
Die Optimierung, die Ihre ersten beiden Aufzählungszeichen erfüllt, wird als Objektpool bezeichnet . Es funktioniert von
Sie können ein Beispiel Klasse finden , die ein Objekt Pool mit einem implementiert
ConcurrentBag
hier .Die Thread- / Prozesspriorität kann einfach zur Laufzeit festgelegt werden. Die Thread-Klasse verfügt über Methoden und Eigenschaften, mit denen Sie Priorität und Prozessoraffinität festlegen können. Die Prozessklasse enthält ähnliche Funktionen.
quelle
Sie können dies tun, indem Sie den GC-Latenzmodus auf einstellen
LowLatency
. Weitere Informationen finden Sie in dieser Antwort auf SO .quelle
Gehen Sie genauso vor wie bei der Spieleentwicklung in einer verwalteten Umgebung und versuchen Sie, die Objekterstellung / den Tod auf ein absolutes Minimum zu reduzieren.
Versuchen Sie beispielsweise, alle Objekte zu erstellen, die zu Beginn wahrscheinlich benötigt werden, und bündeln Sie sie zwanghaft. Gehen Sie nach Möglichkeit an ref vorbei und vermeiden Sie Operationen, die kurzfristige Zwischenobjekte erstellen
quelle
Beachten Sie, dass die Zielumgebung (Windows) ein vorbeugendes Multitasking-Betriebssystem ist. Mit anderen Worten, Ihr weicher Echtzeitprozess wird zwangsläufig irgendwann vorweggenommen, was neben der .NET-Speicherbereinigung auch andere Latenzen zur Folge hat. Sie können dies verringern, indem Sie den Zeitscheibenwert (Quantenwert) reduzieren (Standard ist etwa 16 ms) und die Priorität Ihres Prozesses erhöhen (es gibt jedoch praktische Grenzen). Es werden jedoch / müssen immer noch Vorkehrungen getroffen werden, da andere wichtige Prozesse noch erforderlich sind Sachen machen. All dies hat nichts mit Programmiersprache zu tun; Es ist grundlegend für das O / S.
Abgesehen von GC-Problemen kann Ihre Anwendung, die auf einem sofort einsatzbereiten Windows-Computer ausgeführt wird, wahrscheinlich die meiste Zeit Latenzen von einigen Millisekunden liefern. Es kann sicherlich nicht 100% der Zeit garantiert werden, oder irgendetwas in der Nähe. Selbst bei der Abstimmung (kurzes Quantum, hohe Priorität) treten gelegentlich hohe Latenzen auf. Es ist die Natur des Tieres.
Fazit: Wenn Sie garantierte Antwortzeiten benötigen, insbesondere in der Größenordnung von wenigen Millisekunden, ist Windows wahrscheinlich nicht die beste Wahl für die Zustellung.
quelle