Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

04.05.2017, 22:50

Memory-Alignment in Embeded Garbage Collector?

Hallo Leute :)

Ich hätte da mal eine Frage an Euch und zwar:

Es gibt ja schon einige Implementierungen von C/C++ die einen "Embedded GC" ermöglichen. (Boehm GC)

Und mich würde interessieren, weil ich das nirgends finden konnte, vielleicht habe ich auch einfach beim Lesen der englischen Texte das überlesen^^.

Weil es ist ja so, dass "malloc(...)" zwar einen Pointer zurückgibt der aligned ist, aber nur für einfach Typen, (int, double, etc..)

aber nicht für ALLE Systeme, wie bei Grafikgeschichten kann es z.b ja vorkommen, dass die mal eine striktere Alignmentregel brauchen.

Würde mich echt interessieren, ob da jmd was zu weiß :)

Mfg

JP

2

04.05.2017, 22:56

Zuerst: Was ist C/C++? C++ und C sind ein sehr ganzes Stück verschieden! Malloc (oder auch new) in C++ zu benutzen oder überhaupt C in C++ programmieren zu wollen grenzt an Wahnsinn. ;)

Malloc richtet sich beim Alignment nach dem des größten eingebauten Datentyps, da ja schließlich sämtliche komplexen Typen aus diesen bestehen. Für die Angabe einer exakten Ausrichtung gibt es std::aligned_storage in C++. Was hat das mit einem GC zu tun?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Techel« (04.05.2017, 23:21)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

05.05.2017, 06:25

Ganz ehrlich, eine der großen Stärken von C++11 und folgenden ist, dass Memory-Management sicher, einfach und vorhersagbar ist. Memory-Management ist genauso sicher und einfach geworden wie in GC-basierten Sprachen, hat aber einen gewaltigen Vorteil. Ich wüsste nicht, wieso ich diesen Vorteil durch einen GC vernichten wollen würde.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

4

05.05.2017, 12:59

@BlueCobold
Das ist ein Abschnitt aus einer damaligen Diskussion über GC-Management, der Inhalt entspricht einer txt-file auf meinem rechner.

The advantages of a GC over manual memory management are numerous:

It makes for cleaner code, there's no need to free something, the gc does this
No overhead of destructor calls and recursive freeing
No need to deal with ownership issues
No heap fragmentation (Boehm doesn't do this, but we're looking into alternative gc's that can)
Never access an already freed object
A concurrent copying gc can actually improve allocation time.

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

5

05.05.2017, 13:32

Jaja, hübsch kopiert und so, leider ziemlich veraltet. Sagen wir einfach: wenn Du GC willst, nimm kein C++.

Alignment ist davon ja unabhängig. Und da müssten die selben Regeln gelten wie für alle Typen in C++. Techel hat das bereits beantwortet.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

05.05.2017, 14:14

It makes for cleaner code, there's no need to free something, the gc does this
Smart-Pointer in C++ ebenfalls. Der Vorteil liegt hier bei Smart-Pointern, denn man weiß sogar ganz genau wann es freigegeben wird.

No overhead of destructor calls and recursive freeing
Das ist schlicht falsch. Gelöscht werden muss sowieso, notfalls auch rekursiv und Destruktoren müssen trotzdem gerufen werden. Selbst in Java und C# gibt's das, nennt sich Finalizer. Braucht man nicht so oft und auch in C++ sind sie seit 11 fast absolet geworden - zumindest genauso selten wie Finalizer in managed Sprachen. Solange wie Datenstrukturen verschachtelt sind, muss auch 'rekursiv' gelöscht werden. Jede Rekursion lässt sich auch als Schleife ausdrücken und wenn es also nur um die Rekursion als Fakt geht, dann ist der Punkt unsinnig. Verschachtelte Datentypen müssen inklusive aller ihrer Kinder aufgeräumt werden. Ob das nun per Rekursion oder per Schleife erfolgt, ist völlig unerheblich.

No need to deal with ownership issues
Anders ausgedrückt: Hirn abschalten beim Programmieren, zirkuläre Abhängigkeiten bauen und schon gibt der GC nie wieder etwas frei. Folgerichtig muss man sich darüber in sauberen Programmen basierend auf GC-Sprachen auch Gedanken machen. Also so wie's da steht im Grunde falsch.

No heap fragmentation (Boehm doesn't do this, but we're looking into alternative gc's that can)
Ja, das kann managed memory prima, allerdings kann das kein GC in C++, weil es rohe/unmanaged Pointer gibt.

Never access an already freed object
Sowas ähnliches gibt's auch in GC-Sprachen. Nennt sich NullPointerException. (Ja, es gibt durchaus weak References in GC-Sprachen, jede hat da so ihr eigenes Konzept)

A concurrent copying gc can actually improve allocation time.
Für schnellere Allocations in C++ braucht man keinen GC und das hat mit einem GC auch nichts zu tun, denn "allocation" ist das Gegenteil, bzw. andere Ende von "Garbage".
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »BlueCobold« (05.05.2017, 14:23)


7

05.05.2017, 15:58

@Schrompf

Ich habe ja gesagt, dass das nicht mein Werk war, sondern das ich mir diese damalige Unterhaltung vor einer Zeit abgespeichert habe und das ich Euch das nur zeigen wollte, also kein gemekere bitte.

@BlueCobold
Zu deiner Antwort auf 2)

Das mit der Rekursion ist glaube ich so gemeint, dass man es nicht explicit im Code machen muss, der GC wird das über sein Tracing verfahren machen, also abgekoppelt von deinem Blickfeld und somit sauberer Code entsteht.

Zu deiner Antwort auf 4)
Denke es geht, soweit ich weiß funktionieren nämlich diese Embeded-GC's anders als totalle managed-GC's wie in Java/C#

Zu deiner Antwort auf 6)
Also, der Embeded-GC von Boehm, übernimmt sowohl die Allokation als auch das Finalisieren der Instanzen, nämlich über:
GC_Malloc(...), GC_Malloc_Atomic(...), GC_Free(..)

8

05.05.2017, 17:04

C++ mit einem GC zu benutzen, ist meiner Meinung nach Schwachsinn. Zwar gibt es durchaus Fälle, bei denen ein anderer als der Standardallokator benutzt werden sollte, aber ein GC hat meiner Meinung nach den eigentlichen Sinn verfehlt, dass ein Programmierer sich *nicht* um die Verwaltung von Objektspeicher kümmern muss. Stattdessen tut man tatsächlich das Gleiche wie in C auch, nämlich seine Ressourcen mit close() oder dispose() manuell oder halbautomatisch mit using oder try-with-resources in Java oder C# freizugeben. Das kann C++ eindeutig besser.

Mit Rekursion ist der (durchaus valide) Umstand gemeint, dass Member durch das Parentobjekt zerstört werden. Sieh dir beispielsweise eine naive Implementation einer verketteten Liste an. Jedes Element besitzt das Folgende durch einen std::unique_ptr. Folglich werden alle Elemente bei Zerstörung der Liste rekursiv gelöscht, was bei großen Listen einen Stapelüberlauf aufgrund zu großer Rekursionstiefe zur Folge hat.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

9

05.05.2017, 17:08

Das mit der Rekursion ist glaube ich so gemeint, dass man es nicht explicit im Code machen muss, der GC wird das über sein Tracing verfahren machen, also abgekoppelt von deinem Blickfeld und somit sauberer Code entsteht.

Hat du dir C++ 11 denn mal angesehen? Ich kann mich nicht dran erinnern wann ich das letzte mal delete genutzt habe und selbst irgendetwas aufräumen muss ich auch nichts. Dafür gibt es ja im Notfall die Smartpointer. Und wenn ich Rekursive oder Verschachtelte Typen habe werden die bei mir ganz normal und ohne Mehrarbeit von meiner Seite aufgeräumt.
Denke es geht, soweit ich weiß funktionieren nämlich diese Embeded-GC's anders als totalle managed-GC's wie in Java/C#

Da gibt es verschiedene Ansätze. Ein Ansatz ist jeden Wert im Speicher als Adresse anzusehen. Die Speicherzellen deren Adresse nicht als Wert im Speicher vorkommen können dann gelöscht werden. Das löscht unter Umständen viele viele Speicherstellen nicht. Kann gut sein dass es da mittlerweile neue, bessere Ansätze gibt.
Also, der Embeded-GC von Boehm, übernimmt sowohl die Allokation als auch das Finalisieren der Instanzen, nämlich über:
GC_Malloc(...), GC_Malloc_Atomic(...), GC_Free(..)

Aus welchem Grund soll GC_Malloc(...) schneller sein als ein einfaches new, selbst wenn das in make_unique oder whatever verpackt ist? Das kann ich mir so nicht vorstellen. Wenn du da mehr Infos zu hast, gerne her damit.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

10

05.05.2017, 23:35

Nuja, zumindest new ist in GC-Sprachen tatsächlich schneller. Wenn Du aus einem Wegwerf-Heap schöpfen kannst, ist eine Allokation nur noch ein atomic_int.fetch_and_add(). Und das Aufräumen hinterher *kann* auch schneller sein, je nach Implementation. C++ hat seinen Performance-Vorteil primär daher, dass a) das Erzeugen und Aufräumen deterministisch passiert, also Du als Programmierer darüber bestimmen kannst. Und das willst Du, wenn's kritisch wird. Und wenn's nicht kritisch wird, nimmst Du was Anderes als C++. Außerdem kann b) C++ vieles auf dem Stack oder lokal allokieren, oder per Custom Allocator massive Geschwindigkeitsvorteile aus Kontextwissen ziehen. Auch das ist - wie gesagt - sehr wichtig, wenn's kritisch wird. Und wenn's nicht kritisch wird, nimmst Du kein C++.

Daher ist auch die Idee, C++ mit einer GC zu benutzen, nur übersichtlich clever. Leute, die aus der Java-Welt kommend alles mit new allokieren, produzieren in C++ schlimmeren Code als in Java. Zum Einen leakt das dann doch gern mal hier und da, weil das idiomatische C++ nunmal heutzutage quasi kein direktes new mehr braucht. Zum Anderen ist solcher Code langsamer als in Java, weil Allokationen in C++ nunmal teurer sind als in Java. In Java fehlen Dir dagegen die Mittel, sie ganz zu vermeiden.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Werbeanzeige