Performance-Optimierung
Auf dieser Seite zeigen wir Ihnen, wie Sie ein Linux-basiertes CODESYS Control SL-Produkt für Ihr Gerät und Ihre Anwendung einrichten, damit Sie die bestmögliche Leistung erzielen.
Wir geben Ihnen Werkzeuge an die Hand, mit denen Sie den aktuellen Status Ihres Systems überprüfen und bewerten können.
Wir empfehlen nachfolgende Vorgehensweise. Arbeiten Sie diese Schritte in der vorgegebenen Reihenfolge ab. Es ist nicht sinnvoll, zum nächsten Schritt überzugehen, wenn der aktuelle nicht so optimiert ist, wie es nötig wäre.
Wichtig
Überprüfen Sie nach jedem Schritt, ob die zuletzt durchgeführte Änderung die Optimierungen der vorherigen Schritte negativ beeinflusst hat.
Wenn Sie die gewünschte Performance unter normaler Last erreicht haben, können Sie optional einen Test unter hoher Last mit stress-ng oder iperf durchführen.
Sie finden weiterführende Informationen auf folgenden Internetseiten:
Überprüfen der Hardware
Verwenden Sie keine gemeinsamen Caches für die Prozessorkerne Ihrer Steuerung.
Verwenden Sie für Ihr Zielgerät einen physikalischen Adapter für Ethernet-basierte Feldbusse, wenn Sie diese einsetzen. Verwenden Sie keine Switch-Architektur.
Einrichten von Linux
Verwenden Sie einen Echtzeit-Kernel.
Wichtig
Verwenden Sie für den Echtzeitbetrieb unter Linux den Realtime-PREEMPT-Patch. Der Einsatz eines Low-Latency-Kernels reicht nicht aus, da dieser keine deterministischen Echtzeiteigenschaften gewährleistet.
Für weitere Informationen siehe:
Viele der folgenden Systemeinstellungen können auch direkt mit der PLCShell über das Laufzeitsystem oder direkt über die Konfigurationsdatei des Laufzeitsystems eingestellt werden. Einige der Systemeinstellungen werden nicht über einen Systemneustart persistieren. Durch die Eintragungen der Einstellungen in die Konfigurationsdatei werden die Einstellungen mit dem Start des Laufzeitsystems automatisch wieder eingestellt. Das Absetzten des entsprechenden PLCShell-Kommandos fügt ebenfalls die jeweiligen Einträge der Konfigurationsdatei hinzu.
PLCShell-Kommando
Konfigurationsdateieintrag
Funktion
rt-get scaling_governor/kernelinfo/hyperthreading/throttling/napi <device>Gibt Informationen über die Einstellungen des Systems zurück
Beispiel 3. Beispielrt-get scaling_governorZeigt verfügbare scaling governor an und gibt den für den Kern konfigurierten scaling governor zurück
rt-set scaling_governor <cpu_index> <value>[CmpLinuxRTDiag] ScalingGovernor.CPU0=performance
Setzt den scaling_governor für bestimmte oder alle Kerne auf die angegebene Option
Beispiel 4. Beispielset scaling_governor all performancert-set hyperthreading <state>[CmpLinuxRTDiag] Hyperthreading=off
Schaltet Hyperthreading an oder aus
rt-set throttling <state>[CmpLinuxRTDiag] Throttling=off
Schaltet Throttling an oder aus
rt-set napi <device> <state>[CmpLinuxRTDiag] Napi=eno1
Schaltet threaded Napi für den Netzwerkadapter ein oder aus
rt-clear-settingsLöscht alle
rt-set-Einstellungen aus der Konfigurationsdateirt-marker-set <taskname> <threshold>[CmpLinuxRTDiag] TraceMarker.TaskName=MainTask TraceMarker.ThresholdUs=100 [SysTask] Linux.MeasureInterval=1
Schaltet ein, dass ein Kerneltracemarker für den spezifizierten Task geschrieben wird, wenn der Jitter über der angegebenen Grenze liegt.
Nur verfügbar, wenn das Runtime als root-User ausgeführt wird
rt-marker-disableSchaltet den Kerneltracemarker aus
rt-marker-getGibt den für den Kerneltracemarker konfigurierten Tasknamen und die Jittergrenze an
irq-listListet alle verfügbaren IRQs, deren Prioritäten und Affinität auf dem System auf
irq-set-prio <no | device> <priority>[CmpLinuxInterrupt] Interrupt.1.Priority=51 Interrupt.1.Device=eno1
Setzt die Priorität der entweder über Nummer <no> oder Gerät <device> spezifizierten Interrupts auf den gewünschten Wert.
irq-set-affinity <no | device> <bitmask>[CmpLinuxInterrupt] Interrupt.1.Affinity=128 Interrupt.1.Device=eno1
Setzt die Kernaffinität von des entweder über Nummer <no> oder Gerät <device> spezifizierten Interrupts auf die gewünschte Bitmaske
irq-clear-settingsLöscht alle
irq-set-Einstellungen aus der Konfigurationsdatei.Bei Echtzeitanforderungen ist die Verwendung des RT-Preempt-Kernels (https://wiki.linuxfoundation.org/realtime/documentation/start) für Ihr Linux-System erforderlich. Bei Debian- / Ubuntu-Distributionen finden Sie einen RT-Kernel als Package, das Sie einfach über
aptinstallieren können. Details dazu finden Sie im Handbuch Ihrer Distribution.Auf Debian-Systemen
sudo apt-get install linux-image-rt-amd64Überprüfen Sie, welchen Kernel Sie verwenden, beispielsweise mit dem Befehl
uname -a.
Vermeiden Sie die Verwendung eines Windows-Managers, GUI/X-Servers oder Ähnliches auf Ihrem System.
Die Verwendung der genannten Tools wird die Echtzeitfähigkeiten Ihres Systems beeinträchtigen, was zu einem hohen Jitter bei der IEC-Anwendung führt.
Test
Verwendung von "rt-tools":
Installieren von "rt-tools" :
sudo apt install rt-testsStarten von "cyclictest" :
sudo cyclictest -p 99 -t -mDer Befehl
man cyclictestzeigt Ihnen weitere Kommandozeilenoptionen, mit denen Sie mehr oder bestimmte Leistungsaspekte Ihres Systems besser messen können.
Ob der mit cyclictest ermittelte Wert als "gut" angesehen werden kann, hängt von Ihrer Hardware ab. Wenn Sie einen sehr starken Prozessor einsetzen (beispielsweise Intel Core i7), sollten Sie eine niedrige 1-stellige Zahl als Maximum haben. Wenn Sie einen alten ARM-Prozessor einsetzen, könnte 100 ein gutes Ergebnis sein.
Optimierungsmöglichkeiten
Wichtig
Nach dem Verändern jeder Einstellung oder Kombination von Einstellungen sollten Sie das Programm cyclictest ausführen, um die Effektivität der Änderungen zu verifizieren.
Diese Einstellungen sind nicht persistiert und müssen deshalb nach einem Systemstart/Reboot neu gesetzt werden.
Hinweis
Ab Version 4.21.0.0 bietet CODESYS einen SPS-Shell-Befehl an, mit dem die meisten dieser Werte direkt ausgegeben werden. Führen Sie hierzu den Befehl system-creatertreport aus. Um mehr Details zu dem Befehl zu sehen, führen Sie system-creatertreport ? aus.
Deaktivieren Sie den CPU-Energiesparmodus.
Deaktivieren Sie Hyperthreading.
Sie können das Hyperthreading beispielsweise mit folgendem Befehl deaktivieren:
echo off | sudo tee /sys/devices/system/cpu/smt/controlDeaktivieren Sie CPU-Frequenzskalierung und -Umschaltung so weit wie möglich.
Setzen Sie beispielsweise die minimale und maximale CPU-Frequenz auf denselben (festen) Wert.
Deaktivieren Sie den RealTime-Throttling-Mechanismus des Linux-Kernels, da dieser zu Jitter auf Ihrem System führen kann.
Für weitere Informationen siehe: The Linux Foundation: Scheduling - RT Throttling
Sie können das RealTime-Throttling beispielsweise mit folgendem Befehl deaktivieren:
echo -1 > /proc/sys/kernel/sched_rt_runtime_usPrüfen und ändern Sie den Scheduling/Scaling Governor.
Prüfen des verwendeten Scheduling/Scaling Governor:
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
Ändern des verwendeten Scheduling/Scaling Governors (als
root/admin) aufPerformance:echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor # set it for all available cores: echo "performance" > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor echo "performance" > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor echo "performance" > /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor
Beachten Sie, dass der Scaling Governor nach jedem Systemstart neu gesetzt werden muss. Sie können ihn auch über die Kernelkonfiguration setzen.
Der Kerneltreiber
intel_pstatekann die korrekte Einstellung erschweren. Überprüfen Sie deshalb Ihre Konfiguration mit dem Befehlcpufreq-info.Sie können auch Programme wie
cpu-freq-utilsverwenden. Dies könnte mit den Intel-Pstate-Treibern interferieren. Diese Treiber benötigen normalerweise einen anderen Ansatz, um die CPU-Frequenz festzulegen.Für weitere Informationen siehe https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt
Deaktivieren Sie im Bios
HyperV, falls verfügbar.
Konfigurieren des CODESYS-Laufzeitsystems
Erstellen Sie eine Testapplikation, die in etwa die Applikation beschreibt, für die Sie Ihr System optimieren möchten (in Bezug auf benötigte Ressourcen, erforderliche Leistung und Projektgröße).
Sie können dies iterativ tun: Erstellen Sie zunächst eine sehr grobe Annäherung und erweitern Sie diese dann, um der tatsächlichen Applikation immer näher zu kommen.
Test
Wenn die Applikation läuft, überprüfen Sie die Taskkonfiguration. Öffnen Sie die Taskkonfiguration und wählen Sie die Registerkarte Monitor.

Min. Jitter (µs) / Max. Jitter (µs)
Die Werte sollten so nah wie möglich an den Werten liegen, die durch das Programm "cycletest" ermittelt wurden. Details dazu sind im Abschnitt Einrichten von Linux beschrieben.
Für weitere Informationen bezüglich Jitter und Latenz siehe: Definitionen Jitter, Latenz
Für weitere Informationen zur Registerkarte Überwachung siehe: Registerkarte: Überwachung
Durchschnittliche Zykluszeit (µs) / Max. Zykluszeit (µs)
Der maximale Zyklus sollte nie in die Nähe der konfigurierten Zyklusdauer kommen. Dies führt zu Problemen, sobald das System eine hohe Last erfährt.
Halten Sie die Zykluszeit generell immer so niedrig wie möglich.
Optimierungsmöglichkeiten
Wichtig
Nach dem Verändern jeder Einstellung oder Kombination von Einstellungen sollten Sie das Programm cyclictest ausführen, um die Effektivität der Änderungen zu verifizieren.
Splitten Sie lang laufende Tasks in mehrere kleinere Tasks.
Während des Betriebs sollte die maximale Zykluszeit der höchstpriorisierten Task niemals die konfigurierte Zykluszeit erreichen. Wenn Sie dies nicht vermeiden können, sollten Sie die konfigurierte Zykluszeit erhöhen, um konsistente Ausführungszeiten zu gewährleisten.
Beim Start von Feldbussystemen (beispielsweise EtherCAT / PROFINET) kann es durch die Startzyklen zu einer etwas höheren CPU-Last kommen. Für diesen Fall ist es sinnvoll, die CPU-Last kurz nach dem Start der Applikation zu überwachen.
Die folgenden Optionen können nicht in CODESYS Virtual Control SL geändert werden, sondern müssen auf dem Host konfiguriert werden:
Setzen Sie den Wert für
DisableCpuDmaLatencyauf 1:[SysCpuHandling] Linux.DisableCpuDmaLatency=1
Beachten Sie, dass dies die Standardeinstellung ab Laufzeitversion 4.11.0.0 ist.
Sie können Ihre Laufzeitversion über den Befehl Extras → Linux aktualisieren → System → System-Info überprüfen.
Prüfen Sie, ob der Echtzeitkernel wirklich verwendet wird.
Ab Version 4.11.0.0 können Sie den SPS-Shell-Befehl
rt-get kernelinfoverwenden, um dies zu überprüfen.Wenn Sie eine ältere Version haben, können Sie dies direkt auf der Kommandozeile mit dem Befehl
uname -aprüfen.Wenn der Echtzeit-Kernel nicht verwendet wird, müssen Sie die Optimierung von Grund auf neu starten.
IEC-Application konfigurieren
Dieser Abschnitt bezieht sich auf Ihre eigentliche Applikation.
Test
Sie können die Tests aus dem vorherigen Schritt Konfigurieren des CODESYS-Laufzeitsystems verwenden, um Ihre IEC-Applikation zu testen.
Optimierungsmöglichkeiten
Wichtig
Nach dem Verändern jeder Einstellung oder Kombination von Einstellungen sollten Sie das Programm "cyclictest" ausführen um die Effektivität der Änderungen zu verifizieren.
Sie können das Multicore-Feature in CODESYS nutzen.
Legen Sie die richtigen Prioritäten für Ihre Tasks fest. Wichtige Tasks sollten eine höhere Priorität haben.
Tabelle 6. Zuordnung von IEC-Task-Prioritäten und Linux-Thread-Prioritäten:IEC-Taskpriorität
Runtime-Priorität
Linux-Priorität
--
0
88 (SCHED_FIFO)
--
31
57 (SCHED_FIFO)
0 (höchste Echtzeitpriorität)
32
56 (SCHED_FIFO)
15 (niedrigste Echtzeitpriorität)
47
41 (SCHED_FIFO)
16 (nicht Echtzeitpriorität)
48
0 (SCHED_OTHER)
31 (nicht Echtzeitpriorität)
63
0 (SCHED_OTHER)
--
64
0 (SCHED_OTHER)
--
255
(SCHED_IDLE)
Hinweis
Auf einem herkömmlichen Linuxsystem befinden sich die meisten Interrupts (IRQs) und Kernel-Worker auf Linux-Priorität 50. Das Verwenden von Prioritäten (mit hoher Last) oberhalb kann dazu führen, dass Systemfunktionen (Netzwerk/Speicher) nicht wie gewünscht funktionieren.
Sie können die Priorität einer Task in der jeweiligen Taskkonfiguration konfigurieren.

Wenn Sie nach allen hier genannten Schritten nicht die gewünschte Performance erreichen, können Sie einen Blick auf die folgenden Abschnitte werfen:
Feldbus-spezifische Informationen
Test
Überprüfen Sie die Werte
Send Time/Recv Timeauf der EtherCAT-StatusseiteEine x64 CPU mit einem Intel Core i7-Prozessor und einem guten Adapter sollte weniger als 10µs haben.
ARM-Prozessoren mit integriertem Chip werden ~50µs oder mehr haben.

Überprüfen Sie die Werte
Send Time/Recv Timeauf der PROFINET-Statusseite.Eine x64 CPU mit einem Intel Core i7-Prozessor und einem guten Adapter sollte weniger als 10µs haben.
ARM-Prozessoren mit integriertem Chip werden ~50µs oder mehr haben.

Optimierungsmöglichkeiten
Um Ihre Prioritäten und benötigten IRQs zu sortieren, können Sie die SPS-Shell-Befehle
irq-listundirq-set-prioverwenden.Diese Befehle verwenden die normalen Linux-Prioritäten und nicht die IEC-Prioritäten.
Diese Optimierung ist nicht in CODESYS Virtual Control SL möglich, sondern auf dem Host-System.
Verwenden Sie einen eigenen/separaten Netzwerkadapter für die Geräte.
Für weitere Informationen siehe:
[Für Experten] - Zusätzliche Tools und Themen
Die in diesem Abschnitt beschriebenen Tools und Optionen richten sich an fortgeschrittene Benutzer. Da die zu ergreifenden Maßnahmen stark vom jeweiligen System abhängen, sind eigene Nachforschungen erforderlich. Daher können wir Ihnen keine spezifischen Lösungen anbieten.
Kernelshark / Kernel-Trace
Wenn Sie feststellen, dass die Ursache für Ihre Performanceprobleme im Scheduling liegt, ist dies das Programm Ihrer Wahl. Mithilfe von „Kernel-Trace” können Sie überprüfen, ob Ihre Aufgabe durch eine andere Aufgabe, einen anderen Dienst oder einen Interrupt unterbrochen wird.
trace-cmd record -p functionSie können Kernelshark verwenden, um die erzeugte Datei
trace.datzu untersuchen.
Im Allgemeinen lassen sich die Probleme beim Scheduling in zwei Kategorien einteilen:
Supersession / preemption
Wenn der Interrupt oder die Task, die Ihre Ausführung verhindert, unnötig ist, deaktivieren Sie diese.
Erhöhen Sie die Priorität Ihrer Task oder verringern Sie die der anderen.
Wechseln Sie zu einem anderen CPU-Kern.
Wichtig
Überprüfen Sie die Wirksamkeit der Änderungen mithilfe der im vorigen Kapitel beschriebenen Programme.
Execution Time
Siehe nachfolgend "Kernel Function Trace"
Kernel Function Trace
Wenn die Ausführungszeit des Codes zu hoch ist, können Sie dieses Tool verwenden, um das Problem zu lokalisieren
Wenn die Funktion mit zu hoher Ausführungszeit in Ihrem eigenem Code liegt, müssen Sie ihn optimieren.
Wenn sich die Funktion mit zu hoher Ausführungszeit im Kernel befindet, können Sie versuchen, die gewünschte Funktionalität mit einer anderen Kernel-Funktion zu erreichen. Alternativ können Sie dem Kernel-Treiber möglicherweise Konfigurationsparameter übergeben, um die Ausführungszeit zu verringern.
Wenn keine dieser Optionen das Problem löst, müssen Sie wahrscheinlich eine leistungsstärkere Hardware verwenden.
Prüfen Sie anhand der folgenden Punkte, ob sich das richtige Instrument zur Erreichung Ihrer Performance-Ziele darunter befindet:
PREEMPT_FULL
isolcpu
rcu_nocbs
rcu_nocb_poll
nosoftlockup
irqbalance disable
kernel.sched_rt_runtime_us