Autor Thema: L4-ähnlicher Kernel  (Gelesen 39567 mal)

tev

  • Beiträge: 46
    • Profil anzeigen
    • Vanya HP
Gespeichert
« Antwort #20 am: 20. January 2011, 22:08 »
Aber es ist doch wirklich egal in welcher Sprache ich mein OS/Kernel schreib :-D.
Jeder sollte Spaß dabei haben und davon habe ich halt einfach am meisten mit Assembler, wenn jemand lieber in C programmiert, dann ist das auch vollkommen in Ordnung. :-)

Anders ist es halt, wenn die Zeit, die man für die Entwicklung von etwas braucht, eine Rolle spielt, aber das ist meistens bei Hobbyprojekten zweitrangig.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 20. January 2011, 22:44 »
Aber es ist doch wirklich egal in welcher Sprache ich mein OS/Kernel schreib :-D.
Selbst verständlich. Nur solltest du die Sprache deiner Wahl nicht aus den falschen Gründen wählen. Spaß ist bei Hobby-Projekten natürlich völlig ausreichend. Und, dass du weniger Respektiert wirst weil du Spaß an Assembler hast ist natürlich auch völliger Blödsinn. Wir Programmieren ja auch selbst alle hier und da in Assembler (von den Theoretikern hier mal abgesehen xD).
« Letzte Änderung: 20. January 2011, 22:46 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 20. January 2011, 22:46 »
Anders ist es halt, wenn die Zeit, die man für die Entwicklung von etwas braucht, eine Rolle spielt, aber das ist meistens bei Hobbyprojekten zweitrangig.
Naja, wenn die Zeit dann praktisch gesehen den Unterschied macht, ob ich auch irgendwann mal ein Ergebnis bekomme oder ob es für immer unbenutzbare Baustell bleibt, dann sehe ich das schon auch mal anders. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

tev

  • Beiträge: 46
    • Profil anzeigen
    • Vanya HP
Gespeichert
« Antwort #23 am: 20. January 2011, 22:50 »
Aber nochmal zu meinem Kernel, den ich ja schreib  :-).
Ich werde ja auch Syscalls zur Verfügung stellen, wobei ich nicht genau weiß, welche es sein sollten.

Weil L4 selber stellt ja nur ein paar zur Verfügung nämlich ein paar Funktionen für IPC, Memory Management, Prozesse und noch eine Funktion um die restliche Zeit der Zeitscheibe einem anderen Prozess zur Verfügung stellen.

Wobei ich mir nicht sicher bin, welche ich implementieren soll, weil mein Ziel ist es ja so wenig wie nötig im Kernel zu implementieren.

freecrac

  • Beiträge: 86
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 20. January 2011, 23:20 »
Es bezweifelt hier niemand, dass ein Mensch theoretisch in der Lage ist den Optimalen Assembler-Code zu schreiben.
Und es behauptet hier auch niemand, dass ein Compiler den Optimalen Code erzeugt.

Und wenn das Programm schon fertig ist, schafft man es auch [in endlicher Zeit], das ganze in Assembler zuschreiben, so dass der Code besser ist als von einem Compiler erzeugt. Aber für gewöhnlich schreibt man Programme iterativ, d. h. es kommt immer was dazu und mit jedem Code, der dazu kommt und/oder der sich ändert sieht der Optimale Code anders aus. Was zu exponentiell wachsenden Aufwand wird, dein Assembler Code zu warten und optimieren. Wenn du dir die Arbeit machst, dann gut, aber die Wenigsten werden sich die Arbeit machen, was am Ende dann zu einem (viel) schlechterem Ergebnis führt, als dem Resultat eines modernen Compilers.

Ja hierbei kann ich vollkommen zustimmen.

Zitat
Zitat
Genau, und das sind meistens sehr kleine, überschaubare Stellen.
Daran zeigt sich doch schon wie schlecht die C-Compiler arbeiten, wenn sie nicht mal in der Lage dazu sind so kleine Teile so optimal zu gestalten, das man hierbei überhaupt noch auf Assembler-Code zurückgreifen muss, um eine bestmögliche Ausführungsgeschwindigkeit zu erzielen.
Dann sagst du auch, das eine Funkuhr die an einem Tag eine Zehntel Sekunde falsch geht, ungenauer ist als eine herkömmliche Uhr, die in einer Woche um eine Zehntel Sekunde falsch geht? Also die Funkuhr geht auch nach einem Jahr und mehr nur eine Zehntel-Sekunde [falsch]. Ergo kann ich deinen Schluss hier auf schlechte Compiler nicht verstehen. Manchmal ist halt für kleine Sachen der sonst "schlechtere" Weg doch der bessere.

Ein schlechter Weg ist besser als gar kein Weg, daran habe ich keine Zeifel und soooo schlecht sind die Compiler für das was sie in der Menge leisten nun auch wieder nicht. Sonst gäbe es viele Anwendungen noch nicht.
Man kann auch vermuten das es ohne Hochsprachen unmöglich ist die heutigen Informationswege zu gestalten. Eine riesige Datenflut komt auf uns zu es wird immer schneller und umfangreicher.
Das was wir heute kennen ist doch erst der Anfang.

Wer Zeit und Lust dazu hat kann aber trotzdem mit Assembler etwas programmieren.

Dirk
« Letzte Änderung: 20. January 2011, 23:31 von freecrac »

freecrac

  • Beiträge: 86
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 20. January 2011, 23:47 »
Anders ist es halt, wenn die Zeit, die man für die Entwicklung von etwas braucht, eine Rolle spielt, aber das ist meistens bei Hobbyprojekten zweitrangig.
Naja, wenn die Zeit dann praktisch gesehen den Unterschied macht, ob ich auch irgendwann mal ein Ergebnis bekomme oder ob es für immer unbenutzbare Baustell bleibt, dann sehe ich das schon auch mal anders. ;)

Oha, zwischen unbenutzbar und unvollendet ist ganz gewiss noch ein sehr weiter Weg. 8-)

Dirk

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #26 am: 21. January 2011, 22:41 »
Um mich auch mal in die Diskussion einzumischen ;)

Das man in C programmiert heißt aber noch lange nicht das man auch eher und/oder schneller fertig wird (wenn man das überhaupt schafft) als jemand der in Assembler programmiert.

Es gibt genug Versuche ein OS zu programmieren, die in C geschrieben sind, die nicht alzu weit gekommen sind und genauso gibt es einige (ich möchte das Wort viele in dieser Hinsicht nicht benutzen) OS die verdammt weit gekommen sind (spontan fallen mir nur 2 ein, V2OS und menuetos).

Ich sag mir immer dem jedem das seine. Auch ich habe mit Assembler angefangen und bin halbwegs weit gekommen, aber als es dann losging das ich ELF-Dateien parsen musste, wurde es dann wirklich unschön (warum weiß man wenn man mal meinen C-Code dazu gelesen hat ;) ). Aber ansonsten hatte ich mit Assembler schneller erfolge, konnte Algos besser und schneller umsetzen und der Code war wesentlich kleiner.

Assembler sollte man sich aber auch nur "antun" wenn man sich damit auskennt, ansonsten ist C eindeutig besser.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 21. January 2011, 23:42 »
Bei den schnellen Erfolgen kann ich zustimmen, da man näher an der Maschine arbeitet, liegt weniger Krempel dazwischen (insbesondere die Toolchain ist bei Assembler sehr hergestellt).

Den kleineren Code würde ich so nicht bestätigen. Wenn es noch wenig Code ist, wirkt das oft (zurecht) so, bei komplexeren Dingen ist das eher andersrum - je unübersichtlicher es wird, desto eher tendiert man dazu, Dinge ineffizient oder mehrfach zu erledigen. Außerdem darf der Compiler eine Abwägung zwischen Codegröße und Effizienz (loop-unrolling) treffen. Der Grad der Unübersichtlichkeit hängt außerdem direkt mit der Wahl der Programmiersprache zusammen, ist aber nicht ausschließlich davon abhängig.

Nichttriviale Algorithmen lassen sich in einer Hochsprache eigentlich immer besser/eleganter und vor allem wiederverwertbarer umsetzen.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #28 am: 22. January 2011, 11:36 »
Zitat von: svenska
Nichttriviale Algorithmen lassen sich in einer Hochsprache eigentlich immer besser/eleganter und vor allem wiederverwertbarer umsetzen.
Dem kann ich so nicht zustimmen. Was stimmt ist das sie wiederverwertbarer sind, aber nicht unbedint besser/eleganter.

Das Problem für mich ist halt, das ich mich irgendwann daran gewöhnt hatte dass ich in Assembler "denken" konnte und da viel mir der Umstieg auf eine Hochsprache schwer (das ist bei bestimmten Dingen noch immer so).

Ganz konkret gab es da mal einen Algo den ich versucht habe von Assembler in eine Hochsprache zu übersetzen und damit ich keine goto´s verwende, habe ich einige viele if-Zweige dringehabt und es gab verdammt viel Code-Doppelung.

Die Sache mit den nicht trivialen Algos ist allerdings die, das wenn man als Bsp ne Sprache wie Logic/Prolog/Haskel usw. nimmt, man vllt Code schreibt der schön aussieht und "leicht" lesbar ist, aber wie der Compiler das dann umsetzt entzieht sich eigentlich fast allen Programmierern.

Ein einfaches Bsp wäre Quicksort in Haskel, ich erinnere mich dass das nicht mehr als 2 oder 3 Zeilen war, aber was macht der Compiler daraus?

Das nächste ist, das es schwierig ist einen Compiler richtig zu steuern, ihm also zu sagen, die Funktion ist wichtig, hier jetzt die und die Optimierung machen, die Funktion ist nicht so wichtig, da muss nicht so optimiert werden und die Funktion soll auf Größe optimiert werden.
Gut dazu gibt es #pragma, aber ich bin mir nicht sicher ob das im Standard ist oder ob das ne gcc Erweiterung ist.

Was mich auf jeden Fall an z.B. C stört, ist das ständige herumgecaste ;) Ich will nunmal auch vernünftig mit Pointern rechnen können!

Aber mal back2topic.

Was willst du denn alles im Kernel haben? Wenn du dich an L4 orientieren willst, dann implementiere doch einfach die API, da ist dann aber wirklich so gut wie nichts im Kernel und ganz einfach stelle ich mir das auch nicht vor.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #29 am: 22. January 2011, 12:50 »
Das Problem für mich ist halt, das ich mich irgendwann daran gewöhnt hatte dass ich in Assembler "denken" konnte und da viel mir der Umstieg auf eine Hochsprache schwer (das ist bei bestimmten Dingen noch immer so).
Das ist kein Argument für Assembler. Wenn du in einer Sprache geübt bist, kannst du darin Dinge immer besser umsetzen, als in einer Sprache, in der du nicht geübt bist. :roll:

Ganz konkret gab es da mal einen Algo den ich versucht habe von Assembler in eine Hochsprache zu übersetzen und damit ich keine goto´s verwende, habe ich einige viele if-Zweige dringehabt und es gab verdammt viel Code-Doppelung.
Dann hast du etwas falsch gemacht. :-) Wenn du per Hand von Assembler in C übersetzt, dann sieht man dem Code das oft an (für hinreichend geschulten Leser), einfach weil du die Vorteile und Strukturen von C dann doch nicht nutzt.

Die Sache mit den nicht trivialen Algos ist allerdings die, das wenn man als Bsp ne Sprache wie Logic/Prolog/Haskel usw. nimmt, man vllt Code schreibt der schön aussieht und "leicht" lesbar ist, aber wie der Compiler das dann umsetzt entzieht sich eigentlich fast allen Programmierern.
Je höher die Programmiersprache ist, desto eher musst du wissen, welche Prinzipien bei der Umsetzung verwendet werden, wenn du nicht ausschließlich an der Lösung des Problems interessiert bist. (In den meisten Fällen ist man aber genau das.)

Das nächste ist, das es schwierig ist einen Compiler richtig zu steuern, ihm also zu sagen, die Funktion ist wichtig, hier jetzt die und die Optimierung machen, die Funktion ist nicht so wichtig, da muss nicht so optimiert werden und die Funktion soll auf Größe optimiert werden.
Aha, und das kriegst du per Hand eleganter und effizienter hin? Ich behaupte, dass du in Assembler implizit erstmal alles auf Größe optimierst, weil es dann länger übersichtlich bleibt.

Gut dazu gibt es #pragma, aber ich bin mir nicht sicher ob das im Standard ist oder ob das ne gcc Erweiterung ist.
Compiler-Anweisungen sind compilerspezifisch.

Was mich auf jeden Fall an z.B. C stört, ist das ständige herumgecaste ;) Ich will nunmal auch vernünftig mit Pointern rechnen können!
Wenn du Pointer nicht assemblertypisch als "Zahl" betrachtest, sondern als "Datentyp Pointer", wird es schon viel einfacher... zumal du in vielen Sprachen (z.B. Visual Basic) ohnehin keine Pointer hast und da dann drumrumprogrammierst...

Gruß,
Svenska

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #30 am: 22. January 2011, 13:13 »
Zitat von: svenska
Aha, und das kriegst du per Hand eleganter und effizienter hin? Ich behaupte, dass du in Assembler implizit erstmal alles auf Größe optimierst, weil es dann länger übersichtlich bleibt.
Vom Prinzip her ja und man verwendet keine "Compiler" spezifischen Sachen. Ich kann ja einfach die eine Funktion die ich schreibe auf Größe optimieren und eine andere auf Geschwindigkeit (z.B. durch Alignment, Loop-Unrooling usw.).

Assembler-Code ist ab einer gewissen Größe nicht mehr übersichtlich ;) Mit sowas muss man aber in jeder Sprache leben, sowas wie die perfekte Sprache ist leider noch nicht entwickelt worden :(

Zitat von: svenska
Wenn du Pointer nicht assemblertypisch als "Zahl" betrachtest, sondern als "Datentyp Pointer", wird es schon viel einfacher... zumal du in vielen Sprachen (z.B. Visual Basic) ohnehin keine Pointer hast und da dann drumrumprogrammierst...
Das ist übrigens auch so ein Vorteil (je nachdem wie man es sieht) von Assembler, ich brauche um nichts herum zu programmieren, ich mache es einfach!

Das Problem ist halt mit Pointer, das ich die oft einfach nur als Zahl brauche und dann wieder als Pointer usw.
Mein Code ist voll mit solchen Castings (hat nichts mit DSDS oder solchem Schmarn zu tun ;) ) und das sieht einfach nicht schön aus. Zumal man da wieder bei so einer Sache ist, wenn man wirklich schönen leserlichen Code schreibt, überlässt man halt die ganze Arbeit dem Compiler und der ist nunmal dumm!

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #31 am: 22. January 2011, 13:28 »
zu den gotos in Assembler: Das ist wahrscheinlich die beste Performance"optimierung" die man machen kann, da wird sich die Branchprediction und die Pipeline freuen :-D

und zu Pointern:
#define adjust_pointer(p, T, offset) (T*)((uint8_t*)p + offset)
noch schöner (zu benutzen) gehts in C++ mit:
template<typename T>
T* adjust_pointer(T* p, size_t offset)
{
  return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(p) + offset));
}
Ansonsten sollte man wohl zwischen funktionalen oder deklarativen und imperativen Sprachen unterscheiden. Das ich in Haskel keine Kontrolle über die Codegenerierung habe, ist irgendwie klar, aber auch eben nicht gewollt.

zu Optimierung: über __attribute__ kann man bei gcc teilweise Optimierungen ein/ausschalten (zumindest gibt "hot" und "cold")
edit: es gibt auch "optimize", siehe http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

zu #pragma: ist vollständig compilerspezifisch
« Letzte Änderung: 22. January 2011, 13:42 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #32 am: 22. January 2011, 18:29 »
Ich kann ja einfach die eine Funktion die ich schreibe auf Größe optimieren und eine andere auf Geschwindigkeit (z.B. durch Alignment, Loop-Unrooling usw.).
Tust du das auch oder kannst du es nur?

Das Problem ist halt mit Pointer, das ich die oft einfach nur als Zahl brauche und dann wieder als Pointer usw.
Mein Code ist voll mit solchen Castings (hat nichts mit DSDS oder solchem Schmarn zu tun ;) ) und das sieht einfach nicht schön aus.
Dann machst du grundsätzlich irgendwas falsch oder hast nicht sinnvoll abstrahiert.

Zumal man da wieder bei so einer Sache ist, wenn man wirklich schönen leserlichen Code schreibt, überlässt man halt die ganze Arbeit dem Compiler und der ist nunmal dumm!
Da widerspreche ich dir, möchte da aber auf vorhergehende Analysen verweisen und dies nicht ausdiskutieren. Moderne Compiler enthalten wahrscheinlich mehr Intelligenz als du glaubst. Außerdem haben sie mehr CPU-spezifisches Wissen als du.

Gruß,
Svenska

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #33 am: 22. January 2011, 20:51 »
Man kann gcc sogar Profiling-Informationen  (was z.B. statistische Informationen über Branches beinhaltet) geben, die dann in die Optimierung miteinfließen.

edit: 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. :-D
« Letzte Änderung: 22. January 2011, 20:58 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #34 am: 22. January 2011, 21:08 »
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!!
Reality is that which, when you stop believing in it, doesn't go away.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #35 am: 22. January 2011, 22:01 »
Zu dem Statement, dass Compiler dumm sind, habt ihr mich leider falsch verstanden.

Was ich damit meine ist, das dem Compiler Wissen fehlt das ich als Programmierer haben. Bestes Bsp. sind If-Verzeigungen. Woher soll der Compiler wissen welche Verzweigung die wahrscheinlichere ist, es sei denn ich sage es ihm (was ja GCC spezifisch auch geht).

Und ein anderer Punkt ist, es wird noch immer in Assembler optimiert, wenn auch nur kleine sehr wichtige Stellen, aber wenn ein Mensch nie so gut wie ein Compiler optimieren könnte, wieso ist das dann immernoch der Fall und funktioniert auch?

Das nächste ist dann leserlicher Code, ich erinnere mich da an ein paar Zahlenspiele um eine gewisse Optimierung (war was um fließkomma Zahlen mit hilfe von Integerzahlen zu berechnen oder so) die man ohne Hintergrundwissen und Kommentare nie verstanden hätte. Auf sowas kommt auch kein Compiler und da sind wir wieder dabei das ein Compiler dumm ist.

Edit::

@bluecode

Du willst also das gecaste einfach hinter nem Macro oder ner Funktion verstecken, aber das eigentliche Problem ist damit nicht weg.

Mal ein blödes Bsp.:
struct foo_t *bar= startWert;

for(int x= 0; x < schoenerWert; x++) {
 //mache was mit den Daten der Struktur
 ...
 bar= (struct foo_t *)((uint32t)bar + bar->size));
}
Ist nur mal nen einfaches Bsp. Ich habe noch anderen Code wo noch wilder gecastet wird und auch mit dem Pointer gerechnet wird.
« Letzte Änderung: 22. January 2011, 22:13 von FlashBurn »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #36 am: 22. January 2011, 22:27 »
Du willst also das gecaste einfach hinter nem Macro oder ner Funktion verstecken, aber das eigentliche Problem ist damit nicht weg.

Wenn du jetzt noch erklären würdest wo das Problem beim Casten ist? Außer das man damit Typisierung umgeht, die man in Assembler erst gar nicht hat, sehe ich keines. Der Nachteil gegenüber Assembler ist also ≤ 0.

[edit]
Das nächste ist dann leserlicher Code, ich erinnere mich da an ein paar Zahlenspiele um eine gewisse Optimierung (war was um fließkomma Zahlen mit hilfe von Integerzahlen zu berechnen oder so) die man ohne Hintergrundwissen und Kommentare nie verstanden hätte. Auf sowas kommt auch kein Compiler und da sind wir wieder dabei das ein Compiler dumm ist.
Ich hoffe ich habe dich jetzt richtig verstanden. Mein beispiel ist jetzt zwar Ganzzahlig, aber ich denke das ist aussagekräftig genug:

rdx := rax / 10sieht bei gcc so aus:
movabsq $-3689348814741910323, %rdx
mulq    %rdx
shrq    $3, %rdx
das sind [?]+5+1Ticks(laut AMD)
und du willst mir jetzt hoffentlich nicht erzählen, das du dafür kein 'div' benuzt hättest, das braucht 16Ticks


« Letzte Änderung: 22. January 2011, 22:58 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #37 am: 22. January 2011, 22:39 »
FlashBurn: genau für den Code war das Makro/die Funktion gedacht.

Wahrscheinlich emfindet FlashBurn Typisierung allgemein als lästig. Ich finde es eigentlich eher hilfreich, wenn der Compiler meckert weil ich (was in der Mehrzahl der Fälle auch stimmt) Mist gebaut habe. Abgesehen davon finde ich es gut, wenn ich (manche) Casts (die Ausnahme wäre zB obiges Makro, das relativ ungefährlich ist) sehe, denn es macht explizit das hier irgendetwas "Böses" passiert.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #38 am: 22. January 2011, 22:59 »
Hallo,


Was ich damit meine ist, das dem Compiler Wissen fehlt das ich als Programmierer haben. Bestes Bsp. sind If-Verzeigungen. Woher soll der Compiler wissen welche Verzweigung die wahrscheinlichere ist, es sei denn ich sage es ihm (was ja GCC spezifisch auch geht).
Wenn Du erwartest das der Assemblerprogrammierer seine Jumps so optimiert das für den wahrscheinlichen Ausführungspfad möglichst wenige Sprünge entstehen aber der C-Programmierer keine Vorgaben für den Compiler macht (obwohl er ja auch weiß welcher der wahrscheinliche Ausführungspfad ist) dann vergleichst Du Äpfel mit Birnen. Klar weiß der Compiler nicht wie Dein Programm funktioniert, genauso wenig wie der Assembler und der Linker, aber beide Programmierer wissen das und im Endeffekt kann der Compiler mit Hilfe dieser Information wohl besseren Code erzeugen als der menschliche Assembler-Programmierer.

Und ein anderer Punkt ist, es wird noch immer in Assembler optimiert, wenn auch nur kleine sehr wichtige Stellen, aber wenn ein Mensch nie so gut wie ein Compiler optimieren könnte, wieso ist das dann immernoch der Fall und funktioniert auch?
Da geht es oft um spezielle Fälle oder um Situationen wo der Compiler eine neue Befehlssatzerweiterung der CPU noch nicht kennt.

ich erinnere mich da an ein paar Zahlenspiele um eine gewisse Optimierung (war was um fließkomma Zahlen mit hilfe von Integerzahlen zu berechnen oder so) .... Auf sowas kommt auch kein Compiler und da sind wir wieder dabei das ein Compiler dumm ist.
Aber der menschliche Programmierer kommt darauf das man manchmal auch Floating-Point-Operationen mit Hilfe von Integer-Befehlen erledigen kann und wenn der Assembler-Programmierer das darf dann darf das auch der C-Programmierer tun (in C gehen solche Tricks schließlich auch). Wieder versuchst Du die Unfähigkeit eines offenbar schlechten C-Programmierers dem Compiler anzulasten. Wenn wir schon vergleichen wollen dann bitte auch unter wirklich gleichen Voraussetzungen, also auch exakt gleiche Algorithmen usw.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #39 am: 22. January 2011, 23:37 »
Was ich damit meine ist, das dem Compiler Wissen fehlt das ich als Programmierer haben. Bestes Bsp. sind If-Verzeigungen. Woher soll der Compiler wissen welche Verzweigung die wahrscheinlichere ist, es sei denn ich sage es ihm (was ja GCC spezifisch auch geht).
Wenn Du erwartest das der Assemblerprogrammierer seine Jumps so optimiert das für den wahrscheinlichen Ausführungspfad möglichst wenige Sprünge entstehen aber der C-Programmierer keine Vorgaben für den Compiler macht (obwohl er ja auch weiß welcher der wahrscheinliche Ausführungspfad ist) dann vergleichst Du Äpfel mit Birnen. Klar weiß der Compiler nicht wie Dein Programm funktioniert, genauso wenig wie der Assembler und der Linker, aber beide Programmierer wissen das und im Endeffekt kann der Compiler mit Hilfe dieser Information wohl besseren Code erzeugen als der menschliche Assembler-Programmierer.
Wie oben erwähnt, man kann dem Compiler Prolfing-Informationen übergeben, damit kann er den/die häufigsten Pfade optimieren. Das ist sogar noch viel effektiver, da es reale Informationen sind und nicht irgendwas vom Programmierer erdachtes.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

 

Einloggen