Migration vom eventbasierten zum optimierten Ausführungsmodus

Um deutliche Performancesteigerungen bei der Analyseausführung erzielen zu können, wurde seit ecu.test 7.0 an einer parallelen und effizienteren Abarbeitungsmechanik gearbeitet. Die Unterstützung von 64-Bit-Architekturen ermöglichte es in der Abarbeitungsmechanik, ein Stück weit mit dem eventbasierten Ansatz zu brechen. Statt alle Signalevents einzeln an eine verarbeitende Routine durchzuleiten, werden ganze Arrays von Messpunkten verarbeitet. Durch den Einsatz von Numpy und optimiertem C-Code konnten signifikante Laufzeitverbesserungen erreicht werden. Zu beachten ist, dass die tatsächliche Laufzeitersparnis massiv von einer Reihe von Faktoren abhängt (z.B. Aufbau der Traceanalyse, verwendete interne Funktionen, Tracedateienformate, Anzahl der Messpunkte, Anzahl der Triggerbereiche). Seit ecu.test 8.0 deckt der optimierte Ausführungsmodus die komplette Funktionalität der Traceanalyse ab, weshalb der alte eventbasierte Ausführungsmodus entfernt wurde.

Die optimierte Analyseausführung weicht in wenigen Aspekten vom eventbasierten Vorgehen ab. Die folgende Aufstellung soll die Migration in den neuen Modus erleichtern und solche Abweichungen dokumentieren, bei denen eine Verhaltensänderung angestrebt wird bzw. notwendig ist.

Rundung von Gleitkommazahlen

Bei Ausdrücken von Triggerblöcken und Berechnungsschritten ist auf folgendes zu achten: Durch die Verwendung von NumPy und dessen Datentypen zur schnelleren Berechnung, kann es gegenüber einer reinen Auswertung in Python zu minimal abweichenden Gleitkommawerten kommen. Wenn man zwei Gleitkommazahlen in einem Ausdruck unmittelbar auf Gleichheit prüfen möchte, bietet es sich an, stattdessen eine numerische Erwartung bei Berechnungsschritten zu spezifizieren oder zu prüfen, dass die Differenz der beiden Werte kleiner als ein gewisses Epsilon ist.

Durch dieses Phänomen kann es auch bei den internen Funktionen zu geringfügigen Abweichungen kommen.

Zugriff auf berechnete Signale in Folgeepisoden

In der eventbasierten Ausführung führte das Berechnen eines Signals und ein Zugriff auf dieses Signal innerhalb einer folgenden Episode zwangsläufig dazu, dass dieses Signal in einer CSV-Datei abgelegt wurde, welche anschließend im Reportordner zu finden war.

Im optimierten Ausführungsmodus findet diese Datenübergabe standardmäßig im sogenannten Signaldatencache statt und ist dadurch wesentlich effizienter. Der Signaldatencache lässt sich unter Optionen ‣ Einstellungen ‣ Analyseausführung ‣ Signale cachen bedarfsweise deaktivieren, falls eine CSV-Datei mit den berechneten Signalwerten explizit benötigt wird.

Siehe Einstellungen Traceanalyse.

Besondere Signalwerte (None)

Bei der eventbasierten Analyseausführung wurden Signaldaten in einem Hold-Puffer gehalten. Wurden mehrere versetzt startende Signale verarbeitet, so gab es Zeitstempel, an denen nicht alle Signale einen Messwert hatten. In der eventbasierten Ausführung wurden diese Lücken mit dem besonderen Signalwert None gefüllt. Dies war eine Quelle einer Vielzahl von Fehlern, da in Python 2 beispielsweise None < 0 mit True bewertet wird oder None + 1 in einem NoneType-Error resultiert.

Im optimierten Ausführungsmodus findet abweichend an derartigen Stellen keine Auswertung statt und entsprechende Teilbereiche werden mit NONE und dem Kommentar „Erwartung nicht überprüft“ bewertet.

Folgende Beispiele für Starttriggerbedingungen sollen diesen Unterschied noch einmal verdeutlichen:

Ausdruck als Triggerbedingung

Eventbasierter Ausführungsmodus

Optimierter Ausführungsmodus

Signal1 > 0 and Signal2 < 10

Triggerblock löst bereits aus, wenn Signal2 noch keine Werte hat (also None ist), aber der erste Teil der Bedingung erfüllt ist.

Triggerblock löst erst aus, wenn beide Signale Werte haben und die Bedingung erfüllt ist.

Signal1 > Value(Signal1, -0.001)

Triggerblock löst immer bereits beim ersten Sample aus.

Triggerblock löst frühestens beim zweiten Sample aus.

Signal1 > 0 and Signal2 is None

Triggerblock löst aus, wenn Signal1 größer 0 ist und Signal2 keine Werte hat.

Triggerblock löst nicht aus, wenn Signal2 keine Werte hat. Besser HasValue(Signal2) verwenden!

Optionale und leere Signale

Wird in einem Berechungsschritt nur ein Signal ohne Messpunkte verarbeitet, so greift grundsätzlich die entsprechende Option zur Bewertung leerer Bereiche.

Der Fall der Verwendung eines potentiell leeren Signals in einem Ausdruck mit weiteren Signalen sollte immer in einem Triggerblock mit der HasValue-Funktion (siehe oben) erfolgen. Dies betrifft insbesondere optionale Signale, die sich, sofern sie nicht vorhanden sind, wie Signale ohne Messpunkte verhalten.

Assertion

Im Gegensatz zur eventbasierten Analyseausführung basiert im optimierten Ausführungsmodus das Ergebnis einer Assertion immer auf dem Endresultat des zu untersuchenden Analyseelements. Bei der eventbasierten Ausführung wurde abweichend bei Triggerblöcken ohne Triggerung das bis dahin geltende Analyseergebnis nachbewertet.

Befindet sich eine Assertion über einem Triggerblock, gilt für den optimierten Ausführungsmodus außerdem, dass die Triggerbereiche mit ihrer eigentlichen Bewertung (also ohne Nachbewertung durch die Assertion) im Detailreport angezeigt werden. Bei der eventbasierten Ausführung wurde an dieser Stelle das kumulierte Gesamtergebnis inklusive der Assertion angezeigt. Die Gesamtbewertung stimmt jedoch stets überein.

Auswertezeitpunkte eines Ausdrucks

Im eventbasierten Modus wurden die Signale aller in einer Episode enthaltenen Traceschritte auf einer gemeinsame Zeitachse verarbeitet. Besonders bei der Verwendung berechneter Signale konnte dies zur Beeinflussung eigentlich unabhängiger Berechnungsschritte führen. So konnte beispielsweise ein Berechnungsschritt, welcher ein sehr hoch abgetastetes Signal verarbeitet, dazu führen, dass andere Analyseelemente häufiger aufgerufen wurden, als eigentlich erforderlich.

Abweichend bestimmen bei optimierter Analyseausführung nur die Signale innerhalb des zugehörigen Ausdrucks die Auswertezeitpunkte. Dabei ist zu beachten, dass bei Triggerblöcken Start- und Stoptriggerbedingung (sofern angegeben) immer gemeinsam ausgewertet werden.

Weiterhin wurden Berechnungsschritte/Triggerblöcke unterhalb von Triggerblöcken im eventbasierten Modus immer bereits zum Startzeitpunkt des übergeordneten Triggerbereiches ausgewertet (ggf. mit Hold-Werten). Im optimierten Modus werden solche Schritte erst ausgewertet, sobald alle Signale ihr erstes Sample innerhalb des Triggerbereiches haben.

Datentypen von Signalen

Signale, die im eventbasierten Ausführungsmodus Werte vom Typ int lieferten, liefern im optimierten Ausführungsmodus teilweise Werte vom Typ float (z.B. FrameID). Wenn der geänderte Datentyp Probleme bereitet, kann eine manuelle Typumwandlung, also z.B. int(Signal) Abhilfe schaffen.

Auswertung von Teilausdrücken ohne Signalbezug

Teilausdrücke ohne Signalbezug (auch Funktionsaufrufe) werden im optimierten Ausführungsmodus nur noch einmalig ausgewertet. Im eventbasierten Modus wurden solche Teilausdrücke zu jedem Zeitpunkt neu ausgewertet. Im Ausdruck api.Math.RandomValue(0.5, 0.5, 0.5) * Signal wird also die RandomValue-Funktion nur noch einmalig ausgewertet.

Unterschiede bei internen Funktionen

Bei den internen Funktionen kommt es insbesondere bei Grenzfällen (wie z.B. Signalen mit nur einem Sample), sowie zu Beginn und Ende eines ausgewerteten Bereiches zu Unterschieden. Bei folgenden Funktionen konnten unter bestimmten Bedingungen geringfügige Abweichungen festgestellt werden: Value, Static, HoseAbsolute/HoseRelative, Edge/RisingEdge/FallingEdge, CheckTiming/CheckAlive. Im Folgenden werden nur die wesentlichsten Unterschiede erläutert.

Die Hose-Funktionen betrachten im optimierten Ausführungsmodus bei der zeitlichen Toleranz auch den Hold-Wert am Fensteranfang. Im eventbasierten Modus wurden nur Samples, die im Fenster liegen betrachtet. Außerdem liefern die Hose-Funktionen vor Signalanfang bzw. nach Signalende INCONCLUSIVE. Im eventbasierten Ausführungsmodus wurde mit FAILED bewertet, wenn am Anfang eines der Signale keinen Wert hat. Am Ende wurde je nachdem welches Signal keinen Wert hat, nicht mehr ausgewertet oder mit FAILED bewertet.

Im eventbasierten Modus wurden die Edge-Funktionen erst ab dem zweiten Sample ausgewertet. Im optimierten Ausführungsmodus wird bereits ab dem ersten Sample ausgewertet und man erhält für den entsprechenden Zeitstempel False zurück.