Optimierung automatisierter Prüfanwendungen mit LabVIEW für Multicore-Prozessoren

Überblick

LabVIEW ist eine einzigartige und einfache bedienbare Programmierumgebung für automatisierte Mess- und Prüfanwendungen. Jedoch ist es die Fähigkeit von LabVIEW, Programmcode dynamisch verschiedenen Prozessoren zuzuweisen, welche die Ausführungsgeschwindigkeiten auf Multicore-Prozessoren beschleunigt. Erfahren Sie, wie LabVIEW Anwendungen durch parallele Programmierung optimiert werden können.

Inhalt

Die Herausforderung der Multithreading-Programmierung

Bis vor kurzem haben neue Innovationen in der Prozessortechnologie lediglich dazu geführt, dass Computer Hauptprozessoren erhielten, die mit höheren Taktraten arbeiten konnten. Da sich die Taktraten inzwischen allerdings ihrer theoretischen Obergrenze nähern, werden neue Prozessoren entwickelt, die mehr als nur eine Verarbeitungseinheit, d. h. mehrere Cores, enthalten. Wenn parallele Programmiertechniken zum Einsatz kommen, erreichen automatisierte Prüfanwendungen mit den neuen Multicore-Prozessoren die beste Leistung und den höchsten Durchsatz. Dr. Edward Lee, anerkannter Professor der Elektrotechnik und technischen Informatik an der University of California in Berkeley, beschreibt die Vorteile der parallelen Verarbeitung wie folgt:

„Viele Experten prophezeien, dass auf das Ende der Gültigkeit des Moore'schen Gesetzes zunehmend parallele Computerarchitekturen folgen werden. Wollen wir auch künftig Leistungssteigerungen in der Computertechnologie erzielen, müssen Programme in der Lage sein, aus dieser Parallelität Nutzen zu ziehen.”

Heute herrscht allerdings die Meinung vor, dass es in der Programmierung eine große Herausforderung darstellt, Multicore-Prozessoren wirklich auszunutzen. Microsoft-Gründer Bill Gates erklärt diese Problematik folgendermaßen:

„Um die Leistung von parallel arbeitenden Prozessoren voll auszuschöpfen, ... muss die Software erst einmal mit der Gleichzeitigkeit von Abläufen fertig werden. Jedoch wird jeder Entwickler, der schon einmal multithreading-fähigen Programmcode geschrieben hat, bestätigen, dass dies eine der schwierigsten Aufgaben in der Programmierung überhaupt darstellt.“

Glücklicherweise bietet LabVIEW  eine ideale Programmierumgebung für Multicore-Prozessoren: Erstens stellt es eine intuitive Umgebung für die Erstellung paralleler Algorithmen bereit und zweitens können mehrere Threads einer spezifischen Anwendung dynamisch zugewiesen werden. Tatsächlich können automatisierte Prüfanwendungen, die Multicore-Prozessoren nutzen, recht einfach optimiert werden, um die bestmögliche Leistung zu liefern. Auch modulare Messgeräte nach dem Standard PXI Express tragen dazu bei, da über den PCI-Express-Bus hohe Datenübertragungsraten möglich sind. Zwei Beispiele für Anwendungen, die von Multicore-Prozessoren und PXI-Express-Geräten profitieren, sind Signalanalysen auf mehreren Kanälen und Hardware-in-the-Loop-Anwendungen. Im folgenden Whitepaper werden verschiedene parallele Programmiertechniken evaluiert und deren Leistungsvorteile erläutert.

Implementierung paralleler Prüfalgorithmen

Die Signalanalyse auf mehreren Kanälen ist eine gängige automatisierte Prüfanwendung aus dem ATE-Bereich, die von der parallelen Verarbeitung profitiert. Da die Frequenzanalyse die Prozessorleistung stark beansprucht, kann die Ausführungsgeschwindigkeit erhöht werden: Der Prüfcode wird parallel angelegt, so dass die Verarbeitung der Signale von den einzelnen Kanälen auf mehrere Prozessor-Cores verteilt werden kann. Der Programmierer muss dafür lediglich den Prüfalgorithmus neu strukturieren.

Um dies zu verdeutlichen, werden im Folgenden die Ausführungszeiten zweier Algorithmen für die Frequenzanalyse (Fast-Fourier-Transform, FFT) auf zwei Kanälen eines Hochgeschwindigkeitsdigitalisierers verglichen. In unserem Versuch werden zwei Kanäle des 14-bit-Hochgeschwindigkeitsdigitalisierers PXIe-5122 verwendet, um Signale mit der maximalen Abtastrate von 100 MS/s zu erfassen. Zuerst zeigen wir das traditionelle sequenzielle LabVIEW Programmiermodell für diese Operation. 

Abbildung 1: LabVIEW Programmcode mit sequenzieller Ausführung

Im obigen Blockdiagramm findet die Frequenzanalyse beider Kanäle in einem FFT-Express-VI statt, welches die Kanäle nacheinander analysiert. Zwar können die abgebildeten Algorithmen auch von Multicore-Prozessoren effektiv ausgeführt werden, jedoch ist durch die parallele Verarbeitung der Kanäle eine verbesserte Algorithmusleistung möglich.

Bei genauerer Untersuchung des obigen Algorithmus kommt ans Licht, dass die FFT-Analyse wesentlich länger dauert als die Erfassung vom Hochgeschwindigkeitsdigitalisierer. Wird jeder Kanal einzeln abgefragt und die FFT-Analyse parallel durchgeführt, lässt sich die Verarbeitungszeit erheblich verkürzen. Ein Blockdiagramm, das die parallele Methodik zeigt, ist hier dargestellt:

 Abbildung 2: LabVIEW Programmcode mit paralleler Ausführung

Wie dieser Code zeigt, werden die Kanäle nacheinander vom Digitalisierer abgerufen. Auch dies könnte parallel geschehen, allerdings nur, wenn sich beide Kanäle an unterschiedlichen Messgeräten befänden. Da eine Fourier-Transformation jedoch den Prozessor stark beansprucht, wird bereits eine wesentliche Leistungsverbesserung erzielt, wenn nur die Signalverarbeitung parallel stattfindet. Auf diese Weise wird die gesamte Ausführungszeit verkürzt. Die Dauer beider Implementierungen wird in folgender Abbildung verglichen.

 

Abbildung 3: Ausführungszeit von sequenziell und parallel ausgeführten Algorithmen im Vergleich

Wie oben dargestellt, wird die durch die parallele Ausführung eingesparte Zeit immer deutlicher, je mehr die Blockgröße (Samples pro Abruf) zunimmt. Bei größeren Blöcken führt die parallele Ausführung sogar fast zu einer Halbierung der erforderlichen Zeit und damit zu einer Verdopplung der Leistung. Folgender Graph zeigt die genaue Leistungssteigerung in Prozent als Funktion der Erfassungsgröße (in Samples).

 
[+] Bild vergrößern

Abbildung 4: Leistungssteigerung bei parallelen Algorithmen (in Prozent)

Abbildung 4 macht deutlich, dass die parallele Ausführung bei Blockgrößen von über 1 Million Samples (bei 100 Hz Auflösungsbandbreite) zu einer Leistungssteigerung von mindestens 80 % führt.

Da LabVIEW jeden Thread dynamisch zuweist, kann die Optimierung der Leistung automatisierter Prüfanwendungen auf Multicore-Prozessoren einfach realisiert werden.Anwender müssen nicht einmal speziellen Programmcode schreiben, um Multithreading zu ermöglichen, denn parallele Prüfanwendungen können bereits nach minimalen Anpassungen von Multicore-Prozessoren profitieren.

Konfigurieren anwenderdefinierter paralleler Prüfalgorithmen

Der Vorteil der parallelen Ausführung von Signalverarbeitungsalgorithmen besteht darin, dass LabVIEW die Beanspruchung des Prozessors auf mehrere Cores verteilen kann. Hier wird die Reihenfolge dargestellt, in der der Hauptprozessor die einzelnen Teile des Algorithmus verarbeitet.

Abbildung 5: Ausführung durch den Hauptprozessor

Wie aus diesem Graph ersichtlich wird, ist LabVIEW in der Lage, einen Großteil der erfassten Daten parallel zu verarbeiten, wodurch Ausführungszeit eingespart wird. Eine Anforderung für die parallele Ausführung besteht darin, dass LabVIEW eine Kopie (bzw. einen Klon) jeder Subroutine der Signalverarbeitung erstellen muss. Standardmäßig werden viele Signalverarbeitungsalgorithmen in LabVIEW für eine ablaufinvariante Ausführung konfiguriert. Das bedeutet, dass LabVIEW für jede Subroutine eine eigene Instanz erzeugt – einschließlich separater Threads und Speicherplatz. Deshalb müssen Subroutinen für eine ablaufinvariante Ausführung konfiguriert werden. Dazu dient ein einfacher Konfigurationsschritt in LabVIEW. Um diese Einstellung vorzunehmen, klickt man File >> VI Properties und wählt „Execution“. Dann muss nur noch das Häkchen für die ablaufinvariante Ausführung (Reentrant Execution) gesetzt werden.

 

Abbildung 6: Konfigurierung der ablaufinvarianten Ausführung in LabVIEW

Der eben beschriebene einfache Schritt ermöglicht die parallele Ausführung mehrerer Subroutinen, so wie bei Standardanalysefunktionen in LabVIEW.So ermöglicht eine einfache Programmiertechnik eine erhebliche Leistungssteigerung von automatisierten Prüfanwendungen auf Multicore-Prozessoren.

Optimierung von Hardware-in-the-Loop-Anwendungen

Eine zweite Anwendung, die von paralleler Verarbeitung profitiert, ist die simultane Durchführung von Eingangs- und Ausgangsoperationen auf einem oder mehreren Messgeräten. Solche Applikationen werden meist als Hardware-in-the-Loop- (HIL) oder fertigungsbegleitende Anwendungen bezeichnet. In diesem Szenario wird das Signal entweder von einem Hochgeschwindigkeitsdigitalisierer oder von einem Hochgeschwindigkeits-Digital-I/O-Modul erfasst. Die Software führt einen digitalen Signalverarbeitungsalgorithmus aus. Schließlich wird das Ergebnis von einem anderen modularen Messgerät generiert. Ein typisches Blockdiagramm ist hier abgebildet.

Abbildung 7: Blockdiagramm einer fertigungsbegleitenden Anwendung (HIL)

Häufige HIL-Anwendungen sind beispielsweise: Fertigungsbegleitende Signalverarbeitung (Filtern, Interpolation etc.), Sensorsimulation und anwenderdefinierte Emulation von Komponenten. Im vorliegenden Whitepaper werden Techniken untersucht, mit denen der beste Durchsatz für fertigungsbegleitende digitale Signalverarbeitungsanwendungen erzielt werden kann.

Im Allgemeinen können zwei grundlegende Programmierstrukturen verwendet werden: Die Single-Loop-Struktur und die Multi-Loop-Struktur mit Puffern. Die Single-Loop-Struktur ist einfach zu implementieren und weist bei kleineren Blockgrößen nur geringe Latenz auf. Die Multi-Loop-Architektur kann dagegen viel höheren Durchsatz erzielen, da sie Multicore-Prozessoren besser ausnutzen kann.

Bei der traditionellen Einzelschleife sind die Lesefunktion eines Hochgeschwindigkeitsdigitalisierers, ein Signalverarbeitungsalgorithmus und eine digitale Hochgeschwindigkeits-I/O-Schreibfunktion sequenziell angeordnet. Wie im folgenden Blockdiagramm dargestellt, muss jede dieser Subroutinen nacheinander ausgeführt werden, wie dies im Datenflussprogrammiermodell von LabVIEW vorgegeben ist.

 Abbildung 8: Verarbeitung mit einer einzelnen Schleife

Die Struktur mit nur einer Schleife unterliegt mehreren Einschränkungen. Da ein Schritt nach dem anderen ausgeführt wird, kann der Prozessor nur begrenzt Geräte-I/Os bearbeiten während Daten verarbeitet werden. Daher kann ein Multicore-Prozessor bei diesem Ansatz nicht effizient eingesetzt werden, da der Prozessor nur eine Funktion auf einmal ausführen kann. So kommt nur einer der Cores eines Multicore-Prozessors bei der Anwendung zum Einsatz. Für relativ niedrige Erfassungsraten reicht die Struktur mit einer Schleife aus, bei einem höheren Datendurchsatz sind allerdings mehrere Schleifen erforderlich.

Die Architektur mit mehreren Schleifen nutzt Puffer, um Daten zwischen While-Schleifen auszutauschen. Unten ist das Konzept der Datenflussprogrammierung zwischen While-Schleifen mit Pufferstruktur dargestellt.

 Abbildung 9: Pufferstrukturen ermöglichen den Datenaustausch zwischen mehreren Schleifen.

Die Abbildung zeigt, wie Puffer den Austausch von Daten zwischen mehreren Schleifen ermöglichen. Dabei ist eine sogenannte Erzeuger/Verbraucher-Schleifenstruktur dargestellt. Ein Hochgeschwindigkeitsdigitalisierer erfasst Daten in einer Schleife und übermittelt bei jedem Durchlauf ein neues Datenset an den FIFO. Die Verbraucherschleife überwacht einfach den Status des Puffers und schreibt jedes Datenset auf Festplatte, sobald es zur Verfügung steht. Der Vorteil von Puffern besteht darin, dass Schleifen unabhängig voneinander operieren können. Im obigen Beispiel kann der Hochgeschwindigkeitsdigitalisierer auch dann noch Daten erfassen, wenn es beim Schreiben auf Festplatte zu einer Verzögerung kommt. Die übrigen Samples werden so lange einfach im FIFO gespeichert. Im Allgemeinen erlaubt das Erzeuger/Verbraucher-Modell einen höheren Datendurchsatz, da es den Prozessor effektiver nutzt. Dieser Vorteil wird in Multicore-Prozessoren noch offensichtlicher, da LabVIEW jedem Core dynamisch Prozessor-Threads zuweisen kann.

Für eine fertigungsbegleitende Signalverarbeitungsanwendung können drei unabhängige While-Schleifen und zwei Pufferstrukturen für den Datenaustausch zwischen den Schleifen verwendet werden. In diesem Szenario erfasst eine Schleife Daten von einem Messgerät, eine ist für die dedizierte Signalverarbeitung zuständig und die dritte schreibt Daten auf ein zweites Messgerät, so wie in folgender Abbildung dargestellt.

 

Abbildung 10: Signalverarbeitung in Pipeline-Anordnung mit mehreren Schleifen und Pufferstrukturen

Hier handelt es sich bei der obersten Schleife um eine Erzeugerschleife, die Daten von einem Hochgeschwindigkeitsdigitalisierer erfasst und an die erste Pufferstruktur (FIFO) weiterleitet. Die mittlere Schleife fungiert sowohl als Erzeuger als auch als Verbraucher. Bei jedem Durchlauf holt sie mehrere Datensets aus dem Puffer und verarbeitet sie unabhängig nacheinander. Dieser Ansatz verbessert die Verarbeitungsleistung in Multicore-Prozessoren, indem bis zu vier Datensets parallel verarbeitet werden können. Die mittlere Schleife ist gleichzeitig Erzeuger, denn sie übermittelt die verarbeiteten Daten an den zweiten Puffer. Die untere Schleife schreibt schließlich die verarbeiteten Daten auf Hochgeschwindigkeits-Digital-I/O-Module.

Parallele Verarbeitungsalgorithmen verbessern die Prozessorauslastung von Multicore-Prozessoren. Der Gesamtdurchsatz hängt von zwei Faktoren ab: Prozessorauslastung und Busgeschwindigkeiten. Im Allgemeinen arbeiten Prozessor und Datenbus am effizientesten, wenn große Datenblöcke verarbeitet werden. Der Zeitaufwand für die Datenübertragung kann noch weiter reduziert werden, wenn PXI-Express-Geräte zum Einsatz kommen, die noch schnellere Übertragungsraten ermöglichen. Deshalb wird der maximale Durchsatz als Verhältnis von Abstastrate zur Größe des Datenblocks in Samples dargestellt.

 

Abbildung 11: Durchsatz von Strukturen mit mehreren Schleifen im Vergleich mit Strukturen mit nur einer Schleife

Die Werte, die in diesem Graph aufgeführt sind, wurden durch 16-bit-Abtastungen ermittelt. Außerdem handelte es sich beim verwendeten Signalverarbeitungsalgorithmus um einen Butterwort-Tiefpassfilter 7. Ordnung mit einer Grenzfrequenz von 0,45 x Abtastrate. Wie diese Daten zeigen, ermöglicht der Ansatz mit vier Phasen in Pipeline-Anordnung (mehrere Schleifen) den höchsten Datendurchsatz. Die Signalverarbeitung mit zwei Phasen ergibt eine bessere Leistung als die Methode mit nur einer Schleife (sequenziell), nutzt aber den Prozessor nicht so effizient wie es mit vier Phasen möglich ist. Bei den oben aufgeführten Abstastraten handelt es sich um die maximalen Raten sowohl für Eingang als auch Ausgang am Hochgeschwindigkeitsdigitalisierer PXIe-5122 und am Hochgeschwindigkeits-Digital-I/O-Modul PXIe-6537. Bei 20 MS/s überträgt der Anwendungsbus Daten mit 40 MB/s am Eingang und mit 40 MB/s am Ausgang bei einer gesamten Busbandbreite von 80 MB/s.

Allerdings muss auch in Betracht gezogen werden, dass die Verarbeitung in Pipeline-Anordnung Latenz zwischen Eingang und Ausgang verursacht. Die Latenz hängt von mehreren Faktoren ab, darunter Blockgröße und Abtastrate. Unten stehende Tabelle vergleicht die gemessene Latenz in Bezug auf Blockgröße und maximale Abtastrate für die Architekturen mit einer Schleife und mit vier Phasen und mehreren Schleifen.

 Tabellen 1 und 2: Latenz von Anwendungen mit einzelnen Schleifen und vier Phasen

Wie zu erwarten ist, erhöht sich die Latenz mit zunehmender Prozessorauslastung. Vor allem bei der 4-Phasen-Architektur mit einer Abtastrate von 20 MS/s wird dies deutlich. Dagegen beträgt die Prozessorauslastung bei allen Beispielen mit nur einer Schleife kaum mehr als 50 %.

Fazit

PC-basierte Messgeräte wie z. B. modulare PXI- und PXI-Express-Module profitieren erheblich von Fortschritten in der Multicore-Prozessor-Technologie und verbesserten Geschwindigkeiten von Datenbussen. Bei erhöhter Prozessorleistung aufgrund mehrerer Verarbeitungs-Cores werden parallele oder hintereinander angeordnete Verarbeitungsstrukturen notwendig, um die Effizienz des Prozessors zu optimieren. LabVIEW bietet für diese Herausforderung bei der Programmierung eine hervorragende Lösung, da es den einzelnen Cores Verarbeitungsaufgaben dynamisch zuweist. Indem LabVIEW Algorithmen so strukturiert werden, dass sie die parallele Verarbeitung nutzen, können erhebliche Leistungssteigerungen erzielt werden.