»Device Aware«-Softwareentwicklung Zielhardware berücksichtigen

Embedded-Systeme werden immer komplexer bei kürzerer Entwicklungszeit. Der Druck auf die Entwickler steigt, da Projektzeitpläne und Entwicklungsbudgets eingehalten werden müssen. Wo liegen die Mängel aktueller Werkzeuge für die Softwareentwicklung, und wie lassen sich diese überwinden?

Um wettbewerbsfähige Designs zu erstellen, müssen Entwickler den Funktionsumfang, die Bauteilkosten, die Codegröße, die Performance-Spezifikationen und den Stromverbrauch optimieren. Anders als Hardware ist Software flexibel und somit derjenige Designaspekt, bei dem Entwickler Kompromisse bei den ursprünglichen Projektzielen machen (oder zumindest im Ansatz versuchen) können. Doch die Methoden, mit denen Entwickler ihr Design optimieren, sind wenig raffiniert im Vergleich mit den fortschrittlichen Embedded Systemen, auf die sie diese anwenden. Folglich treten immer mehr Hardware-/Software-Engpässe auf, die moderne Embedded-Designs beeinträchtigen können. Wertvolle Zeit wird verschwendet, um diese Probleme zu lösen. Zeit, die besser für eine kreative Entwicklung und schnellere Markteinführung investiert werden sollte.

Die Optimierung ist derzeit ein hoch manueller Prozess, der meist auf der Methode »Trial & Error« basiert. Die Schwierigkeit, verschiedenen Vorgaben zu genügen, führt meist zu Einbußen bei Funktionsumfang oder Performance – nur um Projektziele zu erfüllen. Es gibt einen entscheidenden technischen Engpass: die Interaktion zwischen dem oder den Prozessoren und den Speichersystemen, die entscheidend für die Effizienz und Leistungsfähigkeit des eingebetteten Systems sind. Da immer fortschrittlichere Speichersysteme mit unterschiedlichen Größen und Zugriffslatenzzeiten in Designs integriert werden, werden die Auswirkungen immer verworrener. Hinzu kommt, dass auch immer mehr Multicore-Prozessoren zum Einsatz kommen, da mehr Leistungsfähigkeit gefordert wird und immer größere Datenmengen zu verarbeiten sind. Das Systemverhalten ist damit schwerer vorauszusagen, was in Echtzeitanwendungen zu einem schwerwiegenden Problem wird.

Diese Trends sollten also entsprechend adressiert werden. Die Softwareentwicklungswerkzeuge haben sich bezüglich dieser Probleme jedoch nicht weiterentwickelt. Compiler generieren grundlegende Code- und Datensequenzen – und zwar einzeln für jede Quelldatei (Bild 1). Sie nutzen nur minimale Informationen zum Zielsystem, um Befehle für eine festgelegte CPU-Befehlssatzarchitektur zu erzeugen. Falls verfügbar, können Profiling-Tools einige Details in Bezug auf die eingesetzten Systemressourcen aufdecken, sie sagen aber wenig über die eigentlichen Problemursachen aus.

Dies hat tiefgreifende Auswirkungen auf Entwicklungsprojekte, vor allem wenn es um Systeme mit komplexen Speicherhierarchien oder mehreren Prozessoren geht. Dies führt oft zu: 

  • Suboptimal erzeugten Befehlsfolgen – deren Größen- und Stromverbrauch ist höher als notwendig. 
  • Unzureichender Positionierung der Speicherressourcen und schlechtem Gesamtlayout. Einzelne Teile des Systems sind daher nicht dort platziert, wo sie am besten für die Befehle oder Datenstrukturen geeignet wären. 
  • Fehlinterpretation von Menschen durchgeführter Optimierungsversuche. Die Folge ist erheblicher Zeitaufwand für experimentelle Änderungen, die nur wenig oder keine Verbesserungen des Systemdesigns ergeben. 

Den Faktor Mensch minimieren

Eine erfolgreiche Optimierung erfordert Informationen über das gesamte System, einschließlich der Speicherhierarchie und des gesamten Programms. Software-/Hardware-Interaktionen sind in heutigen Prozessoren so komplex, dass es für Entwickler zu schwierig ist, viele Probleme über ihren Quellcode zu steuern. Dies führt regelmäßig zu unerwünschten Effekten, sobald sie den Quellcode des Programms verändern. Ihnen fehlen der Einblick und die Kontrolle, um ihre Designs umfassend effizient zu gestalten. Ohne Zugriff auf Informationen über den Grund und die Auswirkungen der verschiedenen Optimierungsabläufe ist es nahezu unmöglich, Vorhersagen zu machen. Versuche, per Hand zu optimieren, sind daher nichts anderes als ein Blindflug.

Eine wirksame Kontrolle und Optimierung lässt sich mit herkömmlichen Tools oder Methoden nicht erreichen, da die Abweichung zu groß ist zwischen dem, was in Hardware erzielt werden kann, und was zur Kontrolle mit Softwareentwicklungswerkzeugen möglich ist. Die Optimierung darf sich nicht länger allein auf den Prozessor konzentrieren. Stattdessen muss das gesamte System adressiert werden, zusammen mit dem Speicher, den Rechen- und Datenanbindungselementen sowie dem gesamten Programm. Außerdem muss der menschliche Faktor aus dem Optimierungsprozess herausgehalten werden. Die hier zugrunde liegenden Beziehungen sind so komplex, dass selbst sehr erfahrene Entwickler sie nicht verstehen können. Dies hat gravierende Auswirkungen: Die Mehrzahl der Entwicklungsprojekte erreicht die ursprünglich gesetzten Ziele nicht.

»Device Aware«-Softwareentwicklungslösungen betrachten die gesamte Systemarchitektur einschließlich aller Prozessorelemente und der Speicherhierarchie (Bild 2). Damit ergeben sich neue Möglichkeiten: Durch die veränderte Methode, Codeerzeugungs- und Datensequenzierungsprozesse anzugehen, lassen sich die Systemeffizienz erheblich steigern und der Zeitaufwand für die Entwicklung wesentlich verringern. Auf jede Art von manuellem Eingriff kann man verzichten, was zeitraubende Optimierungsdurchläufe erübrigt. Informationen, die über die Prozessoren und Speicherarchitektur des Targets gesammelt wurden, können für die »intelligente« Neusequenzierung des Programms verwendet werden. Codegröße, Performance und Ausführungseffizienz lassen sich dann derart optimieren, dass die Entwicklung den ursprünglichen Anforderungen so nahe wie möglich kommt (Best Fit). Damit verbessert sich die durchschnittliche und Best-Case-Ausführungszeit, was ein deterministischeres Verhalten ermöglicht und die Worst-Case-Ausführungszeit begrenzt.

Über den Autor:

David Edwards ist CEO, CTO und Gründer von Somnium Technologies.