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

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

11

09.09.2014, 16:15

Naja, ich handhabe das recht einfach...
Nicht auf dem Heap, außer es gibt einen Grund dazu.

Die zwei häufigsten Gründe dazu ist die Vermeidung das Pointer auf Objekte in Containern invalidiert werden und Vererbung.
Und sehr selten wenn der Besitzer nicht feststeht und das Objekt "std::shared_ptr"-mäßig im Raum steht oder das Objekt nicht verschiebbar ist.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

12

09.09.2014, 16:27

Ich für meinen Teil bin bei C++ doch recht häufig auf Pointer angewiesen. Mag daran liegen dass ich zu wenig Erfahrung mit C++ habe und seit langem eigentlich fast ausschließlich mit anderen Sprachen arbeite. Benötige ich Instanzen in Container, so ist es bei mir zumindest fast immer der Fall dass ich Zeiger benötige. Allein vom Design ist der Erzeuger oft nicht der Besitzer und so muss ich schon zu Zeigern greifen. Aber wie gesagt, das liegt vermutlich auch einfach an mangelnder Erfahrung was C++ betrifft.
An den Threadersteller. Wenn du dir nun Gedanken über solche Dinge machst ist das Buch "Effective C++" möglicherweise etwas für dich. Mir hat es beim Verständnis doch teilweise ganz gut weiter geholfen. Mag aber auch sein dass es da mittlerweile aktuellere tollere Bücher gibt:) Da müssen dann andere mit Ratschlägen her.
„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.“

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

13

09.09.2014, 16:43

Auf den Heap gehört generell alles, was öfters gebraucht wird aber viel zu teuer zum Kopieren ist. Ein Extrem-Beispiel für teure Kopien sind Texturen, die noch nicht im Graphik-Speicher liegen. Aber noch einfacher und besser kann man eine solche Entscheidung treffen, indem man sich fragt, wer mit einem Objekt arbeitet und wer aufräumen soll.

Zum std::shared_ptr: Beim Kopieren werden bloß zwei Pointer kopiert und ein (Atomic) Counter hochgezählt. Das ist zwar mehr als beim std::unique_ptr, aber ist doch eine sehr flinke Operation. Entsprechend sehe ich bei ihnen keinerlei Performanz-Bedenken und ziehe sie klassischen Handles und klassischen Pointern vor.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

14

09.09.2014, 17:04

Zitat von »Evrey«

Zum std::shared_ptr: Beim Kopieren werden bloß zwei Pointer kopiert und ein (Atomic) Counter hochgezählt.

Ein Atomic ist schonmal schlecht und überflüssig. Aber es kommt noch mehr: Das Hochzählen führt leicht zu einem Cachemiss.

Und ganz besonders "shared_ptr" auch dem direkten Verwenden vorzuziehen ist eine sehr sehr schlechte Idee. Besonders Cacheeffekte aber auch die einmalige Allokation können sich leicht ernsthaft auf die Performance niederschlagen.
Außerdem spricht das nicht unbedingt für deine Softwarearchitektur.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

15

09.09.2014, 17:55

Ja, der eine Cachemiss beim Schreiben ist schon wirklich tragisch. So pauschalisiert ist Deine Aussage architektonischer Unsinn. Gutes Design ist einem Cachemiss vorzuziehen, solange nicht eindeutig erwiesen ist, dass dies der Flaschenhals der Anwendung ist.
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]

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

16

09.09.2014, 19:15

Gutes Design kann unter anderem daraus bestehen, das Cachemisses vermieden werden. "std::shared_ptr" ist auch aus anderer Perspektiven meistens zweite Wahl. Die Ausnahme bestätigt die Regel, wie meistens.

Um nochmal darauf zurückzukommen, es geht um das kopieren von "std::shared_ptr". Und das häufig zu tun hat relativ wenig mit Softwaredesign an sich zu tun sondern ist einfach gesagt überflüssig. Das ist ungefähr so überflüssig wie große Texturen im RAM zu kopieren oder große Strukturen by value zu übergeben. Auch wenn beides vielleicht nicht unbedingt der Flaschenhals ist, so ist doch beides im Generellen einfach langsamer als nötig wäre und damit als generelle Empfehlung eine schlechte Idee. Wenn man einen "shared_ptr" kopieren muss dann soll man das tun. Ein "std::shared_ptr" ist dafür da mehrere Besitzer zu haben und muss daher irgendwie kopiert werden. Das ist auch total in Ordnung, aber man sollte wissen, dass es einen deutlichen Overhead-Unterschied macht und dass man es eben nur machen sollte, wenn es notwendig ist. Wenn man eine Textur kopieren möchte, um zum Beispiel bei Änderungen das Original noch zu haben, soll man das tun. Aber das heißt nicht, dass man jetzt alle Texturen kopieren sollte, bloß weil es in dieser Anwendung auch so vlt. noch schnell genug geht. Wenn es vermeidbar ist lässt man das kopieren sowohl bei den Texturen wie auch bei "std::shared_ptr" bleiben. :)

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

17

09.09.2014, 20:16

Ich habe auch nirgends dazu aufgerufen, std::shared_ptr durch die Gegend zu kopieren. Begonnen hat es mit der Aussage, dass std::unique_ptr performanter als std::shared_ptr sei. Ich habe dann verdeutlicht, wo die Unterschiede in der Performanz bestehen, und dass die Dereferenzierung bei beiden Pointern identisch schnell ist. Natürlich sollte man nicht ständig std::shared_ptr durch die Gegend kopieren. Nicht wegen Cache Misses, die haste in Spielen eh ständig und überall, sondern wegen der ständig lahmgelegten MMUs, weil Atomics. Deswegen werden std::shared_ptr auch wo möglich per Referenz durchgereicht, bis sie am Zielort ankommen, wo sie wirklich-wirklich kopiert werden müssen.

Ja, Referenzen sind eine weitere Dereferenzierungs-Umleitung, aber auch die ist verhältnismäßig gering. Kritisch werden sie erst in Hochleistungs-Anwendungen wie VMs und GCs, aber da hat man eh' Handles der Marke Eigenbau.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

18

10.09.2014, 01:32

Mir fällt zu dem Thema der allseitsbekannte Spruch:
"Don't optimize yet" ein.

Finde man muss sich den viel öfter vor Augen führen. Viel wichtiger ist es erstmal, dass das Ding stabil(!!) läuft und zuverlässig ist. Und dann kann man auch optimieren. Wird wohl heutzutage kaum eine Anwendung geben, bei der man von Anfang an penibel darauf achten muss, dass alles optimal performant ist. Und wenn doch weiß man meistens auch schon warum und kann dementsprechend Bottlenecks vermeiden. Für alles andere siehe Zitat oben.
WIP Website: kevinheese.de

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

19

10.09.2014, 13:59

Ich möchte an der Stelle nochmal auf diesen Artikel hier verweisen was die Problematik dazu meiner Meinung nach gut darstellt und sich mit meiner Erfahrung deckt:
http://www.nosid.org/about-premature-optimization.html

Ist natürlich auch nicht überzubewerten. Und Stablität ist auch sehr wichtig. Hat damit aber sehr wenig zu tun.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (10.09.2014, 14:06)


GMoney597

Frischling

Beiträge: 48

Wohnort: Roth

Beruf: Verwaltungsfachangesteller (Stadtverwaltung), Fitness-Trainer und Muay-Thai-Trainer

  • Private Nachricht senden

20

10.09.2014, 14:18

ich bin alles andere als ein Programmierer vom Fach und von logischem Denken ganz weit weg

ich stelle mir eigentlich immer wieder die Frage, ob ich nicht irgendwie vergesse mit Zeigern zu arbeiten - und wenn es auch nicht ganz in dieses Thema fällt,
so scheint mir doch, dass die Antwort schnell gefunden sein dürfte.

Bei allen Projekten, die ich bisher angefangen habe (nie etwas großes) habe ich immer nur mit Referenzen gearbeitet.
Ist das jetzt doof, schlimm oder schlechter Stil oder sind die Referenzen eine gute Alternative zu Pointern (jeglicher Natur).
Ich habe zwar den Unterschied begriffen aber ich bin nie dahinter gestiegen, wann es für mich sinnvoll sein könnte einen Zeiger, statt einer Referenz
weiterzureichen.

:hmm: :thinking:

Werbeanzeige