Hallo,
@tev:Wenn Du speziell für den P4 optimieren willst dann solltest Du bedenken das es für diesen 2 verschiedene Typen an Chipsätzen gab. Einmal mit dem doofen und billigen Standard-DDR-SDRAM und einmal mit dem coolen und teuren RAMBUS-DRAM. Letzterer kann eine höhere Transferrate aber manchmal auch niedrigere Latenzen bieten (u.a. weil er mehr Pages/Lines offen halten kann). Gerade bei der extrem langen P4-Pipeline kann es von erheblicher Bedeutung sein ob die gewünschten Daten aus dem RAM schon da sind oder ob gewartet werden muss. Performance hängt von sehr viel mehr ab als nur von der CPU!
Den L4-Ansatz halte ich persönlich nicht für sehr zielführend weil da extrem viel per IPC kommuniziert werden muss. Ich würde eher versuchen die guten IPC-Konzepte des L4 mit einem vollwertigen Mikrokernel zu verbinden (das möchte ich zumindest versuchen).
Der P4 hat einen L1-Code-Cache der ungefähr 12 kBytes entspricht und das ist schon ziemlich wenig wenn Du wirklich versuchen möchtest das Dein Kernel mit einem so extrem kleinen Cache-Foot-Print aus kommt das er da weitestgehenst komplett rein passt (zumindest die permanent verwendeten Code-Teile) und noch genug für die Applikationen übrig bleibt.
Grüße
Erik
achja, ich wurde ja gebeten Teil zu nehmen:
.... Compiler und der ist nunmal dumm!
Genau das stimmt absolut nicht. Ich habe mir schon von einigen Compilern den Assembler-Code angesehen und muss sagen das da teilweise Tricks drin waren auf die ich nicht von alleine gekommen wäre. Nebst dessen das ein Compiler problemlos verschiedene Wege verfolgen kann um dann zum Schluss das beste Ergebnis zu benutzen. Die Kernfrage ist "Was ist der optimale Code?". Wenn damit die Ausführungsgeschwindigkeit gemeint ist wird bei Programmen ab einer gewissen Größe immer der Compiler gewinnen einfach weil er mehr Arbeitsspeicher zur Verfügung hat als das menschliche Gehirn. Klar könnte theoretisch der Mensch den besseren Code abliefern (der Compiler wurde ja auch von einem Menschen entwickelt) aber wenn man tausende Details beachten muss die auch noch sehr komplexe wechselseitige Abhängigkeiten haben dann verliert der Mensch irgendwann den Überblick, spätestens bei 10'000 (um einfach mal ne hohe Zahl zu nennen) Assemblerbefehlen ist Schluss das kann
kein Mensch mehr im Kopf optimieren. Das nächste Problem ist der sogenannte
Schmetterlingseffekt, da der Compiler den Assembler-Code bei jedem Durchlauf komplett neu erzeugt kann er auch bei jedem iterativen Programmierschritt den optimalen Code erzeugen wohingegen der menschliche Assemblerprogrammierer wohl kaum das gesamte Programm komplett umgestalten wird nur weil sich irgendwo ein Detail geändert hat das nun Auswirkungen auf die Optimierungsstrategie hat. Ein Beispiel sind da die Aufrufkonventionen die die Compiler (innerhalb einer Übersetzungseinheit und bei LTO auch über das gesamte Programm) nach Bedarf frei festlegen können. Wenn in einer Leaf-Funktion z.B. ein Algorithmus geändert wird der dann mit weniger/mehr Registern auskommt kann der Compiler entscheiden das die aufrufenden Funktionen mehr/weniger Register sichern müssen und das kann theoretisch Rückwirkungen bis hin zu main haben.
Ich betrachte mich als recht guten Assemblerprogrammierer, ich habe da über 15 Jahre Erfahrung und kann auf mehreren (recht unterschiedlichen CPU-Architekturen) in Assembler programmieren (wenn auch nicht auf allen gleich gut). Darüber hinaus habe ich auch einiges an Ahnung davon wie eine CPU funktioniert. Trotzdem würde ich niemals behaupten das mein Assembler-Code auch nur annähernd so gut ist wie der von einem guten Compiler der gut programmierten Hochspachen-Code compiliert.
Wenn hier schon verglichen werden soll dann sollten aber der Assembler-Code
und der Hochsprachen-Code (und auch der Compiler) von einem jeweils guten Programmierer stammen. Ob der Vergleich dann bei einer einigermaßen großen Problemstellung (also etwas das mindestens 100'000 Zeilen C-Code entspricht) auch nur annähernd für den Assemblerprogrammierer ausgeht wage ich sehr zu bezweifeln, mal ganz davon abgesehen das der Assemblerprogrammierer vielleicht gar nicht lange genug lebt um überhaupt fertig zu werden.
Mich würde es übrigens wundern, wenn echt optimierter Assemblercode lesbar ist, da man zum Optimieren Instruktionen sehr wild reordnern müsste. Aber es optimiert sowieso keiner, insofern ist die Frage eher theoretischer Natur.
Zu der Zeit als ich versucht habe an Grafik-Demos mit zu programmieren (was aber nicht so meine Stärke war und ich mich dann lieber auf den PM-Unterbau konzentriert habe) haben wir die verschiedenen Datenflüsse durch den Assembler-Code versucht mit unterschiedlichen Einrückungen der Befehle auseinander zu halten und das Ergebnis war auch tatsächlich einigermaßen lesbar aber trotzdem nicht wirklich wartbar (wir haben dann mehrmals nur die Reihenfolge der Befehle einer ganzen Funktion umarrangiert nur weil sich irgendwo ein kleines Detail geändert hat). Mit einem heutigen Compiler verglichen war unser Code sicher trotzdem noch lange nicht optimal und wir haben auch nur kleine Teile der Demos in Assembler programmiert.
Das war mein Senf zum aktuellen Flame-War.
PS.: Flame-Wars sind voll Moppelkotze!!