PART 2 ยท ๊ฐ•์˜ 4/4

Cluster GC

FUObjectCluster, ClusterRoot, ํด๋Ÿฌ์Šคํ„ฐ ๋‹จ์œ„ ์ˆ˜์ง‘์œผ๋กœ GC ์ˆœํšŒ ๋น„์šฉ์„ ๋Œ€ํญ ์ค„์ด๋Š” ์ตœ์ ํ™” ๊ธฐ๋ฒ•

SECTION 01

Cluster GC์˜ ๊ฐœ๋…

๊ด€๋ จ ๊ฐ์ฒด๋“ค์„ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ฌถ์–ด GC ํšจ์œจ์„ ๋†’์ด๋Š” ๊ธฐ๋ฒ•

์™œ Cluster GC์ธ๊ฐ€?

๋Œ€๊ทœ๋ชจ ์—์…‹(์˜ˆ: UStaticMesh)์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ˆ˜์‹ญ ๊ฐœ์˜ ์„œ๋ธŒ ๊ฐ์ฒด(LOD ๋ฐ์ดํ„ฐ, ๋จธํ‹ฐ๋ฆฌ์–ผ ์Šฌ๋กฏ ๋“ฑ)๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ด๋“ค์„ ๊ฐœ๋ณ„์ ์œผ๋กœ GC์—์„œ ์ถ”์ ํ•˜๋ฉด ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. Cluster GC๋Š” ์ด๋“ค์„ ํ•˜๋‚˜์˜ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด, ๋ฃจํŠธ๋งŒ ๊ฒ€์‚ฌํ•˜๋ฉด ์ „์ฒด์˜ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ์„ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋… // ํด๋Ÿฌ์Šคํ„ฐ ์—†์ด: ๊ฐœ๋ณ„ ๊ฐ์ฒด ์ „๋ถ€ ์ˆœํšŒ UStaticMesh โ† GC ๊ฒ€์‚ฌ UStaticMeshLOD_0 โ† GC ๊ฒ€์‚ฌ UStaticMeshLOD_1 โ† GC ๊ฒ€์‚ฌ UStaticMeshLOD_2 โ† GC ๊ฒ€์‚ฌ UBodySetup โ† GC ๊ฒ€์‚ฌ UMaterialSlot_0 โ† GC ๊ฒ€์‚ฌ UMaterialSlot_1 โ† GC ๊ฒ€์‚ฌ // 7๋ฒˆ์˜ GC ๊ฒ€์‚ฌ // ํด๋Ÿฌ์Šคํ„ฐ ์‚ฌ์šฉ: ๋ฃจํŠธ๋งŒ ๊ฒ€์‚ฌ [Cluster: UStaticMesh] โ† GC ๊ฒ€์‚ฌ 1๋ฒˆ! โ”œโ”€โ”€ UStaticMeshLOD_0 (ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„) โ”œโ”€โ”€ UStaticMeshLOD_1 (ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„) โ”œโ”€โ”€ UStaticMeshLOD_2 (ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„) โ”œโ”€โ”€ UBodySetup (ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„) โ”œโ”€โ”€ UMaterialSlot_0 (ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„) โ””โ”€โ”€ UMaterialSlot_1 (ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„) // 1๋ฒˆ์˜ GC ๊ฒ€์‚ฌ โ†’ 6๋ฐฐ ํšจ์œจ!
๊ธฐ๋ณธ ํด๋Ÿฌ์Šคํ„ฐ๋ง ๋Œ€์ƒ

UE5์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํด๋ž˜์Šค: UStaticMesh, USkeletalMesh, UTexture, UMaterial, UBlueprint, UAnimSequence ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ ์—์…‹ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. gc.CreateGCClusters=1(๊ธฐ๋ณธ๊ฐ’)๋กœ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

SECTION 02

FUObjectCluster ๊ตฌ์กฐ

ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋‚ด๋ถ€ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ๊ด€๋ฆฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜

FUObjectCluster ๋‚ด๋ถ€

์—”์ง„ ์†Œ์Šค (๊ฐ„๋žตํ™”) struct FUObjectCluster { // ํด๋Ÿฌ์Šคํ„ฐ ๋ฃจํŠธ ๊ฐ์ฒด์˜ GUObjectArray ์ธ๋ฑ์Šค int32 RootIndex; // ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„ ๊ฐ์ฒด๋“ค์˜ ์ธ๋ฑ์Šค ๋ชฉ๋ก TArray<int32> Objects; // ์™ธ๋ถ€ ์ฐธ์กฐ (ํด๋Ÿฌ์Šคํ„ฐ ๋ฐ–์—์„œ ๋ฉค๋ฒ„๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒฝ์šฐ) TArray<int32> ReferencedClusters; // ์ด ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ๋“ค TArray<int32> ReferencedByClusters; // ์™ธ๋ถ€์—์„œ ์ง์ ‘ ์ฐธ์กฐ๋˜๋Š” ๋ฉค๋ฒ„ (Mutable ์ฐธ์กฐ) TArray<int32> MutableObjects; }; // ๊ธ€๋กœ๋ฒŒ ํด๋Ÿฌ์Šคํ„ฐ ๋งค๋‹ˆ์ € class FGCClusterManager { TArray<FUObjectCluster> Clusters; // ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ int32 CreateCluster(int32 RootObjectIndex); // ํด๋Ÿฌ์Šคํ„ฐ ํ•ด์ฒด void DissolveCluster(int32 ClusterIndex); // ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฉค๋ฒ„ ์ถ”๊ฐ€ void AddObjectToCluster(int32 ClusterIndex, int32 ObjectIndex); };

ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ ์กฐ๊ฑด

์กฐ๊ฑด ์„ค๋ช…
CanBeClusterRoot() ํด๋ž˜์Šค๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ ๋ฃจํŠธ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š”์ง€ (๊ฐ€์ƒ ํ•จ์ˆ˜)
CanBeInCluster() ๋ฉค๋ฒ„๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ์— ํฌํ•จ๋  ์ˆ˜ ์žˆ๋Š”์ง€
์™ธ๋ถ€ ์ฐธ์กฐ ์—†์Œ ๋ฉค๋ฒ„๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ ์™ธ๋ถ€์—์„œ ์ฐธ์กฐ๋˜์ง€ ์•Š์•„์•ผ ํ•จ
gc.CreateGCClusters=1 ๊ธ€๋กœ๋ฒŒ ํด๋Ÿฌ์Šคํ„ฐ๋ง ํ™œ์„ฑํ™”
SECTION 03

์ปค์Šคํ…€ ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌํ˜„

์‚ฌ์šฉ์ž ์ •์˜ UObject์— ํด๋Ÿฌ์Šคํ„ฐ๋ง์„ ์ ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

ํด๋Ÿฌ์Šคํ„ฐ ๋ฃจํŠธ ์„ ์–ธ

C++ UCLASS() class UMyAsset : public UObject { GENERATED_BODY() // ํด๋Ÿฌ์Šคํ„ฐ ๋ฃจํŠธ ๊ฐ€๋Šฅ ์„ ์–ธ virtual bool CanBeClusterRoot() const override { return true; } // ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ ์‹œ ๋ฉค๋ฒ„ ๋“ฑ๋ก virtual void CreateCluster() override { Super::CreateCluster(); // ์„œ๋ธŒ์˜ค๋ธŒ์ ํŠธ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„๋กœ ์ถ”๊ฐ€ if (SubDataA) SubDataA->AddToCluster(this); if (SubDataB) SubDataB->AddToCluster(this); for (UObject* Child : ChildObjects) { if (Child && Child->CanBeInCluster()) Child->AddToCluster(this); } } private: UPROPERTY() UMySubData* SubDataA; UPROPERTY() UMySubData* SubDataB; UPROPERTY() TArray<UObject*> ChildObjects; };
ํด๋Ÿฌ์Šคํ„ฐ ํ•ด์ฒด ์ฃผ์˜

ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„์— ๋Œ€ํ•œ ์™ธ๋ถ€ ์ฐธ์กฐ๊ฐ€ ์ƒ๊ธฐ๋ฉด ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ํ•ด์ฒด(dissolve)๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ UPROPERTY๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•˜๋ฉด ํ•ด๋‹น ๋ฉค๋ฒ„๋Š” ๋…๋ฆฝ์ ์œผ๋กœ GC ์ถ”์ ์ด ํ•„์š”ํ•ด์ ธ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๋ถ„๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” GC ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ค๋ฏ€๋กœ ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„์— ๋Œ€ํ•œ ์™ธ๋ถ€ ์ฐธ์กฐ๋ฅผ ์ตœ์†Œํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

SECTION 04

ํด๋Ÿฌ์Šคํ„ฐ GC ์„ฑ๋Šฅ ์˜ํ–ฅ

ํด๋Ÿฌ์Šคํ„ฐ๋ง์ด GC ์„ฑ๋Šฅ์— ๋ฏธ์น˜๋Š” ์‹ค์งˆ์  ํšจ๊ณผ

์„ฑ๋Šฅ ์ธก์ • ๊ฒฐ๊ณผ

์‹œ๋‚˜๋ฆฌ์˜ค ํด๋Ÿฌ์Šคํ„ฐ OFF ํด๋Ÿฌ์Šคํ„ฐ ON ๊ฐœ์„ ์œจ
UObject 100K๊ฐœ 15ms 8ms ~47%
๋Œ€๊ทœ๋ชจ ์˜คํ”ˆ์›”๋“œ 25ms 10ms ~60%
์—๋””ํ„ฐ (๋งŽ์€ ์—์…‹) 50ms 15ms ~70%
ํด๋Ÿฌ์Šคํ„ฐ ๋ชจ๋‹ˆํ„ฐ๋ง

๋‹ค์Œ ๋ช…๋ น์–ด๋กœ ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • gc.PrintClusterInfo - ๋ชจ๋“  ํด๋Ÿฌ์Šคํ„ฐ ์ •๋ณด ์ถœ๋ ฅ
  • obj list class=StaticMesh -gc - GC ๊ด€๋ จ ์ •๋ณด์™€ ํ•จ๊ป˜ ๋ชฉ๋ก ์ถœ๋ ฅ
  • gc.CreateGCClusters 0/1 - ๋Ÿฐํƒ€์ž„ ํด๋Ÿฌ์Šคํ„ฐ ํ† ๊ธ€ (ํ…Œ์ŠคํŠธ์šฉ)
SUMMARY

ํ•ต์‹ฌ ์š”์•ฝ

์ด ๊ฐ•์˜์—์„œ ๋ฐฐ์šด ๋‚ด์šฉ
  • Cluster GC๋Š” ๊ด€๋ จ ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์–ด GC ์ˆœํšŒ ๋น„์šฉ์„ ํฌ๊ฒŒ ์ค„์ž…๋‹ˆ๋‹ค
  • FUObjectCluster๋Š” ๋ฃจํŠธ ์ธ๋ฑ์Šค, ๋ฉค๋ฒ„ ๋ชฉ๋ก, ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„ ์ฐธ์กฐ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค
  • CanBeClusterRoot()๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์ปค์Šคํ…€ ํด๋ž˜์Šค์— ํด๋Ÿฌ์Šคํ„ฐ๋ง์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
  • ํด๋Ÿฌ์Šคํ„ฐ ๋ฉค๋ฒ„์— ์™ธ๋ถ€ ์ฐธ์กฐ๊ฐ€ ์ƒ๊ธฐ๋ฉด ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ํ•ด์ฒด๋˜์–ด ์„ฑ๋Šฅ์ด ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค
  • ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ํด๋Ÿฌ์Šคํ„ฐ GC๋Š” 47~70%์˜ GC ์‹œ๊ฐ„ ์ ˆ๊ฐ ํšจ๊ณผ๋ฅผ ์ค๋‹ˆ๋‹ค
PRACTICE

๋„์ „ ๊ณผ์ œ

๋ฐฐ์šด ๋‚ด์šฉ์„ ์ง์ ‘ ์‹ค์Šตํ•ด๋ณด์„ธ์š”

์‹ค์Šต 1: GC Cluster ์ƒ์„ฑ ๋ฐ ํ™•์ธ

CanBeClusterRoot()์™€ CanBeInCluster()๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•œ ์ปค์Šคํ…€ UObject๋ฅผ ๋งŒ๋“ค๊ณ , CreateCluster()๋กœ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ํ˜•์„ฑํ•˜์„ธ์š”. obj cluster ๋ช…๋ น์–ด๋กœ ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ์„ ํ™•์ธํ•˜๊ณ , ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด ๊ฐœ๋ณ„ ๊ฐ์ฒด์˜ GC ๋™์ž‘์„ ํ…Œ์ŠคํŠธํ•˜์„ธ์š”.

์‹ค์Šต 2: ํด๋Ÿฌ์Šคํ„ฐ ํ•ด์ œ์™€ GC ์˜ํ–ฅ ์ธก์ •

๋Œ€๋Ÿ‰์˜ UStaticMesh ์—์…‹์„ ๋กœ๋“œํ•˜์—ฌ GC ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์ž๋™์œผ๋กœ ํ˜•์„ฑ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์„ธ์š”. DissolveCluster ์ „ํ›„์˜ stat gc Mark ์‹œ๊ฐ„์„ ๋น„๊ตํ•˜์—ฌ ํด๋Ÿฌ์Šคํ„ฐ๋ง์˜ ์„ฑ๋Šฅ ํšจ๊ณผ๋ฅผ ์ˆ˜์น˜๋กœ ํ™•์ธํ•˜์„ธ์š”.

์‹ฌํ™” ๊ณผ์ œ: ์—์…‹ ํด๋Ÿฌ์Šคํ„ฐ๋ง ์ตœ์ ํ™” ์ „๋žต

์‹ค์ œ ๊ฒŒ์ž„ ๋ ˆ๋ฒจ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์—์…‹๋“ค์„ ๋ถ„์„ํ•˜์—ฌ ์ตœ์ ์˜ ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ์„ ์„ค๊ณ„ํ•˜์„ธ์š”. ํ•จ๊ป˜ ๋กœ๋“œ/์–ธ๋กœ๋“œ๋˜๋Š” ์—์…‹ ๊ทธ๋ฃน์„ ์‹๋ณ„ํ•˜๊ณ , ์ปค์Šคํ…€ ํด๋Ÿฌ์Šคํ„ฐ ๋ฃจํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ GC Mark ์‹œ๊ฐ„ ๊ฐ์†Œ ํšจ๊ณผ๋ฅผ ์ธก์ •ํ•˜์„ธ์š”.