Radiosity - Die Lichtenergie gerät bei zu geringen Abstand aus dem Ruder


  • Mod

    wie kommt das limit zustande?



  • Ich muss ja dann für jeden Patch zu jeden anderen Patch die FormFaktor berechne. Wärend er diese Berechnung macht, wächst der Speicher von den Prozess immer weiter an, da es so viele Patche sind. Wenn ich überhaupt keine feinere Unterteilung mache, dann erhalte ich ja schon 10.000 Patche. Untereile ich dann nochmal einige von den Patches auf ein Zentel von ihrer Größe, dann bekomme ich beim FormFaktor-Erstellen eine OutOfMemoryExcepiton.


  • Mod

    das ist natuerlich kein neues Problem, spare matrix

    Ein paar tricks sind:
    -jede Zeile Runlength encoden (da vieles 0 sein sollte), du arbeitest eh zeile fuer zeile ab. (ich empfehle 1 byte mit 4bit fuer wieviele 0 und 4bit fuer wieviele nicht-null folgen).
    -quantifizierung (du suchst pro zeile den maximaln float raus und teilst durch den, legst dann jeden einzelwert als 0-255 oder 0-65525 ab)
    -clustering: du merkst dir beim teilen der patches welche zusammengehoeren, wenn du dann dir formfaktoren errechnest (von anderen patches zu dem zerteilten) und die variieren nicht, legst du nur den wert zum haupt-patch ab.



  • rapso schrieb:

    das ist natuerlich kein neues Problem, spare matrix

    Ein paar tricks sind:
    -jede Zeile Runlength encoden (da vieles 0 sein sollte), du arbeitest eh zeile fuer zeile ab. (ich empfehle 1 byte mit 4bit fuer wieviele 0 und 4bit fuer wieviele nicht-null folgen).
    -quantifizierung (du suchst pro zeile den maximaln float raus und teilst durch den, legst dann jeden einzelwert als 0-255 oder 0-65525 ab)
    -clustering: du merkst dir beim teilen der patches welche zusammengehoeren, wenn du dann dir formfaktoren errechnest (von anderen patches zu dem zerteilten) und die variieren nicht, legst du nur den wert zum haupt-patch ab.

    Also ich speichere die Formfaktoren ja nicht in einer 2D-Matrix sondern jetztes Patch besitzt eine Liste von FormFaktoren:

    class Patch
    {
     public List<ViewFaktor> ViewFaktors { get; private set; }
    }
    
    class ViewFaktor
        {
            public Patch Patch;
            public float FormFaktor;
        }
    

    In dieser Liste werden ja nur die ViewFaktor-Objekte gespeichert, wo der FormFaktor-Wert größer null ist. Ich verstehe jetzt also nicht, inwiefern mir die SpareMatrix-Sache hier weiter helfen kann.

    Ich selbst sehe nur eine sinnvolle Lösung: Ich muss die Patches, welche ich weiter untereile weiter einschränken. Momentan sind es noch immer zu viele. Mich interessieren ja nur die Bereiche, wo es Schattenkanten zu sehen gibt.


  • Mod

    Wieviel speicher kostet eine "verbindung" bei dir genau?



  • C# hat für Datentypen, dass Speicher vom GC verwaltet wird anscheinend kein sizeof-Operator. Wenn ich die Klasse serialisiere, dann erhalte ich 168 Byte. Vermutlich hat er die Patch-Klasse mit serialisiert obwohl sie ein Null-Pointer ist.

    long size = 0;
                object o = new ViewFaktor();
                using (System.IO.Stream s = new System.IO.MemoryStream())
                {
                    System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    formatter.Serialize(s, o);
                    size = s.Length; //->Hier sagt der Debugger 168 
                }
    

    Mein zweiter Weg war über die GC.GetTotalMemmory-Funktion.

    long s1 = GC.GetTotalMemory(false);
                ViewFaktor v = new ViewFaktor();
                string s5 = v.GetType().ToString();
                long s2 = GC.GetTotalMemory(false);
                long s3 = s2 - s1; //-> Hier sagt er 0 Byte
                string s4 = s1.ToString() + s2.ToString() + s3.ToString() + v.ToString() + s5;
    

    Dabei kommt 0 Byte raus.

    Das heißt meine Klasse brauch so zwischen 0 und 168 Byte^^ Das ist so peinlich, dass C# mit dieser simplen Sache überfordert ist.

    Laut meiner Schätzung dürften es 8 Byte sein. Aber zwischen den einzelnen Memberm können noch speicherlöcher sein, so dass die Klasse gut auch doppelt so groß sein kann. Ich weiß es halt nicht genau.

    Mit

    System.Runtime.InteropServices.Marshal.SizeOf(typeof(ViewFaktor));
    

    habe ich es übrigens auch schon versucht und bekomme da nur eine Execption, da das eine Manged-Class- ist.



  • vielleicht kannst du eine million verbindungen allokieren, so wie du es normalerweise machst, und die differenz aus vorher/nachher nehmen, notfalls im taskmanager.

    mit einer matrix solltest du auf etwa 4-5byte pro verbindung kommen (RLE komprimiert).


Anmelden zum Antworten