Hat jemand Erfahrung mit der Verwendung von Python als
Programmiersprache für Applikationen unter Embedded Systems
(Linux/ARM-Cortex-A7)
Unter welchen Bedingungen könnte man dazu raten, Python einzusetzen?
Wann würde man eher davon abraten?
Danke !
Moin,
Michael W. schrieb:> Unter welchen Bedingungen könnte man dazu raten, Python einzusetzen?
Wenn man irgendjemanden kennt, der das embedded system soweit
"hochzieht", dass Python drauf laeuft. Wenn man sonst keine Spache kann.
Wenn Performance egal ist.
Gruss
WK
Es geht hier um ein embedded Sytsem mit
> Linux/ARM-Cortex-A7
also ein Raspberry Pi o.ä.
Darauf läuft auch ein unabgespecktes Python so gut wie auf einem älteren
PC.
Michael W. schrieb:> Unter welchen Bedingungen könnte man dazu raten, Python einzusetzen?
Immer dann, wenn man zu faul ist, etwas in C, C++ oder einer anderen
klassischen Sprache zu programmieren und man schneller zu einem Ergebnis
kommen möchte ;-)
> Wann würde man eher davon abraten?
Wenn die Rechenleistung des ARM für eine Anwendung nicht ausreicht. Das
merkst du aber selber, wenn es so weit ist. Dann kannst den Code dann
immer noch in C[++] umschreiben. Der zusätzliche Zeitaufwand durch das
zweimalige Programmieren ist dabei gering.
So arg langsam ist Python i.Allg. aber gar nicht, wenn man die richtigen
Bibliotheken gewinnbringend nutzt. Für ein paar Dinge, wie bspw. eine
Brute-Force-Suche für ein Schachprogramm würde ich aber C vorziehen :)
Je nach Anwendung und RAM-Ausbau des Systems könnte evtl. auch die
Speicherkapazität ein Problem werden. Aber bei 256 MB, die der kleinste
RasPi hat, geht da schon ziemlich viel.
Michael W. schrieb:> Wann würde man eher davon abraten?
Kernelspace unter Linux geht halt nicht - d.h., Treiber kann man damit
nicht schreiben. Ansonsten ist die Schlange schon gut zu gebrauchen,
auch unter anderen Betriebssystemen.
Yalu X. schrieb:> immer noch in C[++] umschreiben. Der zusätzliche Zeitaufwand durch das> zweimalige Programmieren ist dabei gering.
Da bin ich doch etwas skeptisch. Zunächst muss man sich natürlich gut in
C++ auskennen (was bei mir nicht wirklich der Fall ist :-))
Dann hat man in C++ ja keinen Garbage-Collector. Und sonst, kann man
denn wirklich all die Python-Konstrukte ohne großen Aufwand nach C++
abbilden?
Aber grundsätzlich sehe ich das ähnlich -- nicht trivialen Code zunächst
in einer Hochsprache zu schreiben und dann etwa nach C zu portieren kann
weniger Aufwand sein als von Anfang an in C zu programmieren.
Aber gut, das ist off topic und hilft den Thread-Starter nicht für sein
Referat.
ich steuere mittels python auf einem orange-pi einen LED-strip über SPI.
Die Erfahrung ist eher ernüchternd. Die CPU last ist unnötig hoch.
Es wird 1 Kern bei 1,2 GHz benötigt um eine einfache animation mit
60LEDs (APA102) bei 100 frames/sec zu generieren.
Daher muss ich mich nach einer Alternative umschauen.
Ein Freund von mehr nutzt das Micropython auf einem STM32F429 und ist
positiv überrascht.
Stefan Salewski schrieb:> Yalu X. schrieb:>> immer noch in C[++] umschreiben. Der zusätzliche Zeitaufwand durch das>> zweimalige Programmieren ist dabei gering.>> Da bin ich doch etwas skeptisch. Zunächst muss man sich natürlich gut in> C++ auskennen (was bei mir nicht wirklich der Fall ist :-))
Ich glaube, ich habe mich oben etwas unklar ausgedrückt, deswegen hier
ein Beispiel:
Du programmierst eine Anwendung in Python und brauchst dafür 2 Stunden.
Nach Fertigstellung des Programms stellst du fest, dass es zu langsam
läuft. Also programmierst du das Ganze noch einmal in C++ und brauchst
dafür 6 Stunden. Nach insgesamt 8 Stunden bist du fertig.
Hättest du das Programm sofort (ohne den Umweg über Python) in C++
geschrieben, hättest du 7 Stunden gebraucht. Das sind etwas mehr als
die o.a. 6 Stunden, denn du kannst dabei nicht auf die bereits bei der
Python-Programmierung gemachten Überlegungen zur Programmstruktur und
zu den verwendeten Algorithmen zurückgreifen.
Der Versuch, das Ganze erst einmal in Python hinzubekommen, hat dich
also 1 Stunde (zusätzlich zu den 7, die du sowieso brauchst) gekostet.
Das ist der Versuch IMHO wert, denn in vielen Fällen kann man auch die
C++-Programmierung verzichten und spart dadurch 5 von 7 Stunden.
Die angegeben Zeiten sind natürlich beispielhaft zu sehen und können je
nach programmierter Anwendung und Programmiererfahrung stark variieren.
Ben W. schrieb:> Es wird 1 Kern bei 1,2 GHz benötigt um eine einfache animation mit> 60LEDs (APA102) bei 100 frames/sec zu generieren.
Es gibt natürlich Anwendungen, wo Python ganz klar an seine Grenzen
stößt. 10 ms pro Zyklus sind schon eine recht kurze Zeit, um neben der
Kommunikation mit den LED-Stripes noch eine Menge Berechnungen zur
Erzeugung der Bilder bzw. Leuchtsequenzen anzustellen.
Trotzdem kann man den Python-Code auch in solchen Fällen oft noch ein
ganzes Stück optimieren, indem man ihn nicht C-ähnlich programmiert,
sondern unter bevorzugter Verwendung von High-Level-Funktionen aus
Bibliotheken den Interpreteranteil bei der Ausführung auf ein Minimum
reduziert. Matlab-Nutzer kennen das nur zu gut, denn dort ist der
Interpreter – verglichen mit Python – noch sehr viel langsamer.
Yalu X. schrieb:> Immer dann, wenn man zu faul ist, etwas in C, C++ oder einer anderen> klassischen Sprache zu programmieren und man schneller zu einem Ergebnis> kommen möchte ;-)
...oder wenn man den Code häufiger mal schnell erweitern und an neue
Anforderungen anpassen will.
>> Wann würde man eher davon abraten?>> Wenn die Rechenleistung des ARM für eine Anwendung nicht ausreicht. Das> merkst du aber selber, wenn es so weit ist. Dann kannst den Code dann> immer noch in C[++] umschreiben. Der zusätzliche Zeitaufwand durch das> zweimalige Programmieren ist dabei gering.
Zumal C++-Code mithilfe von Boost::Python recht problemlos in Python
integriert und Python-Code mit nuitka in C++-Code übersetzt werden kann.
Dadurch bieten sich dann schon einige Möglichkeiten die Performance zu
verbessern ohne gleich das ganze Programm neu schreiben zu müssen.
> So arg langsam ist Python i.Allg. aber gar nicht, wenn man die richtigen> Bibliotheken gewinnbringend nutzt.
Numpy, Scipy, Pandas und die Scikit-Bibliotheken sind in weiten Teilen
in performantem C- oder C++-Code implementiert und decken viele Aufgaben
des Numbercrunching ab.
Yalu X. schrieb:> Du programmierst eine Anwendung in Python und brauchst dafür 2 Stunden.> Nach Fertigstellung des Programms stellst du fest, dass es zu langsam> läuft. Also programmierst du das Ganze noch einmal in C++ und brauchst> dafür 6 Stunden. Nach insgesamt 8 Stunden bist du fertig.
Das kann ich so nur absolut unterschreiben! Ich habe meinen 27" Monitor
mit einem Ambilight ausgestattet. Das ganze läuft mit den WS2812,
angesteuert über einen kleinen Mikrocontroller.
Jetzt zu python. Für einen ersten Test hab ich den Algorithmus in Python
geschrieben und das lief auch alles echt ganz gut! In Python hab ich
bereits GTK verwendet für Screenshots, Skalierung und darauf dann meinen
Algorithmus gesetzt. Irgendwann war das etwas zu langsam für hektische
Videos.
Dann hab ich das ganze umgesetzt auf C. Der Algorithmus war fast copy
paste. Die Variablen haben Typen bekommen und nach ein paar weiteren
Student lief das ganze genau so in C mit GTK und schönen 60-70 frames
ggü. den 10-15 aus Python.
Soviel zu meinem Einsatz von Python und C und wie Sachen zuerst in
Python entstehen aufgrund der Einfachheit um später dann das ganze in
ein C Programm zu gießen.
Beachtlich find ich noch die Systemlast, unter Python 20-30% und unter C
gerade mal 5-10%
-D
Moin,
>> Zumal C++-Code mithilfe von Boost::Python recht problemlos in Python> integriert und Python-Code mit nuitka in C++-Code übersetzt werden kann.> Dadurch bieten sich dann schon einige Möglichkeiten die Performance zu> verbessern ohne gleich das ganze Programm neu schreiben zu müssen.>
Und dann wird ein Boost-gewrapptes C++-Python-Modul dank wüstem
Template-Overhead mehrere MB gross. Nee danke, das ist dann doch nix für
Embedded, geht eleganter, es muss ja nicht gleich SWIG sein, ein
robustes Python-Modul ist auch schnell von Hand entworfen.
>> So arg langsam ist Python i.Allg. aber gar nicht, wenn man die richtigen>> Bibliotheken gewinnbringend nutzt.>
Manche Sachen lassen sich mit Hilfe von Cython deutlich beschleunigen.
Macht aber nur Sinn für komplexe Frameworks mit vielen
Laufzeit-Objekten, bei denen Python gegenüber C/C++ punktet.
Typischerweise bin ich auch mit der Entwicklung immer schneller, auch
wenn es doppelt gemacht werden muss (Prototyp in Python, danach die
lahmen Teile als Modul in C umsetzen). Der Punkt ist, dass das
Regress-Testing auf Robustheit gleich mit Python "gratis" kommt - wenn
man's entsprechend auch testet.
Strubi schrieb:>> Zumal C++-Code mithilfe von Boost::Python recht problemlos in Python>> integriert und Python-Code mit nuitka in C++-Code übersetzt werden kann.>> Dadurch bieten sich dann schon einige Möglichkeiten die Performance zu>> verbessern ohne gleich das ganze Programm neu schreiben zu müssen.>> Und dann wird ein Boost-gewrapptes C++-Python-Modul dank wüstem> Template-Overhead mehrere MB gross.
Das wollte ich jetzt mal genauer wissen und habe ein minimales
HelloWorld-Beispiel gebaut. Dessen Binary kommt gestrippt auf gerade
einmal 44k...
Yalu X. schrieb:> Der Versuch, das Ganze erst einmal in Python hinzubekommen, hat dich> also 1 Stunde (zusätzlich zu den 7, die du sowieso brauchst) gekostet.> Das ist der Versuch IMHO wert, denn in vielen Fällen kann man auch die> C++-Programmierung verzichten und spart dadurch 5 von 7 Stunden.
Ich sehe einen weiteren Vorteil von Python, gerade wenn der
Threadersteller Python schon gut beherrscht. Man kann in C oder gar
Assembler sehr viel mehr verkehrt machen, allein schon das manuelle
Ressourcenmanagement und Rumhantieren mit Pointern. Also splittet man
die Arbeit:
- erstmal in Python die grundsätzliche Funktion des Programmes korrekt
hinkriegen. Egal wie langsam, Hauptsache übersichtlich. Dann auf
Korrektheit testen und debuggen.
- von Matlab kenne ich es, daß eine Art Befehlszähler eingebaut ist, was
bei einer Skriptsprache ja trivial ist. Den nutzt man dann fürs
Profiling, und zwar auf dem Host-PC. Geht bequemer als auf dem Target.
- mit diesen Daten guckt man, wo sich algorithmische Optimierung lohnt.
Also keine Programmiertricks, sondern bessere Auswahl der Algorithmen.
Ein Bubblesort wird bei einigen Datenmengen auch in Assembler langsamer
sein als ein anständiger Shellsort in Python. Eine Lookuptabelle
hingegen kann man auch schon in Python realisieren.
- mit dem bequemen Befehlszähler wieder nachmessen.
- wenn die Programmfunktion und algorithmische Optimierung komplett ist,
aber es immer noch zu langsam ist, dann kann man zu C wechseln.
Handwerkliche Programmierfehler muß man debuggen, aber die eigentliche
Funktionalität hat man ja schon vorher debuggt, in Python.
- Zudem kann man das funktionierende Python-Programm heranziehen, an
welchen Stellen welche Zwischenergebnisse anfallen, und das mit C
vergleichen (printf-Ausgaben einbauen). Das vereinfacht die Eingrenzung
von Fehlern enorm.
- zuguterletzt das C-Programm auf das Target ziehen. Da man vorher schon
die Applikation auf dem PC getestet hat, wird man zu einer annehmbaren
Kapselung der Hardware-Eigenarten ohnehin gezwungen und hat eine saubere
Architektur.
Mit diesem Ansatz hab ich mal einen recht komplexen Algorithmus erst in
Matlab gemacht und dann nach Assembler auf einen DSP portiert. Hätte ich
das gleich in Assembler gemacht, hätte das weitaus länger gedauert, wenn
es denn überhaupt funktioniert hätte.
Karl Käfer schrieb:> Strubi schrieb:>>> Zumal C++-Code mithilfe von Boost::Python recht problemlos in Python>>> integriert und Python-Code mit nuitka in C++-Code übersetzt werden kann.>>> Dadurch bieten sich dann schon einige Möglichkeiten die Performance zu>>> verbessern ohne gleich das ganze Programm neu schreiben zu müssen.>>>> Und dann wird ein Boost-gewrapptes C++-Python-Modul dank wüstem>> Template-Overhead mehrere MB gross.>> Das wollte ich jetzt mal genauer wissen und habe ein minimales> HelloWorld-Beispiel gebaut. Dessen Binary kommt gestrippt auf gerade> einmal 44k...
Wenn du eine bestehende Klasse z.B. von Objekten und zugehörigen
Container-Objekten mit ein paar STL-Iteratoren und Smart pointern
wrappst, sieht das schnell anders aus. Für einen - zugegebenen im Source
kompakten - Boost-Wrapper-20-Zeiler kamen bei mir ca. 6 MB an Code raus,
und noch mit nem Refcount-Bug. Dasselbe in SWIG unter 100k (und nicht
buggy). Erst mal allen überflüssig generierten Code zu identifizieren
und rauszuoptimieren dauerte mir zu lang.