Hallo Welt
In einer schwachen philosophischen Stunde habe ich über die Welt, Computer und Programme sinniert.
Die Frage, die sich jedoch festbrannte, war die nach der Leistung. Immer mehr Prozessoren mit lächerlich viel Puste kommen auf den Markt, und selbst die künstlich hochgehaltenen Preise vermögen ein mehr oder weniger akzeptables P/L-Verhältnis nicht zu zerstören.
Nun habe ich einen alten Raspberry Pi Model B Rev 1 aus dem Jahr 2011 rumliegen gehabt und aus Jux und Dollerei begonnen, ein kleines OS dafür zu schreiben.
Wer die Hardware nicht kennt: Es ist ein bcm2385-Chip mit ARM1176-jzf-Architektur (j=Jazelle, java-bytecodefähig, f = hardware floating point unit) und einer Taktrate von niedlichen 700MHz - single core.
Die Architektur ist schwach (u.a. RISC-bedingt), das Wortfragment "Giga" sucht man vergeblich, und alleine schon die Tatsache, dass die GPU (Videocore IV) das OS in den Hauptspeicher lädt, zumindest kurios.
Und dennoch: Selbst ohne GPU-Unterstützung (Framebuffer wird mit CPU geschrieben, zumindest testweise) bauen sich Bilder schnell auf und selbst die Initialisierung geht einigermassen schnell, trotz vergleichsweise schnarchiger Class 4 SD-Karte.
Natürlich ist mein kleines OS noch recht roh, ohne richtige FS-Operationen (muss noch sehr viel FAT-Code schreiben. OT: FAT ist ein ziemliches Verbrechen) und ohne Userinputs (der USB-Standard ist noch mühsamer...), aber dennoch läuft dieses recht rohe OS schon stabiler, als ich mir das erhofft hatte.
Jedenfalls ist mir natürlich klar, dass Simulationen und komplexe Berechnungen sehr viel mehr Leistung erfordern als es eine popelige Bildausgabe tut.
Ich meine damit eher den Verbrauchermarkt. Es wird ja regelrecht mit hochgetakteten (~2.4GHz) Prozessoren um sich geschmissen, sei es in Bürorechnern, Laptops oder sogar Handies (Naja, nicht ganz. Aber fast
).
Warum? Und vor allem: Warum wird das gebraucht?
Ich denke da nicht an Games und Videoschnitt - das sind ja die Klassiker, und ja, dort ist diese Leistungsbolzerei auch erwünscht.
Ich meine da alltägliche Programme wie Browser, Textverarbeitung und Co. Warum kann ich auf einem alten Laptop von 2009 mit einem 1.4GHz Centrino 2 Duo kaum noch irgendwas machen; selbst Internetbrowser haben Probleme, die animierten Websites flüssig darzustellen und warum kann sich der Witz über die Speicherhamsterei des Chrome-Browsers so lange halten?
Als C-Fanatiker habe ich immer über dynamische Sprachen wie JS oder PHP geflucht. Warum mussten die statischen Typen weichen? Warum so eine Textsprache, die erst durch mehrere Optimierer gejagt werden muss, bis sie einigermassen performant ist (zumindest bei JS)?
Doch dann habe ich in einem kleinen Projekt den Framebuffer füllen müssen. Und getreu dem Motto "Code muss möglichst wiederverwendbar sein" habe ich eine schöne kleine Funktion geschrieben, die Pixel setzt. Einzeln. "Der Compiler wird das schon inlinen". Das Resultat: 2-3 Sekunden pro Bild.
Also händisch mit Assembly nachgeholfen, die Function Calls reduziert und generell möglichst wenig am Stack verändert, und siehe da: Es läuft schnell. Sehr schnell. Dann noch die Cache Einstellungen korrekt gesetzt, und es funktioniert bestens. Allerdings hinterliess diese Erfahrung eine tiefe Narbe: Der Compiler kann nicht so gut optimieren wie der Mensch - er macht es nur fehlerfreier.
Die Frage, die sich nun stellt ist: Verleitet dieser Überfluss an Leistung dazu, dass man nicht mehr optimieren muss? All diese Komfortfunktionen wie freie Typen bei JS und PHP oder Exceptions bei Java oder C#: Wie könnten diese Systeme effizienter als C++, geschweige denn gutes C oder gar Assembly sein?
Die Entwicklung der Sprachen ging Richtung Funktionalität (SQL, Haskell), Stabilität (Rust) und generell Features (C++11/14), aber keine Sprache ist so richtig eine Lowlevel-Sprache. C hat keine Bitfields bzw. keine brauchbaren mit einstellbarer Reihenfolge. Zudem ist die Logik/Unlogik von uint32_t* i; i++ doof. Man kann dadurch nicht einfach auf das nächste Byte zugreifen, sondern muss casten. Dass ein i[12] noch Sinn macht, ist klar. Und ebenso ist klar, dass das nur *(i + 12) ist. Es macht Sinn, aber es ist mühsam, immer zu casten. Ebenso: Alignment und Byte Order. Gibt es nicht im Standard. Warum? Warum nur?
Zusammenfassend:
Heute wird im Studium gelehrt: Nutze die Funktionen, die du bekommst. Der Compiler wird es schon richten. O(1000n) ist gleich O
, da muss nix optimiert werden.
Es gibt unglaubliche Abstraktionen. Microsoft will Win32 kippen und pusht Metro bzw. Modern UI mit C# oder JS. Auch Ubuntu will in eine ähnliche Richtung gehen, soweit ich weiss. Es wird alles webbasiert realisiert. Tausende Animationen auf Websites (Vor allem diese Auto- und Smartphonewerbeseiten, aber auch z.B. die Star Citizen Homepage) machen sie auf schwachen Geräten träge, obwohl doch Animationen eingeführt worden waren, um Ladezeiten zu überdecken bzw. das Aufploppen zu verwischen. Überall, auch in C/C++ gibt es unüberschaubar viele Bibliotheken, die auf anderen aufbauen und die Programme aufblasen. Qt ist bspw. wirklich komfortabel, aber so viele .dlls müssen dabei sein. Für Dinge, die man unter dem eigentlichen OS / Runtime schon hat, nur nochmals anders (QThread etc.). Es wird nur einfacher, Applikationen für grössere Märkte zu entwickeln.
Sind wir (die Entwickler) schuld an den ewig grösser werdenden Programme, weil wir die bequemen Lösungen bevorzugen? Ist es einfach der Zeitgeist, dass etwas möglichst schnell möglichst cool auszusehen hat, ohne sich Gedanken um Optimierung zu machen (bspw. bei Portierungen von Videospielen von Konsolen auf die wesentlich stärkeren PCs)? Ist es die Gier der Gewinnmaximierung ("Funktioniert ja")?
Ist es eine Folge der Fragmentierung des Marktes, dass jeder eine andere Konfiguration hat und entsprechend allgemeine Lösungen gebraucht werden, die immer funktionieren, ungeachtet des Optimums?
Oder basiert alles heute noch auf altem Code, den zu kippen zu viel Arbeit erfordern würde?
Was sind eure Meinungen dazu?
Gruss
cwriter
In einer schwachen philosophischen Stunde habe ich über die Welt, Computer und Programme sinniert.
Die Frage, die sich jedoch festbrannte, war die nach der Leistung. Immer mehr Prozessoren mit lächerlich viel Puste kommen auf den Markt, und selbst die künstlich hochgehaltenen Preise vermögen ein mehr oder weniger akzeptables P/L-Verhältnis nicht zu zerstören.
Nun habe ich einen alten Raspberry Pi Model B Rev 1 aus dem Jahr 2011 rumliegen gehabt und aus Jux und Dollerei begonnen, ein kleines OS dafür zu schreiben.
Wer die Hardware nicht kennt: Es ist ein bcm2385-Chip mit ARM1176-jzf-Architektur (j=Jazelle, java-bytecodefähig, f = hardware floating point unit) und einer Taktrate von niedlichen 700MHz - single core.
Die Architektur ist schwach (u.a. RISC-bedingt), das Wortfragment "Giga" sucht man vergeblich, und alleine schon die Tatsache, dass die GPU (Videocore IV) das OS in den Hauptspeicher lädt, zumindest kurios.
Und dennoch: Selbst ohne GPU-Unterstützung (Framebuffer wird mit CPU geschrieben, zumindest testweise) bauen sich Bilder schnell auf und selbst die Initialisierung geht einigermassen schnell, trotz vergleichsweise schnarchiger Class 4 SD-Karte.
Natürlich ist mein kleines OS noch recht roh, ohne richtige FS-Operationen (muss noch sehr viel FAT-Code schreiben. OT: FAT ist ein ziemliches Verbrechen) und ohne Userinputs (der USB-Standard ist noch mühsamer...), aber dennoch läuft dieses recht rohe OS schon stabiler, als ich mir das erhofft hatte.
Jedenfalls ist mir natürlich klar, dass Simulationen und komplexe Berechnungen sehr viel mehr Leistung erfordern als es eine popelige Bildausgabe tut.
Ich meine damit eher den Verbrauchermarkt. Es wird ja regelrecht mit hochgetakteten (~2.4GHz) Prozessoren um sich geschmissen, sei es in Bürorechnern, Laptops oder sogar Handies (Naja, nicht ganz. Aber fast

Warum? Und vor allem: Warum wird das gebraucht?
Ich denke da nicht an Games und Videoschnitt - das sind ja die Klassiker, und ja, dort ist diese Leistungsbolzerei auch erwünscht.
Ich meine da alltägliche Programme wie Browser, Textverarbeitung und Co. Warum kann ich auf einem alten Laptop von 2009 mit einem 1.4GHz Centrino 2 Duo kaum noch irgendwas machen; selbst Internetbrowser haben Probleme, die animierten Websites flüssig darzustellen und warum kann sich der Witz über die Speicherhamsterei des Chrome-Browsers so lange halten?
Als C-Fanatiker habe ich immer über dynamische Sprachen wie JS oder PHP geflucht. Warum mussten die statischen Typen weichen? Warum so eine Textsprache, die erst durch mehrere Optimierer gejagt werden muss, bis sie einigermassen performant ist (zumindest bei JS)?
Doch dann habe ich in einem kleinen Projekt den Framebuffer füllen müssen. Und getreu dem Motto "Code muss möglichst wiederverwendbar sein" habe ich eine schöne kleine Funktion geschrieben, die Pixel setzt. Einzeln. "Der Compiler wird das schon inlinen". Das Resultat: 2-3 Sekunden pro Bild.
Also händisch mit Assembly nachgeholfen, die Function Calls reduziert und generell möglichst wenig am Stack verändert, und siehe da: Es läuft schnell. Sehr schnell. Dann noch die Cache Einstellungen korrekt gesetzt, und es funktioniert bestens. Allerdings hinterliess diese Erfahrung eine tiefe Narbe: Der Compiler kann nicht so gut optimieren wie der Mensch - er macht es nur fehlerfreier.
Die Frage, die sich nun stellt ist: Verleitet dieser Überfluss an Leistung dazu, dass man nicht mehr optimieren muss? All diese Komfortfunktionen wie freie Typen bei JS und PHP oder Exceptions bei Java oder C#: Wie könnten diese Systeme effizienter als C++, geschweige denn gutes C oder gar Assembly sein?
Die Entwicklung der Sprachen ging Richtung Funktionalität (SQL, Haskell), Stabilität (Rust) und generell Features (C++11/14), aber keine Sprache ist so richtig eine Lowlevel-Sprache. C hat keine Bitfields bzw. keine brauchbaren mit einstellbarer Reihenfolge. Zudem ist die Logik/Unlogik von uint32_t* i; i++ doof. Man kann dadurch nicht einfach auf das nächste Byte zugreifen, sondern muss casten. Dass ein i[12] noch Sinn macht, ist klar. Und ebenso ist klar, dass das nur *(i + 12) ist. Es macht Sinn, aber es ist mühsam, immer zu casten. Ebenso: Alignment und Byte Order. Gibt es nicht im Standard. Warum? Warum nur?
Zusammenfassend:
Heute wird im Studium gelehrt: Nutze die Funktionen, die du bekommst. Der Compiler wird es schon richten. O(1000n) ist gleich O

Es gibt unglaubliche Abstraktionen. Microsoft will Win32 kippen und pusht Metro bzw. Modern UI mit C# oder JS. Auch Ubuntu will in eine ähnliche Richtung gehen, soweit ich weiss. Es wird alles webbasiert realisiert. Tausende Animationen auf Websites (Vor allem diese Auto- und Smartphonewerbeseiten, aber auch z.B. die Star Citizen Homepage) machen sie auf schwachen Geräten träge, obwohl doch Animationen eingeführt worden waren, um Ladezeiten zu überdecken bzw. das Aufploppen zu verwischen. Überall, auch in C/C++ gibt es unüberschaubar viele Bibliotheken, die auf anderen aufbauen und die Programme aufblasen. Qt ist bspw. wirklich komfortabel, aber so viele .dlls müssen dabei sein. Für Dinge, die man unter dem eigentlichen OS / Runtime schon hat, nur nochmals anders (QThread etc.). Es wird nur einfacher, Applikationen für grössere Märkte zu entwickeln.
Sind wir (die Entwickler) schuld an den ewig grösser werdenden Programme, weil wir die bequemen Lösungen bevorzugen? Ist es einfach der Zeitgeist, dass etwas möglichst schnell möglichst cool auszusehen hat, ohne sich Gedanken um Optimierung zu machen (bspw. bei Portierungen von Videospielen von Konsolen auf die wesentlich stärkeren PCs)? Ist es die Gier der Gewinnmaximierung ("Funktioniert ja")?
Ist es eine Folge der Fragmentierung des Marktes, dass jeder eine andere Konfiguration hat und entsprechend allgemeine Lösungen gebraucht werden, die immer funktionieren, ungeachtet des Optimums?
Oder basiert alles heute noch auf altem Code, den zu kippen zu viel Arbeit erfordern würde?
Was sind eure Meinungen dazu?
Gruss
cwriter