Makro verhält sich fehlerhaft bei GNU Compiler Linux u. Windows



  • Tim schrieb:

    Ich kann mir gerade nicht so recht einen Fall konstruieren wo es schneller wäre eine Funktion nicht zu inlinen. Imho ist das eher ein Kompromiss aus Laufzeit und Codegröße. Und evtl. auch Stack.

    Zu hohe Codegröße sprengt dir den Cache und geht dann auf die Performance.



  • Na da bin ich froh keinen Cache zu haben 😃



  • Ich hatte im Dezember einen Kompressor geschrieben und dabei die Hashfunktion und den selbst geschriebenen memcmp zum byteweisen Vergleich durch "static inline" Funktionen ersetzt und mit einem 1 GByte File getestet. Inline war beim Komprieren schneller als Makro oder Funktionsaufruf, aber der Effekt war nicht riesig. Bei kleinen Dateien fällt das vermutlich nicht ins Gewicht.



  • Makros sind subba!

    Makros sind subba und wenn diese auch noch optimal gelingen sind diese auch suboptimal...

    Zu hohe Codegröße sprengt dir den Cache und geht dann auf die Performance.

    😕
    Ist das jetzt sarkastisch gemeint ?

    Ich kann mir gerade nicht so recht einen Fall konstruieren wo es schneller wäre eine Funktion nicht zu inlinen. Imho ist das eher ein Kompromiss aus Laufzeit und Codegröße. Und evtl. auch Stack.

    Im Fall wo es auf jedes (Kilo)Byte, jeden Takt ankommt, verstehe ich deine Argumente.

    Aber auf etwas größeren Prozessoren und einem etwas guten Compiler würde ich von solchen Mikrooptmierungen eher abraten. Auf der einen Seite sind Makro's vielleicht etwas schneller, verbrauchen weniger Speicher (paar Bytes) und benötigen ein paar Takte weniger, sind aber dafür fehleranfälliger und kaum debuggbar. Funktionen haben die Makro-typsichen Fehler nicht, sind debuggbar, benötigen dafür aber ein wenig mehr Speicher und Takte.

    Ich könnte auch genausogut argumentieren dass das Überprüfen der Speichergrenzen von Arrays ineffizient ist. Verbraucht auch ein paar Takte mehr und benötigt auch mehr Code.

    Wer garantiert eigentlich das der Compiler/Optimierer nicht bereits solche Optimierungen ohne dein zutun macht? Der VC Compiler/Optimierer ist da böse, er fummelt auf höchster Optmierunsstufe schon erheblich am Code herum, behandelt Funktionen als inline, zerlegt for-Schleifen, ...



  • Bitte ein Bit schrieb:

    Zu hohe Codegröße sprengt dir den Cache und geht dann auf die Performance.

    😕
    Ist das jetzt sarkastisch gemeint ?

    Nein. Was lässt dich das vermuten?



  • Tim schrieb:

    Zum einen unterstützen weder Borland noch MSVC die neueren C-Standards (C99 aufwärts) und sollten demnach im C-Modus auch kein inline verstehen. Zweitens ist inline keine Garantie dass auch geinlined wird. Ergo: Kann viel gelabert werden, um Makros kommt man aber oft nicht herum.

    Macros sind der Spezialfall. Allgemein sollte man inline bevorzugen. Das heißt natürlich nicht, dass man niemals nie Macros verwenden darf. Aber allgemein sollte Macros vermeiden.

    Ein guter Einsatzzweck ist zB die ganzen "forced inline" Varianten der verschiedenen Compiler portabel zu benutzen 🙂

    #ifdef __GNUC__
    #define FORCE_INLINE __attribute__((always_inline));
    #elif ANDERERCOMPILER
    #define FORCE_INLINE foobarinline
    #else
    #error "no force inline"
    #endif
    


  • Nein. Was lässt dich das vermuten?

    Der Sinn deines Satzes bezogen auf einen Otto-Normal-Entwicklungsrechner mit modernen Prozessor: Zu hohe Codegröße sprengt dir den Cache und geht dann auf die Performance.

    Das würde ja implizieren das eine hohe Codegröße mit einem Performanceverlust einhergeht, was so nicht stimmt. Wenn ein Prozessor 4 kByte L1-Cache hat, bedeutet dann dass alle Programme > 4 kByte langsam sind ?

    Was ist mit der Cache-Prediction ?



  • Bitte ein Bit schrieb:

    Der Sinn deines Satzes bezogen auf einen Otto-Normal-Entwicklungsrechner mit modernen Prozessor: Zu hohe Codegröße sprengt dir den Cache und geht dann auf die Performance.

    Das ist sogar mein Wortlaut.

    Das würde ja implizieren das eine hohe Codegröße mit einem Performanceverlust einhergeht, was so nicht stimmt. Wenn ein Prozessor 4 kByte L1-Cache hat, bedeutet dann dass alle Programme > 4 kByte langsam sind ?

    Die Programmgröße ist uninteressant, aber es gibt schlagartig Einbrüche, wenn der Code einer performancekritischen Schleife mehr als 4 kByte groß ist.

    Was ist mit der Cache-Prediction ?

    Keine Ahnung, erzähl du's mir.

    Ich frage mich nach wie vor, wieso du von Sarkasmus ausgehst. Kann doch sein, dass ich einfach uninformiert bin. Wenn du es besser weißt, lass hören!


  • Mod

    Performanceverlust durch massives Inlining ist ein realer Effekt, auch auf modernen Rechnern. Und zwar durchaus recht heftig ⚠ . Du kannst ja gerne mal ein paar Tests machen. Das Problem ist nämlich, das viel Code mehrfach ausgeführt wird. Und wenn dieser Code total aufgeblasen ist, weil jede Funktion mehrfach drinsteht anstatt den Code einmal zu haben und ansonsten nur einen Call, dann kann es schnell passieren, dass bei einer Schleife in jedem Durchgang der Code vom Anfang nochmal nachgeladen werden muss, weil das Schleifeninnere nicht mehr als ganzes in den IC passt. Da nützt dir auch keine Prediction etwas und das hat auch überhaupt nichts mit der Gesamtgröße des Programms zu tun.

    edit: Boah, Bashar, du ninjast mich heute schon zum zweiten Mal! 😃



  • Performanceverlust durch massives Inlining ist ein realer Effekt...

    Das ist mit klar, aber ich habe mich extra auf einen sauberen Code bezogen, wo also inline Funktionen nicht bis zum Erbrechen benutzt wird.

    MSDN zu inline

    Indiscriminate use of __forceinline can result in larger code with only marginal performance gains or, in some cases, even performance losses (due to increased paging of a larger executable, for example).

    @Bashar:
    Tut mit leid, aber deine Wort verwirren mich. 😞


Anmelden zum Antworten