Gut, das Projekt kannte ich noch nicht. Für Deinen Primzahlen-Benchmark
ist dein Compiler ja echt fix. Wenn Du Lua nicht kanntest, dann wohl Nim
auch nicht. Ich habe mal den Python Code angepaßt. Aber tatsächlich ist
er für dieses Beispiel nicht so extrem viel schneller.
1
proc main =
2
const limit = 100000
3
var letztePrimzahl: int
4
for zahl in 2 .. limit:
5
var primzahl = true
6
for zaehler in 2 .. zahl div 2:
7
if zahl mod zaehler == 0:
8
primzahl = false
9
break
10
if primzahl:
11
letztePrimzahl = zahl
12
echo "Die hoechste ermittelte Primzahl ist ", $letztePrimzahl
Stefan S. schrieb:> Wenn Du Lua nicht kanntest, dann wohl Nim auch nicht.
Stimmt, kannte ich bisher auch nicht.
> Ich habe mal den Python Code> angepaßt. Aber tatsächlich ist er für dieses Beispiel nicht so extrem> viel schneller
Ich habe den Code bewusst 1:1 in jede der anderen Sprachen übersetzt, um
irgendwelche sprachabhängigen Optimierungen zu vermeiden.
> $ nim c -d:release p.nim> time ./p> Die hoechste ermittelte Primzahl ist 99991>> real 0m1.829s> user 0m1.828s> sys 0m0.000s
Das ist allerdings wirklich flott. Wie ich eben mal schnell nachgelesen
habe, erzeugt nim u.a. C-Output, der wieder durch den C-Compiler gejagt
wird. Damit ist die hohe Ausführungsgeschwindigkeit erklärbar.
An dem C-Code-Erzeuger für NIC arbeite ich noch, jedoch liegt bei mir
die höhere Priorität beim Interpreter. Die Compile-Execute-Test-Zyklen
sind durch das immer wieder notwendige Flashen des µCs ziemlich lang.
Mit NIC will ich nicht nur Zeit auf dem µC sparen, sondern auch
wertvolle Zeit des Programmierers. ;-)
Mit der Beta-Version von NIC wird auch eine erste Version des
C-Code-Erzeugers (habe noch keinen richtigen Namen dafür) fertig sein,
vermutlich im Juli. Ich erhoffe mir eine 10- bis 100-fache
Ausführungsgeschwindigkeit. Dann stelle ich das komplette Projekt unter
"Projekte & Code" vor.
Auf jeden Fall Danke für Deine Hinweise auf Lua und Nim. Ich schaue mir
beides näher an. Man kann dabei nur lernen ;-)
Frank M. schrieb:> Stefan S. schrieb:>> Wenn Du Lua nicht kanntest, dann wohl Nim auch nicht.>> Stimmt, kannte ich bisher auch nicht.>>> Ich habe mal den Python Code>> angepaßt. Aber tatsächlich ist er für dieses Beispiel nicht so extrem>> viel schneller>> Ich habe den Code bewusst 1:1 in jede der anderen Sprachen übersetzt, um> irgendwelche sprachabhängigen Optimierungen zu vermeiden.>>> $ nim c -d:release p.nim>> time ./p>> Die hoechste ermittelte Primzahl ist 99991>>>> real 0m1.829s>> user 0m1.828s>> sys 0m0.000s>> Das ist allerdings wirklich flott. Wie ich eben mal schnell nachgelesen> habe, erzeugt nim u.a. C-Output, der wieder durch den C-Compiler gejagt> wird. Damit ist die hohe Ausführungsgeschwindigkeit erklärbar.>> An dem C-Code-Erzeuger für NIC arbeite ich noch, jedoch liegt bei mir> die höhere Priorität beim Interpreter. Die Compile-Execute-Test-Zyklen> sind durch das immer wieder notwendige Flashen des µCs ziemlich lang.> Mit NIC will ich nicht nur Zeit auf dem µC sparen, sondern auch> wertvolle Zeit des Programmierers. ;-)>> Mit der Beta-Version von NIC wird auch eine erste Version des> C-Code-Erzeugers (habe noch keinen richtigen Namen dafür) fertig sein,> vermutlich im Juli. Ich erhoffe mir eine 10- bis 100-fache> Ausführungsgeschwindigkeit. Dann stelle ich das komplette Projekt unter> "Projekte & Code" vor.>> Auf jeden Fall Danke für Deine Hinweise auf Lua und Nim. Ich schaue mir> beides näher an. Man kann dabei nur lernen ;-)
Mein Codegenerator braucht zwar recht lang, bis der Code erzeugt ist
(mehr als 6 Minuten auf einem i7 @ 2GHz), dafür ist die
Ablaufgeschwindigt super:
Übrigens auch für ARM und AVR und auch auf AVR braucht der Code nur ein
paar Bytes und läuft dementsprechend unschlagbar schnell!
Die space-for-speed Variante erzeugt den Code in
Frank M. schrieb:> Das ist allerdings wirklich flott. Wie ich eben mal schnell nachgelesen> habe, erzeugt nim u.a. C-Output, der wieder durch den C-Compiler gejagt> wird. Damit ist die hohe Ausführungsgeschwindigkeit erklärbar.
Sowas in der Art kann ja auch Matlab. So hat man die enorme
Funktionsvielfalt, zumal man im Realtime-Workshop sich ja auch graphisch
was zusammenklicken kann.
Die Geschwindigkeit ist immer noch gut. Nicht so gut wie bei manuellem
C-Code vielleicht, aber den zu entwickeln würde viel zu lange dauern.
Wilhelm M. schrieb:> Mein Codegenerator braucht zwar recht lang, bis der Code erzeugt ist> (mehr als 6 Minuten auf einem i7 @ 2GHz), dafür ist die> Ablaufgeschwindigt super:
Ich seh jetzt nicht was das mit dem Thema zu tun hat.
Und wenn man in einem ernsthaften Projekt sowas braucht, wird man
ziemlich sicher zu aute-generiertem Code greifen. Die C++ Tricks haben
zwar den Vorteil, dass die Generierung einfacher ist, aber einen
Compiler als Skripting-Engine zu verwenden ist wohl so ziemlich das
ineffizienteste was ich mir vorstellen kann. Die Ergebnisse sind zwar
ok, aber bis man dahin kommt macht es einfach nur AUA. Wenn du in der
Entwicklungsphase jedes mal 6 Min warten musst, wirst du alsbald zu
einem anderen Paradigma greifen :-)
Frank M. schrieb:> Ich habe den Code bewusst 1:1 in jede der anderen Sprachen übersetzt, um> irgendwelche sprachabhängigen Optimierungen zu vermeiden.
Dennoch muss man ziemlich aufpassen, dass Tests nicht trivialisieren und
wirklich in etwa das testen, was man auch anvisisert.
> Die Compile-Execute-Test-Zyklen sind durch das immer wieder> notwendige Flashen des µCs ziemlich lang.
huh? Sowas entwickelt man doch ersma mit nem Simulator, der einem diesen
ganzen Zirkus und Overhead erspart.
Johann L. schrieb:>>>> Dennoch muss man ziemlich aufpassen, dass Tests nicht trivialisieren und> wirklich in etwa das testen, was man auch anvisisert.
Ja, natürlich hast Du recht. Vornehmlich geht es mir auch darum, eine
einfache Programmiersprache für 32-Bit-µCs anzubieten. Wie man immer
wieder aus einzelnen Forumsbeiträgen herausliest, scheuen viele
AVR-Programmierer den Umstieg auf z.B. den STM32 wegen der steigenden
Komplexität. Die Leute, die hier bisher in Bascom programmiert haben,
sind da ganz aufgeschmissen.
Es stimmt ja auch: Man muss beim STM32, um eine LED blinken zu lassen,
normalerweise eine ganze Latte von Portinitialisierungen vornehmen,
bevor die LED überhaupt einen Mucks tut. Wenn man auf Delays verzichten
will, kommen auch noch Timer-Initialisierungen hinzu. Hinderlich hierbei
ist zudem, dass der C-Code für STM32F10x und STM32F4xx allein schon bei
der Port-Initialisierung verschieden aussieht.
Als NIC-Programm sieht das Blinken einer LED einfach so aus:
1
function void blink ()
2
gpio.toggle (GPIOA, 5)
3
endfunction
4
5
function void main ()
6
gpio.init (GPIOA, 5, OUTPUT)
7
alarm.set (500, function.blink) // blink() alle 500msec automatisch aufrufen lassen
8
9
loop
10
// ... // Hier koennen komplett andere Aufgaben erledigt werden
11
endloop
12
endfunction
Die LED blinkt dann im 1Hz-Rhythmus. Das erledigt die Runtime-Bibliothek
im Hintergrund. Die Hauptschleife ("loop") ist hier noch komplett leer,
da das Blinken dann timergesteuert erfolgt. Die Syntax dabei ist so
simpel, dass jeder Programmieranfänger das sofort versteht.
Der Schwerpunkt liegt also eher bei der Einfachheit der Sprache. Wenn
der Interpreter nebenbei auch noch flott läuft, bin ich schon zufrieden.
Das Sieve-Programm gibt mir dabei erstmal einen Anhaltspunkt - mehr
nicht.
>> Die Compile-Execute-Test-Zyklen sind durch das immer wieder>> notwendige Flashen des µCs ziemlich lang.>> huh? Sowas entwickelt man doch ersma mit nem Simulator, der einem diesen> ganzen Zirkus und Overhead erspart.
Naja, wenn ich einen Packen WS2812-Streifen aus China bekomme, die
plötzlich Pausen von 280µs statt 50µs (wie im Datenblatt steht) zwischen
den Datenpaketen benötigen, weiß ich nicht, wie ich dieses Fehlverhalten
in einem Simulator reproduzieren könnte ;-)
Johann L. schrieb:> Wilhelm M. schrieb:>> Mein Codegenerator braucht zwar recht lang, bis der Code erzeugt ist>> (mehr als 6 Minuten auf einem i7 @ 2GHz), dafür ist die>> Ablaufgeschwindigt super:>> Ich seh jetzt nicht was das mit dem Thema zu tun hat.
Das ganze war doch als Scherz markiert!
Motiviert war es durch dieses Aussage von Frank M. in dem anderen Thread
Beitrag "Welche Programmiersprache auf µC"Frank M. schrieb:> Die hohe Ausführungsgeschwindigkeit wird dadurch erreicht, dass der Host> das NIC-Script vorcompiliert und dann auf den µC einen> maschinenunabhängigen Objekt-Code hochlädt. Dabei werden dann auch> direkt einige Optimierungen vorgenommen: Zum Beispiel werden konstante> Ausdrücke in Expressions direkt zur Compilezeit ausgerechnet.
Denn in meinem Beispiel findet ja auch eine (Vor-)Kompilierung statt und
zur Compilezeit konstante Ausdrücke werden berechnet!
Was das NIC ja in diesem Fall wohl eben nicht macht, sondern zur
Laufzeit ...
Und ich sags nochmal: das war scherzhaft ...
Frank M. schrieb:> Es stimmt ja auch: Man muss beim STM32, um eine LED blinken zu lassen,> normalerweise eine ganze Latte von Portinitialisierungen vornehmen,
Und deswegen braucht man gleich eine neue Sprache? Kann man so etwas
nicht auch in vernünftige™ API's in C++ oder C kapseln? (Die API's von
ST selber mit HAL/SPL zähl ich mal nicht als vernünftig). Mit der
Arduino Umgebung für STM32 sollte das ja auch nicht mehr so schwierig
sein, und das ist ja auch C++.
Dr. Sommer schrieb:> Und deswegen braucht man gleich eine neue Sprache?
Nein, man braucht keine neue Sprache. Für Dich ist sie schon gar nicht
gedacht.
Merke: Ich will hier keinem was aufdrängen. Wer es nutzen will, kann es
nutzen, wer nicht, der nicht. Ich mache das aus Spaß. Und den kannst Du
weißgott nicht in Frage stellen ;-)
Ich verstehe auch nicht, warum die Leute immer direkt mit Kritik und
Fragen nach dem "Warum" angeschossen kommen, wenn irgendjemand etwas
einfaches zusammenbaut und dann auch noch verschenken will.
> Kann man so etwas nicht auch in vernünftige™ API's in C++ oder C> kapseln?
Klar kann "man" das. Mach doch. Wenn ein Anfänger oder
Bascom-Programmierer das dann auch noch anwenden kann, umso besser.
Vielleicht kannst Du Dir auch vorstellen, dass die
NIC-Laufzeitbibliothek, die ja in C geschrieben ist, bereits dem
NIC-Interpreter eine API zur Verfügung stellt. Diese kann man natürlich
auch in C direkt aufrufen, ohne den Interpreter zu bemühen. Ob sie aber
"vernünftig" ist, sei mal dahingestellt. Hier geht es darum, einem
Programm eine API zu bieten und keinem Programmierer. Daher sieht sie
ein wenig langweilig aus ;-)
P.S.
Solche Fragen nach dem "Warum" hörte ich schon damals, als ich das
fli4l-Projekt ins Leben rief: "Router? Wofür? Ich steck mein DSL-Modem
ins LAN-Interface und bin drin.". Klar war er drin, so drin, dass jeder
direkt von außen auf seinen PC zugreifen konnte. Und die Frau und Kinder
mussten warten, bis der Papa mit dem Surfen fertig war. Früher war das
parallele Surfen aus einem Haushalt über mehrere PCs von der Telekom
verboten. Heutzutage bekommt man die Internet-Router an jeder Ecke
nachgeschmissen und die ganze Familie kann gleichzeitig surfen. Warum
wohl?