Die Vorteile der grafischen Programmierung mit NI LabVIEW

Überblick

LabVIEW has been used by millions of engineers and scientists to develop sophisticated test, measurement, and control applications. While LabVIEW provides a variety of features and tools ranging from interactive assistants to configurable user-defined interfaces, it is differentiated by its graphical, general-purpose programming language (known as G) along with an associated integrated compiler, a linker, and debugging tools.

A Brief History of the Pursuit of Higher-Level Programming

To better understand the major value propositions of LabVIEW graphical programming, it is helpful to review some background on the first higher-level programming language. At the dawn of the modern computer age in the mid-1950s, a small team at IBM decided to create a more practical alternative to programming the enormous IBM 704 mainframe (a supercomputer in its day) in low-level assembly language, the most modern language available at the time. The result was FORTRAN, a more human-readable programming language whose purpose was to speed up the development process.

The engineering community was initially skeptical that this new method could outperform programs hand-crafted in assembly, but soon it was shown that FORTRAN-generated programs ran nearly as efficiently as those written in assembly. At the same time, FORTRAN reduced the number of programming statements necessary in a program by a factor of 20, which is why it is often considered the first higher-level programming language. Not surprisingly, FORTRAN quickly gained acceptance in the scientific community and remains influential.

Fifty years later, there are still important lessons in this anecdote. First, for more than 50 years, engineers have sought easier and faster ways to solve problems through computer programming. Second, the programming languages chosen by engineers to translate their tasks have trended toward higher levels of abstraction. These lessons help explain the immense popularity and widespread adoption of G since its inception in 1986; G represents an extremely high-level programming language whose purpose is to increase the productivity of its users while executing at nearly the same speeds as lower-level languages like FORTRAN, C, and C++.

LabVIEW: Graphical, Dataflow Programming

LabVIEW is different from most other general-purpose programming languages in two major ways. First, G programming is performed by wiring together graphical icons on a diagram, which is then compiled directly to machine code so the computer processors can execute it. While represented graphically instead of with text, G contains the same programming concepts found in most traditional languages. For example, G includes all the standard constructs, such as data types, loops, event handling, variables, recursion, and object-oriented programming.

While Loop Block Diagram

Figure 1: A While Loop in G is intuitively represented by a graphical loop, which executes until a stop condition is met.

The second main differentiator is that G code developed with LabVIEW executes according to the rules of data flow instead of the more traditional procedural approach (in other words, a sequential series of commands to be carried out) found in most text-based programming languages like C and C++. Dataflow languages like G (as well as Agilent VEE, Microsoft Visual Programming Language, and Apple Quartz Composer) promote data as the main concept behind any program. Dataflow execution is data-driven, or data-dependent. The flow of data between nodes in the program, not sequential lines of text, determines the execution order.

This distinction may seem minor at first, but the impact is extraordinary because it renders the data paths between parts of the program to be the developer’s main focus. Nodes in a LabVIEW program (in other words, functions, structures such as loops, subroutines, and so on) have inputs, process data, and produce outputs. Once all of a given node’s inputs contain valid data, that node executes its logic, produces output data, and passes that data to the next node in the dataflow path. A node that receives data from another node can execute only after the other node completes execution.

Benefits of G Programming

Intuitive grafische Programmierung

Wie die meisten Menschen lernen auch Ingenieure und Wissenschaftler durch das Betrachten und Verarbeiten von Bildern, ohne sich bewusst damit auseinanderzusetzen. Viele Ingenieure und Wissenschaftler können auch als „visuelle Denker“ bezeichnet werden, d. h., sie nutzen insbesondere visuelle Verarbeitung, um Informationen zu organisieren. Anders ausgedrückt: Sie denken am besten in Bildern. Dies wird in Universitäten und Hochschulen häufig noch weiter verstärkt, indem Studierende Lösungen zu Problemen als Prozessdiagramme darstellen sollen. Viele universelle Programmiersprachen erfordern jedoch das zeitintensive Erlernen der spezifischen textbasierten Syntax der jeweiligen Sprache und die anschließende Anwendung der Sprachenstruktur auf das zu lösende Problem. Die grafische Programmierung mit G bietet einen wesentlich intuitiveren Ansatz.

G-Code ist für Ingenieure und Wissenschaftler in der Regel einfacher zu verstehen, da sie mit dem Konzept der Visualisierung sowie der Darstellung von Prozessen und Aufgaben in Block- und Flussdiagrammen (die ebenfalls den Regeln des Datenflusses folgen) vertraut sind. Da datenflussbasierte Sprachen erfordern, dass die Programmstruktur auf dem Fluss der Daten basiert, werden Anwender angehalten, sich auf das zu lösende Problem zu konzentrieren. So erfasst ein typisches G-Programm z. B. auf mehreren Kanälen Temperaturdaten, überträgt diese anschließend an eine Analysefunktion und schreibt die analysierten Daten letztendlich auf die Festplatte. Der Fluss der Daten und die jeweiligen Schritte im Programm sind im LabVIEW-Blockdiagramm einfach nachzuvollziehen.

Abbildung 2: Daten werden mit der Erfassungsfunktion erfasst und über Verdrahtungen intuitiv an die Analysefunktion und anschließend an die Speicherfunktion weitergeleitet.

Interaktive Fehlerbehebungswerkzeuge

Da der grafische G-Code von LabVIEW einfach zu verstehen ist, gestalten sich auch Programmieraufgaben wie die Fehlerbehebung wesentlich intuitiver. LabVIEW bietet beispielsweise einzigartige Fehlerbehebungswerkzeuge, mit denen während der Programmausführung interaktiv beobachtet werden kann, wie Daten entlang der Verdrahtungen von einer Funktion zur nächsten übertragen werden (dieses wird in LabVIEW als Highlight-Funktion bezeichnet).

Abbildung 3: Die Highlight-Funktion bietet eine intuitive Möglichkeit, die Ausführungsreihenfolge des G-Codes nachzuvollziehen.

LabVIEW bietet zudem Fehlerbehebungsfunktionen für G, die mit denen in traditionellen Programmierwerkzeugen verglichen werden können. Auf diese Funktionen, u. a. Sonden, Haltepunkte und Hineinspringen/Überspringen/Hinausspringen, kann über die Werkzeugleiste des Blockdiagramms zugegriffen werden.

Abbildung 4: Die Werkzeugleiste des Blockdiagramms bietet Zugriff auf Fehlerbehebungswerkzeuge wie den Einzelschrittmodus.

Mit diesen Fehlerbehebungswerkzeugen ist es möglich, Daten an mehreren Stellen des Programms simultan zu untersuchen, die Ausführung zu unterbrechen und in Subroutinen zu springen, ohne dass eine komplexe Programmierung erforderlich wäre. Dies ist zwar auch in anderen Programmiersprachen möglich, jedoch ist es einfacher, den Programmstatus und die Beziehungen zwischen parallelen Codebereichen zu visualisieren.

Abbildung 5: Sonden sind effektive Werkzeuge in LabVIEW, um Werte, die entlang der Verdrahtungen übertragen werden, zu visualisieren. Dies gilt auch für parallele Codeabschnitte.

Abbildung 6: Im Sondenüberwachungsfenster können die Werte für alle Sonden der Anwendung (einschließlich Subroutinen) angezeigt werden.

Eine der gängigsten Fehlerbehebungsfunktionen in LabVIEW ist der immer aktivierte Compiler. Während Programmcode entwickelt wird, überprüft der Compiler kontinuierlich, ob Fehler aufgetreten sind, und bietet Semantik- und Syntax-Feedback für die Anwendung. Tritt ein Fehler auf, kann das Programm nicht ausgeführt werden. Dies wird durch einen durchbrochenen Pfeil in der Werkzeugleiste dargestellt.

Abbildung 7: Der durchbrochene Pfeil zeigt sofort an, ob im G-Code Syntaxfehler vorliegen.

Wird auf den durchbrochenen Pfeil geklickt, öffnet sich eine Liste mit zu behandelnden Problemen. Sobald diese Probleme gelöst wurden, kompiliert der LabVIEW-Compiler den Programmcode in Maschinencode. Sobald der Code kompiliert wurde, entspricht die Leistung des G-Programms in etwa der Leistung traditionellerer Sprachen wie C.

Abbildung 8: Die Fehlerliste zeigt detaillierte Erklärungen für jeden Syntaxfehler in der gesamten Codehierarchie.

Automatische Parallelität und Leistung

Datenflusssprachen wie LabVIEW ermöglichen automatische Parallelität. Im Gegensatz zu sequenziellen Sprachen wie C und C++ enthalten grafische Programme Informationen darüber, welche Teile des Codes parallel ausgeführt werden sollten. Ein gängiges Entwurfsmuster der Sprache G ist beispielsweise das Erzeuger/Verbraucher-Entwurfsmuster, bei dem zwei separate While-Schleifen unabhängig voneinander ausgeführt werden: Die erste Schleife erzeugt Daten, während die zweite Schleife die Daten verarbeitet. Obwohl sie parallel ausgeführt werden (u. U. mit unterschiedlichen Raten), werden zwischen den Schleifen über Queues, Standarddatenstrukturen in universellen Programmiersprachen, Daten ausgetauscht.

Abbildung 9: Das Erzeuger/Verbraucher-Entwurfsmuster von LabVIEW wird häufig für die Leistungssteigerung bei Anwendungen, die parallele Tasks erfordern, eingesetzt.

Aufgrund aktueller Entwicklungen bei Computerprozessoren ist Parallelität für Computerprogramme wichtig, da dadurch Leistungssteigerungen gegenüber rein sequenziellen Programmen erreicht werden können. Mehr als 40 Jahre lang haben Hersteller von Computerchips stetig Prozessortaktraten erhöht, um die Chipleistung zu steigern. Momentan sind jedoch weitere Erhöhungen der Taktgeschwindigkeiten zur Erzielung von Leistungssteigerungen wegen des Stromverbrauchs und der Wärmeabgabe nicht mehr realisierbar. Aufgrund dessen haben sich Hersteller auf neue Chiparchitekturen konzentriert, wobei mehrere Prozessoren auf einem Chip integriert sind.

Um die Leistungsvorteile von Multicore-Prozessoren nutzen zu können, müssen Anwendungen Multithreading-fähig sein (d. h., die Anwendung muss in Abschnitte aufgeteilt werden können, die unabhängig voneinander ausgeführt werden). Bei traditionellen textbasierten Sprachen müssen Threads explizit erstellt und verwaltet werden, um Parallelität zu implementieren. Dies ist eine große Herausforderung für Programmierer ohne großen Erfahrungsschatz auf diesem Gebiet.

Dank der parallelen Natur des G-Codes gestaltet sich die Implementierung von Multitasking und Multithreading in LabVIEW unkompliziert. Der integrierte Compiler arbeitet kontinuierlich im Hintergrund, um Codeabschnitte, die parallel ausgeführt werden können, zu identifizieren. Wann immer eine Verzweigung in einer Verdrahtung oder eine parallele Sequenz in den Knoten des Blockdiagramms auftritt, versucht der Compiler, den Code innerhalb eines von LabVIEW automatisch erstellten Threads parallel auszuführen. In der Computerfachsprache ist das eine „implizite Parallelität”, da Programmcode nicht speziell mit dem Zweck geschrieben werden muss, ihn parallel auszuführen. Die Sprache kümmert sich selbst um einen gewissen Grad an Parallelität.

Abgesehen vom Multithreading in einem Multicore-System bietet G eine noch bessere parallele Ausführung, indem die grafische Programmierung auf FPGAs ausgeweitet wird. FPGAs (Field-Programmable Gate Arrays) sind wiederprogrammierbare Schaltkreise, die über ein hohes Maß an Parallelität verfügen. Jeder Verarbeitungs-Task kann einem dedizierten Bereich des Chips zugewiesen und unabhängig ausgeführt werden. Dabei spielt die Anzahl der verfügbaren Verarbeitungskerne keine Rolle. Aufgrund dessen wird die Leistungsfähigkeit der Anwendung nicht eingeschränkt, wenn weitere Verarbeitungs-Tasks hinzugefügt werden.

In der Vergangenheit war die Programmierung von FPGAs Experten vorbehalten, die über fundierte Kenntnisse digitaler Hardwarebeschreibungssprachen verfügten. Jedoch haben auch immer mehr Anwender ohne FPGA-Expertise den Wunsch, FPGA-basierte benutzerdefinierte Hardware einzusetzen, um individuelle Timing- und Triggerroutinen, Hochgeschwindigkeits-Steuer- und -Regel- sowie RF- und Kommunikationsanwendungen und weitere Anwendungen zu erstellen, die zuverlässige Hardware für hohe Geschwindigkeiten, benutzerdefinierte Anpassung und hohen Determinismus erfordern. G-Code ist besonders geeignet für die FPGA-Programmierung, da er die Parallelität und den Datenfluss eindeutig abbildet. Des Weiteren gewinnt die Programmiersprache unter Entwicklern, die parallele Verarbeitung und deterministische Ausführung benötigen, immer mehr an Popularität.

Abbildung 10: Die Speicherverwaltung in LabVIEW ist optional, wobei fortgeschrittene Anwender die Speichernutzung überwachen und optimieren können.

Zeigt G-Code unerwartetes Verhalten, das mit den oben genannten Werkzeugen nicht behoben werden kann, stehen erweiterte Fehlerbehebungsfunktionen in Form des LabVIEW Desktop Execution Trace Toolkits zur Verfügung. Dieses Toolkit wurde für fortgeschrittenere Anwender konzipiert, die dynamische Codeanalysen durchführen wollen, u. a. zur:

Erkennung von Speicher- und Referenzverlusten
Isolierung des Ursprungs eines Ereignisses oder unerwünschten Verhaltens
Suche nach Anwendungsbereichen, deren Leistung verbessert werden kann
Identifizierung des letzten Aufrufs vor dem Auftreten eines Fehlers
Sicherstellung, dass die Anwendung auf verschiedenen Zielgeräten gleich ausgeführt wird

Einsatz von G mit anderen Sprachen

Obwohl G-Code eine exzellente Darstellung der Parallelität ermöglicht und die Speicherzuweisung übernimmt, ist er nicht unbedingt für jede Aufgabe ideal geeignet. Insbesondere mathematische Formeln und Gleichungen lassen sich häufig besser als Text darstellen. Aus diesem Grund kann LabVIEW mit verschiedenen Arten der textbasierten Programmierung kombiniert werden. Bei der Arbeit mit LabVIEW kann der Anwender wählen, ob er den textbasierten oder grafischen Ansatz bzw. eine Kombination aus beiden bevorzugt.

LabVIEW umfasst z. B. den Formelknoten, der, ähnlich wie C, textbasierte mathematische Funktionen und Ausdrücke auf dem Blockdiagramm evaluiert. Diese mathematischen Formeln können zusammen mit grafischem LabVIEW-Code ausgeführt und in diesen integriert werden.

Abbildung 11: Der Formelknoten nutzt eine ähnliche Syntax zu C und stellt mathematische Ausdrücke in einem textbasierten Format dar.

Einfache Möglichkeiten zur Problemlösung

LabVIEW und sein grafischer, datenflussbasierter Programmieransatz bieten einfachere Möglichkeiten für die Lösung von Problemen als traditionelle Lower-Level-Sprachen. Der Beweis hierfür liegt in der Langlebigkeit von LabVIEW. Die Hauptunterschiede der Programmierung in G liegen im intuitiven, grafischen Code und der datengesteuerten Ausführung. Zusammen bieten sie eine Programmiererfahrung, die die Gedankenprozesse des Anwenders besser widerspiegelt als andere Sprachen. Obwohl G eine Higher-Level-Sprache ist, kann aufgrund des integrierten LabVIEW-Compilers trotzdem eine Ausführungsleistung erzielt werden, die Sprachen wie C entspricht.