Cluster GC
FUObjectCluster, ClusterRoot, ํด๋ฌ์คํฐ ๋จ์ ์์ง์ผ๋ก GC ์ํ ๋น์ฉ์ ๋ํญ ์ค์ด๋ ์ต์ ํ ๊ธฐ๋ฒ
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(๊ธฐ๋ณธ๊ฐ)๋ก ํ์ฑํ๋ฉ๋๋ค.
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 |
๊ธ๋ก๋ฒ ํด๋ฌ์คํฐ๋ง ํ์ฑํ |
์ปค์คํ ํด๋ฌ์คํฐ ๊ตฌํ
์ฌ์ฉ์ ์ ์ UObject์ ํด๋ฌ์คํฐ๋ง์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ
ํด๋ฌ์คํฐ ๋ฃจํธ ์ ์ธ
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 ์ฑ๋ฅ์ ์ ํ์ํค๋ฏ๋ก ํด๋ฌ์คํฐ ๋ฉค๋ฒ์ ๋ํ ์ธ๋ถ ์ฐธ์กฐ๋ฅผ ์ต์ํํด์ผ ํฉ๋๋ค.
ํด๋ฌ์คํฐ 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- ๋ฐํ์ ํด๋ฌ์คํฐ ํ ๊ธ (ํ ์คํธ์ฉ)
ํต์ฌ ์์ฝ
- Cluster GC๋ ๊ด๋ จ ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ์ด GC ์ํ ๋น์ฉ์ ํฌ๊ฒ ์ค์ ๋๋ค
- FUObjectCluster๋ ๋ฃจํธ ์ธ๋ฑ์ค, ๋ฉค๋ฒ ๋ชฉ๋ก, ํด๋ฌ์คํฐ ๊ฐ ์ฐธ์กฐ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค
- CanBeClusterRoot()๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ์ฌ ์ปค์คํ ํด๋์ค์ ํด๋ฌ์คํฐ๋ง์ ์ ์ฉํ ์ ์์ต๋๋ค
- ํด๋ฌ์คํฐ ๋ฉค๋ฒ์ ์ธ๋ถ ์ฐธ์กฐ๊ฐ ์๊ธฐ๋ฉด ํด๋ฌ์คํฐ๊ฐ ํด์ฒด๋์ด ์ฑ๋ฅ์ด ์ ํ๋ฉ๋๋ค
- ๋๊ท๋ชจ ํ๋ก์ ํธ์์ ํด๋ฌ์คํฐ GC๋ 47~70%์ GC ์๊ฐ ์ ๊ฐ ํจ๊ณผ๋ฅผ ์ค๋๋ค
๋์ ๊ณผ์
๋ฐฐ์ด ๋ด์ฉ์ ์ง์ ์ค์ตํด๋ณด์ธ์
CanBeClusterRoot()์ CanBeInCluster()๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ ์ปค์คํ UObject๋ฅผ ๋ง๋ค๊ณ , CreateCluster()๋ก ํด๋ฌ์คํฐ๋ฅผ ํ์ฑํ์ธ์. obj cluster ๋ช ๋ น์ด๋ก ํด๋ฌ์คํฐ ๊ตฌ์ฑ์ ํ์ธํ๊ณ , ํด๋ฌ์คํฐ ๋ด ๊ฐ๋ณ ๊ฐ์ฒด์ GC ๋์์ ํ ์คํธํ์ธ์.
๋๋์ UStaticMesh ์์ ์ ๋ก๋ํ์ฌ GC ํด๋ฌ์คํฐ๊ฐ ์๋์ผ๋ก ํ์ฑ๋๋ ๊ฒ์ ํ์ธํ์ธ์. DissolveCluster ์ ํ์ stat gc Mark ์๊ฐ์ ๋น๊ตํ์ฌ ํด๋ฌ์คํฐ๋ง์ ์ฑ๋ฅ ํจ๊ณผ๋ฅผ ์์น๋ก ํ์ธํ์ธ์.
์ค์ ๊ฒ์ ๋ ๋ฒจ์์ ์ฌ์ฉ๋๋ ์์ ๋ค์ ๋ถ์ํ์ฌ ์ต์ ์ ํด๋ฌ์คํฐ ๊ตฌ์ฑ์ ์ค๊ณํ์ธ์. ํจ๊ป ๋ก๋/์ธ๋ก๋๋๋ ์์ ๊ทธ๋ฃน์ ์๋ณํ๊ณ , ์ปค์คํ ํด๋ฌ์คํฐ ๋ฃจํธ๋ฅผ ๊ตฌํํ์ฌ GC Mark ์๊ฐ ๊ฐ์ ํจ๊ณผ๋ฅผ ์ธก์ ํ์ธ์.