Faustregeln

This page is the German Translation of Rules of thumb.

Dieser Text ist gedacht für Leute, die bisher mit C/OpenGL gearbeitet haben.

Obwohl OpenTK automatisch alle GL/AL Funktionsaufrufe von C# nach C umwandelt, arbeiten einige Dinge in der Welt der verwalteten Sprachen etwas anders vergleichen mit simplem C.

Faustregeln

  1. Bevorzugen Sie Server-Speicher statt Klientspeicher

    Ein paar alte OpenGL-Funktionen nutzen Zeiger auf Speicher, der vom Nutzer verwaltet ist. Das bekannteste Beispiel sind Vertex Arrays - die Familie der GL.*Pointer-Funktionen.

    Dieser Ansatz kann in einer Garbage Collector Umgebung (wie .NET es ist) nicht genutzt werden, da der Garbage Collector (GC) die Inhalte des Buffers eventuell verschiebt. Es ist sehr empfehlenswert alte Vertex Arrays mit Vertex Buffer Objects zu ersetzen, welche dieses Problem nicht haben.

    Anders als OpenGL 2.1, wird OpenGL 3.0 keinerlei solcher Funktionen zur Nutzung des Klientspeichers beinhalten.

  2. Versuchen Sie die Anzahl der OpenGL-Funktionsaufrufe per Frame zu minimieren

    Dies ist für jede Programmierumgebung wichtig, die OpenGL nutzt, für OpenTK jedoch sogar noch ein wenig wichtiger: Obwohl die OpenGL/AL Bindings ziemlich optimiert sind, kostet der Übergang von der verwalteten zur unverwalteten Welt einen kleinen, aber messbaren, Overhead (Einbußen an Performance).

    Um den Einfluss des Overheads zu minimieren, versuchem Sie die Anzahl der OpenGL/OpenAL Aufrufe zu verringern. Eine gute Faustregel ist es nicht mehr als 300-500 OpenGL-Aufrufe per Frame zu haben. Dies kann durch Vermeidung des Immediate Mode zu Gunsten von Display Listen oder VBO's geschehen.

  3. Nutzen Sie ref Funktions-Überladungen für maximale Performance bei Mathe-Routinen
    Dies ist wichtig weil Vector3, Matrix3 etc. Strukturen und keine Klassen sind. Klassen-Objekte werden standardmäßig per Referenz übergeben.

    Vector3 v1 = Vector3.UnitX;
    Vector3 v2 = Vector3.UnitZ;
    Vector3 v3 = Vector3.Zero;
    v3 = v1 + v2;                        // requires three copies; slow.
    Vector3.Add(ref v1, ref v2, out v3); // nothing is copied; fast!

    Das gleiche trifft für das Aufrufen von OpenGL-Funktionen zu:

    GL.Vertex3(ref v1.X);  // pass a pointer to v1; fast!
    GL.Vertex3(v1);        // copy the whole v1 structure; slower!

Performance messen

  1. GameWindows besitzt einen eingebauten Frames-pro-Sekunde-Zähler. Wie auch immer, GLControl hat keinen.
  2. Eine einfache und bequeme Möglichkeit zur Messung der Performance Ihres Codes stellt die .NET 2.0 / Mono 1.2.4 Stopwatch Klasse dar. Benutzen Sie sie wie folgt:
    Stopwatch sw = new Stopwatch();
    sw.Start();
    // Your code goes here.
    sw.Stop();
    double ms = sw.Elapsed.TotalMilliseconds;

    Anmerkung: Vermeiden Sie die Nutzung von DateTime.Now oder anderer DateTime-basierte Methoden für Zeitspannen unter ein paar Sekunden, da die Präzisision bei 10ms oder schlecher liegt. (Gerüchte besagen, dass es von Zeit zu Zeit sogar schlechter wird!) DateTime für das Messen von langen Operationen (einige Sekunden) zu nutzen ist OK.

  3. Wenn Sie Windows nutzen, können Sie Fraps downloaden, um die Anzahl der Frames pro Sekunde zu messen, die in Ihrer Anwendung gezeichnet werden.

Referenzen:
http://www.gamedev.net/community/forums/topic.asp?topic_id=484756&whichp...