Performance von inline Funktionen



  • Wo auch immer du das her hast: Das ist völliger Schwachsinn.

    @dot
    Aus mehreren Quellen liefert sich mir folgender Wortlaut:
    Hier wird der Compiler die Anweisungen nicht als Funktion aufrufen, sondern an die Stelle des Funktionsaufrufs jeweils den Funktionsinhalt kopieren.

    Ich will ja überhaupt keine Winforms schreiben. Das ganze hier ist wie eine Exkursion für mich insofern habe ich mich von euch belehren lassen und fang jetzt erstmal mit konsolenanwendungen an.

    forceinline sollte den aufruf inlineet erzwingen? Wenn ja dann funktionierts nicht.

    @hustbear
    Die direkte Programmausführung gibt mir die selben werte aus.

    Ich habe doch anfangs bereits angemerkt das ich getsystemtime lediglich aus einfachheitsgründen verwende.

    wMillisecond ist eine short Variable die werte von 0 bis 999 ausgibt. Solange sich die Funktionsdauer auf 120 ms beschränkt nutze ich den Wertebereich von wMillisecond. In einigen Fällen, beim anbruch der nächsten sekunde bekomme ich negative Differenzen, diese ich einfach ignorieren kann.

    warum sollte der Schleifeninhalt durch msvc bereinigt werden? In der Schleife werden doch relevante Operationen durchgeführt.



  • int main(array<System::String ^> ^args)

    Es ist immer noch kein C++ Programm. Wie waere es mit dem Installieren von Visual C++ 2010 Express?

    Die direkte Programmausführung gibt mir die selben werte aus.

    Das kann viele Gruende haben.



  • c++neuling2 schrieb:

    @dot
    Aus mehreren Quellen liefert sich mir folgender Wortlaut:
    Hier wird der Compiler die Anweisungen nicht als Funktion aufrufen, sondern an die Stelle des Funktionsaufrufs jeweils den Funktionsinhalt kopieren.

    Dann liegen deine Quellen falsch, oder du hast sie falsch verstanden.

    Ach weißt du was, ich habe gerade nichts zu tun. VS öffnen, ein neues Leeres Projekt erstellen, Code einfügen, oben wo "Debug" steht auf "Release" stellen, Projekteigenschaften -> Linker -> Subsystem auf Console stellen, strg+f5 drücken, sehen dass beides gleich lange braucht.

    #include <ctime>
    #include <iostream>
    
    class vector3
    {
      float data_[3];
    public:
      vector3()
      {}
    
      vector3(float x, float y = 0.f, float z = 0.f)
      {
        data_[0] = x;
        data_[1] = y;
        data_[2] = z;
      }
    
      float& x()
      {
        return data_[0];
      }
    
      const float& x() const
      {
        return data_[0];
      }
    
      float& y()
      {
        return data_[1];
      }
    
      const float& y() const
      {
        return data_[1];
      }
    
      float& z()
      {
        return data_[2];
      }
    
      const float& z() const
      {
        return data_[2];
      }
    };
    
    vector3 operator + (const vector3& lhs, const vector3& rhs)
    {
      return vector3(lhs.x() + rhs.x(), lhs.y() + rhs.y(), lhs.z() + rhs.z());
    }
    
    vector3& operator += (vector3& lhs, const vector3& rhs)
    {
      lhs.x() += rhs.x();
      lhs.y() += rhs.y();
      lhs.z() += rhs.z();
      return lhs;
    }
    
    std::ostream& operator << (std::ostream& stream, const vector3& rhs)
    {
      return stream << '(' << rhs.x() << ", " << rhs.y() << ", " << rhs.z() << ')';
    }
    
    int main()
    {
      vector3 v(10.f, 10.f, 10.f);
    
      auto t = std::clock();
      vector3 v1(1.f, 1.f, 1.f);
      for (unsigned i = 500000000; i-- != 0; )
      {
        v1 += v;
      }
    
      double elapsed = (std::clock() - t) / static_cast<double>(CLOCKS_PER_SEC);
      std::cout << v1 << '\n';
      std::cout << "Elapsed: " << elapsed << "\n\n";
    
      t = std::clock();
      vector3 v2(1.f, 1.f, 1.f);
      for (unsigned i = 500000000; i-- != 0; )
      {
        v2.x() += v.x();
        v2.y() += v.y();
        v2.z() += v.z();
      }
    
      elapsed = (std::clock() - t) / static_cast<double>(CLOCKS_PER_SEC);
      std::cout << v2 << '\n';
      std::cout << "Elapsed: " << elapsed << "\n\n";
    
      return 0;
    }
    

    ASM Code für Additionen:

    v1 += v;
    000812F3  addss       xmm1,xmm0  
    000812F7  addss       xmm2,xmm0  
    000812FB  addss       xmm3,xmm0
    
    v2.x() += v.x();
    00081400  addss       xmm1,xmm0  
    		v2.y() += v.y();
    00081404  addss       xmm2,xmm0  
    		v2.z() += v.z();
    00081408  addss       xmm3,xmm0
    


  • ja danke es funktioniert und ich seh grade er hats automatisch geinlinet 🙂

    Also lag der Fehler bei meinem Funktionsprototypen? Bei mir wurde lediglich ein argument unzwar der 2. Summand übergeben und ich dachte die Funktion müsse keinen Rückgabetyp beinhalten, da der Operator direkt auf den ersten Summanden angewendet wird.

    Ansonsten seh ich das Richtig, also keine Winforms in c++, sondern graphiktechnisches arbeiten mit externen Apis und verwendung nicht verwalteter typen? Noch was zu beachten? 😃

    sry übrigens das ich anscheinend wegen soner einfachen Frage das ganze Forum auf den Kopf gestellt habe 😉



  • c++neuling2 schrieb:

    Also lag der Fehler bei meinem Funktionsprototypen?

    Ich denke mal es lag daran, dass du diese komischen ^ CLI Handles genutzt hast. (Warum auch immer, die sind eigentlich für was komplett anderes...)

    c++neuling2 schrieb:

    Ansonsten seh ich das Richtig, also keine Winforms in c++, sondern graphiktechnisches arbeiten mit externen Apis und verwendung nicht verwalteter typen? Noch was zu beachten? 😃

    Zu beachten? Kommt darauf an, was genau du eigentlich machen willst, das hast du uns ja immer noch nicht verraten. 😉
    Du willst C++ programmieren? Dann nutze auch nur C++. Oder kannst du die Sprachmittel nicht unterscheiden? Da hilft wohl nur ein Buch.. oder viel Geduld..



  • cooky451 schrieb:

    Da hilft wohl nur ein Buch.. oder viel Geduld..

    Eher beides 😉



  • c++neuling2 schrieb:

    Ansonsten seh ich das Richtig, also keine Winforms in c++, sondern graphiktechnisches arbeiten mit externen Apis und verwendung nicht verwalteter typen? Noch was zu beachten?

    Was noch zu beachten ist sind sämtliche Konsequenzen, die sich aus dem Unterschied native<->managed ergeben. Der komplett unterschiedliche Programmierstil und die komplett unterschiedlichen Bibliotheken sind da nur die Spitze des Eisbergs. Immerhin bist du als C#er vielleicht einen halben Millimeter näher dran als Javaisten.
    Erster Tip: nicht alles mit new anfordern und ein gutes Augenmerk auf die Speicherverwaltung haben. Zweiter Tip: Templates nicht mit Generics verwechseln.



  • pumuckl schrieb:

    Zweiter Tip: Templates nicht mit Generics verwechseln.

    Könntest du das bitte näher erläutern. Mir ist klar, dass es sich bei Templates und Generics um zwei technisch verschiedene Umsetzungen des Konzepts generischer Programmierung handelt.
    Aber welche Konsequenzen ergeben daraus, die man beim Programmieren in der jeweiligen Sprache beachten sollte?



  • ananas schrieb:

    Aber welche Konsequenzen ergeben daraus, die man beim Programmieren in der jeweiligen Sprache beachten sollte?

    Ich kenne mich mit C# nicht genügend aus, um da qualifiziert was genaueres sagen zu können. Ich weiß nur, dass es viele Umsteiger gibt, die bei der teilweise recht ähnlichen bis identischen Syntax in Java/C#/C++ automatisch davon ausgehen, dass es in der anderen Sprache exakt das Selbe ist - und das ist eben nicht der Fall. Allgemein ist immer angesagt, die Features in beiden Sprachen gut zu verstehen, um auch die Unterschiede zu verstehen, die sicherlich manchmal sehr subtil sein können.



  • c++neuling2 schrieb:

    @hustbear
    Die direkte Programmausführung gibt mir die selben werte aus.

    warum sollte der Schleifeninhalt durch msvc bereinigt werden? In der Schleife werden doch relevante Operationen durchgeführt.

    Nö.
    Wo?
    Du zählst da lustig, und dann verwirfst du das Ergebnis.
    MSVC denkt sich "WTF?!?" und verwirft die ganze Schleife.
    (Nicht nur der SchleifenINHALT, die ganze Schleife, alles weg)



  • ananas schrieb:

    Könntest du das bitte näher erläutern. Mir ist klar, dass es sich bei Templates und Generics um zwei technisch verschiedene Umsetzungen des Konzepts generischer Programmierung handelt.
    Aber welche Konsequenzen ergeben daraus, die man beim Programmieren in der jeweiligen Sprache beachten sollte?

    Generics und Templates sind zwei völlig verschiedene Dinge. Da Templates zur Compiletime verarbeitet werden, ist z.B. statischer Polymorphismus möglich. Mit Generics kannst du das vergessen. Generics sind ausreichend für sowas wie List<T> und das wars dann auch recht bald schon. C++ Templates dagegen sind für sich allein genommen schon turing-vollständig...


Anmelden zum Antworten