Du bist nicht angemeldet.

Werbeanzeige

1

13.04.2003, 17:27

Speicher Manager in einem großen Projekt

In einem größerem Projekt, ist ein gutes Speicher Managment wichtig. Ich habe mir gedacht das ich einen eigenen Speicher Manager Implementiere und den new- & delete-Operator überlade.
Der Speicher Manager reserviert dann z.B. 100MB am stück (ist Variable), und dort werden dann alle Daten hineingelegt. Dazu zählen auch die einzelnen Klassen wie z.B. CGraphic oder CInput oder so.
Der Vorteil dabei währe das man seine gesamte API auf einen Schlag aus dem Speicher entfernen kann (ohne Memory Leaks zu erzeugen), und bei einem Fehler ein Speicherbild erzeugen kann.

Dies ist aber nur eine mögliche Lösung. Wie würdet Ihr das alle bei einem großen Projekt angehen?
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Jumping Jack

Treue Seele

Beiträge: 142

Wohnort: Hamburg

Beruf: Schüler

  • Private Nachricht senden

2

14.04.2003, 21:05

hm, ich habe mich damit auch n bischen beschäftigt,
bin da aber nicht sehr weit gekommen.
Ich habe mir bis jetzt nur überlegt, ob ich nicht den speicher in 2 blöcke aufteilen soll:
1 block für kleine datenfelder(<= ca. 512byte) d.h klasseninstanzen usw.
und der zweite block für große datenmengen.

ob das sehr sinnvoll ist weis ich noch nicht, aber man hat schonmal eine grobe auftrennung der daten. Man könnte versuchen die listen dann für ihre daten zu optimieren, ich weiß aber nicht obs da überhaupt noch was zu optimieren gibt.

Anonymous

unregistriert

3

17.04.2003, 12:19

Re:

Diese Technik wird als „MemoryPool“ bezeichnet, auf dem Amiga und C64 war das an der Tagesordnung. Bei Hauptklassen einer Engine macht das keinen sinn mehr, der aufwand dafür ist einfach zu groß. Aber dort wo sehr viele kleine Allokationen auftreten z.B. in einer Linked list, ist so was doch westenlich schneller. Oder bei Texturen, die ja meist immer die gleiche Größe haben, aber mit dem V-Ram muss man sorgfältiger umgehen, er ist schließlich immer zu knapp auch bei 256 MB. Bei meiner Engine belegt allein der Vertex Buffer schon ca. 80 MB... Um Memory Leaks vorzubeugen kann man aber auch „SmartPointer“ einsetzen.

Mit freundlichen Grüßen

:huhu:

Maverick

4

17.04.2003, 17:55

Zitat

Um Memory Leaks vorzubeugen kann man aber auch „SmartPointer“ einsetzen

Das ist schon richtig. Allerdings sollte man SmartPointer höchstens in der Debug-Version benutzen. Weil ein SmartPointer bis zu 10% Langsamer sein kann wie ein Normaler Pointer.

Das kann sich unangenehm auf die Performance auswirken, da man ja nicht grad wenige Pointer-Zugriffe hat.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Anonymous

unregistriert

5

18.04.2003, 17:32

:kotz:

Quatsch!! Ob der „->“ operator jetzt ein

return this macht oder ein return realptr, macht in der Laufzeit keinen unterschied.

mfg

Maverick

6

18.04.2003, 17:37

Na wenn der SmartPointer keine prüfungen macht wie z.B. ob der Pointer überhaupt noch gültig ist, macht ein SmartPointer keinen Sinn.

Und eben genau diese Prüfungen brauchen Zeit ;)

Zudem würde ich das nicht sagen, wenn ich es nicht selbst mal ausgetestet hätte 8)
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Maverick

Frischling

Beiträge: 14

Wohnort: Paderborn

Beruf: IT Fachinformatiker ANW

  • Private Nachricht senden

7

18.04.2003, 18:53

8)

Diese Prüfung kannst du aber mittels des Prärpzessors #ifndef steuern, so das sie nur im Debug Modus ausgeführt wird. Klar machen Smart_ptr’s sinn grade unter Verwendung der Ausnahmebehandlung, wer soll sonst die Pointer löschen? Davon machst du ja intensiv gebrauch, übrigens noch ein tipp, anstatt der for schleifen zum Kopieren in deiner CArray würde ich einfach einen memcpy vornehmen, dass ist westlich schneller, da du den Speicher am stück kopierst und nicht Häppchenweise. Des weitern solltest du einen s.g. Interator definieren, dass ist ein Objekt welches in der CArray eingebettet ist und einen überladenen ++ operator besitzt. Damit kannst du wesentlich schneller und vor allem einheitlich alle deine Container durchgehen.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
-------------------------------------------------------------------------------
********************** - GtcVector class declaration - ************************
-------------------------------------------------------------------------------
*/
template< typename T = *void >
template< typename Tvalue = GtUInt >
class GtcVector : public GtcGenericDataContainer< T >
{

/*
---------------------------------------
******** Iterator of GtcVector ********
---------------------------------------
*/
private:

    class GtcVectorIterator
    {

    friend class GtcVectorIterator;

    /*
    ----------------------------------------
    ** Data elements of GtcVectorIterator **
    ----------------------------------------
    */
    private:

        GtcVector *m_pGtcVectorCursor;

    /*
    ----------------------------------------
    * con/destructors of GtcVectorIterator *
    ----------------------------------------
    */
    public:
        
        GtcVectorIterator( GtcVector *p_aGtcVector ) : this->m_pGtcVectorCursor( p_aGtcVector )
        {

        }

        ~GtcVectorIterator()
        {

        }

    /*
    ----------------------------------------
    **** Operators of GtcVectorIterator ****
    ----------------------------------------
    */
    public:

        bool operator!=( GtcVectorIterator aGtcVectorIterator ) const
        {
            return( this->m_pGtcVectorCursor != aGtcVectorIterator.m_pGtcVectorCursor );
        }

        GtcVector& operator*() const
        {
            return( *m_pGtcVectorCursor );
        }

        GtcVectorIterator& operator++()
        {
            ++m_pGtcVectorCursor;

            return( *this );
        }
    };
/*
---------------------------------------
***** Data elements of GtcVector *****
---------------------------------------
*/
private:

    T                 *m_pGtcVectorData          ;
    GtcVectorIterator *m_pMyIterator             ;
    Tvalue             m_NumberOfElements        ;
    Tvalue             m_NumberOfEmtyElements    ;
    Tvalue m_NumberOfOccupiedElements;


/*
---------------------------------------
***** con/destructors of GtcVector ****


Des weitern solltest du die Template Attribute fixieren, und der Class einen überladenen Dynamic_Cast operator geben, damit hast du die Option die Classe auch als Parameter innerhalb von COM Interfaces zu verwenden. Zum glücklich sein fehlen jetzt nur noch bequeme Zugriffsmethoden .

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
---------------------------------------
****** Get methods of GtcVector *******
---------------------------------------
*/

    Tvalue             GetNumberOfTotalElements ( void ) const;
    Tvalue             GetNumberOfEmtyElements      ( void ) const;
    Tvalue             GetNumberOfOccupiedElements  ( void ) const;
    GtcVectorIterator *GetIterator                  ( void ) const; 

/*
---------------------------------------
****** Add methods of GtcVector *******
---------------------------------------
*/

    void AddElements( Tvalue uiNumberOfNewElements  );
    void AddElements( GtcVector const &a_GtcVector  );
    void AddElements( GtcVector const *a_pGtcVector );

/*
---------------------------------------
** Insert/Take methods of GtcVector ***
---------------------------------------
*/

    Tvalue InsertElement( T &tNewElement        )      ;
    &T     TakeElement  (Tvalue NumberOfElement) const;

/*
---------------------------------------
****** Find methods of GtcVector ******
---------------------------------------
*/

    Tvalue FindElement( T &tElement ) const;

/*
---------------------------------------
**** Special methods of GtcVector *****
---------------------------------------
*/

    void DumpAll( void );
    void Rebuilt( void );

/*
---------------------------------------
******* Operators of GtcVector ********
---------------------------------------
*/

    bool operator==(GtcVector const &a_GtcVector,
                    GtcVector const &a_GtcVector   ) const;

    bool operator!=(GtcVector const &a_GtcVector,
                    GtcVector const &a_GtcVector   ) const;


    bool operator> (GtcVector const &a_GtcVector,
                    GtcVector const &a_GtcVector   ) const;

    bool operator< (GtcVector const &a_GtcVector,
                    GtcVector const &a_GtcVector   ) const;

    bool operator>=(GtcVector const &a_GtcVector,
                    GtcVector const &a_GtcVector   ) const;

    bool operator<=(GtcVector const &a_GtcVector,
                    GtcVector const &a_GtcVector   ) const;

    bool operator==(GtcVector const &a_GtcVector,
                    GtcVector const &a_GtcVector   ) const;

    bool operator!=(GtcVector const &a_GtcVector,
                    GtcVector const &a_GtcVector   ) const;


    bool operator> (GtcVector const *a_pGtcVector,
                    GtcVector const *a_pGtcVector   ) const;

    bool operator< (GtcVector const *a_pGtcVector,
                    GtcVector const *a_pGtcVector   ) const;

    bool operator>=(GtcVector const *a_pGtcVector,
                    GtcVector const *a_pGtcVector   ) const;

    bool operator<=(GtcVector const *a_pGtcVector,
                    GtcVector const *a_pGtcVector   ) const;

    &T   operator= ( GtcVector const &a_GtcVector  );
    &T   operator= ( GtcVector const *a_pGtcVector );
    bool operator< ()


    const &T operator[](GtUInt NumberOfElement) const;
    &T       operator[](GtUInt NumberOfElement);

// usw...


So, so jetzt fehlt nur noch eine Load/Save Methode des ganzen, ich glaube ich muss dir nicht sagen, was für vorteile es hat, wenn man seien „Daten Container“ „Durably“ Binär speichern kann.

mfg

Mverick

8

18.04.2003, 19:09

Du sagtest

Zitat

Diese Prüfung kannst du aber mittels des Prärpzessors #ifndef steuern, so das sie nur im Debug Modus ausgeführt wird.

Ich sagte

Zitat

Das ist schon richtig. Allerdings sollte man SmartPointer höchstens in der Debug-Version benutzen.

Das sagt schon alles ;)

@Vecktor Klasse
Stimmt, ein memcpy währe schneller. Allerdings reagiert die Funktion nicht auf den Zuweisungsoperator. D.h. wenn man eine Klasse als Typ verwendet muss man darauf achten das sie Referenzen für Ihre Pointer benutzt da man ja nur eine Flache Kopie erstellt und keine Tiefe.

An einen Iterator habe ich auch schon gedacht. Währe wohl auch eine sehr Sinnvolle Erweiterung.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Maverick

Frischling

Beiträge: 14

Wohnort: Paderborn

Beruf: IT Fachinformatiker ANW

  • Private Nachricht senden

9

18.04.2003, 19:23

Und dafür gibt es wieder das schöne reference counting.... oder du benutzt einfach den dereferenzirugs operator * . Schöner wäre ja ein COM Based PlugInSystem. Damit hast du solche Probleme nicht mehr. Auch wenn es vielen Leuten widerstrebt ein 3D Mesch als COM Objekt zu bauen, es ist einfach besser. Ich benutze selber etwas ähnliches.

mfg

Maverick

10

18.04.2003, 19:30

Das muss der User dann aber auch wissen das er bei der Klasse nur eine Flache Kopie gemacht wird, und daher immer Referenzen verwenden muss.
Mit Schleifen ist es zwar langsamer aber dafür macht man aber auch eine Kopie wie es der User haben will, und nicht wie ich es vorschreiben ;)
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Werbeanzeige