| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 리눅스
- 성능 최적화
- 렌더링파이프라인
- ecs
- 유니티
- 배칭
- 에셋번들
- SQL시험
- unity
- ubuntu
- 스레드
- GPU 병목
- URP
- c#
- SRP
- rocky linux
- dots
- 메모리
- SQLD
- 픽셀 쉐이더
- 멀티스레드
- AssetBundle
- 리눅스 명령어
- 유니티 최적화
- 프로세스
- 쉐이더
- 버텍스 쉐이더
- 정렬
- 디자인패턴
- HDRP
Archives
- Today
- Total
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 리눅스
- 성능 최적화
- 렌더링파이프라인
- ecs
- 유니티
- 배칭
- 에셋번들
- SQL시험
- unity
- ubuntu
- 스레드
- GPU 병목
- URP
- c#
- SRP
- rocky linux
- dots
- 메모리
- SQLD
- 픽셀 쉐이더
- 멀티스레드
- AssetBundle
- 리눅스 명령어
- 유니티 최적화
- 프로세스
- 쉐이더
- 버텍스 쉐이더
- 정렬
- 디자인패턴
- HDRP
Archives
- Today
- Total
Let's Girin!
[Unity] DOTS - Collections 및 Mathematics 본문
1. Collections 패키지
Collections 패키지는 Unity의 관리되지 않는 컬렉션 타입을 제공한다.
"관리되지 않는" 이라는 것은 C# 런타임이나 가비지 컬렉터가 이 컬렉션들의 메모리 관리를 하지 않는다는 의미다.
즉, 사용자가 명시적으로 메모리를 관리해야 하므로 성능을 높이는 데 유리하지만, 잘못된 메모리 관리는 문제를 일으킬 수 있다.
🔹관리되지 않는 컬렉션 특징
- 메모리 관리 : Collections 패키지는 자동으로 메모리를 관리하지 않기 때문에, 사용자는 더 이상 필요하지 않은 컬렉션을 직접 Dispose() 메서드를 호출하여 해제해야 한다.
- 가비지 컬렉션 부하 없음 : 관리되지 않는 컬렉션은 가비지 컬렉터에 의해 추적되지 않기 때문에, 가비지 컬렉션 부하를 줄이고, 성능을 높이는 데 도움을 준다.
- 게임의 성능 최적화 : 특히 잡(Job) 시스템과 버스트 컴파일러와 결합되어, 성능을 극대화할 수 있다.
🔹컬렉션 타입 분류
✔️ Native 컬렉션
- Native로 시작하는 컬렉션 타입은 안전성 검사를 수행한다. 이러한 컬렉션은 메모리 누수나 스레드 안전성 문제를 미리 방지할 수 있다.
- 안전성 검사 : 컬렉션이 적절히 해제되지 않은 경우, 컬렉션이 스레드 안전하지 않은 방식으로 사용된 경우
ex. NativeList, NativeHashMap
using Unity.Collections;
// Allocator.Temp : 한 프레임 이내 사용.
// Allocator.TempJob: 4프레임 이내 사용(잡 실행 동안).
// Allocator.Persistent: 장기 보관.
var nativeList = new NativeList<int>(Allocator.Temp);
nativeList.Add(10);
nativeList.Add(20);
nativeList.Add(30);
for (int i = 0; i < nativeList.Length; i++)
Debug.Log(nativeList[i]);
// 안전성 검사: 해제하지 않으면 메모리 누수 경고 발생.
nativeList.Dispose();
var nativeMap = new NativeHashMap<int, float>(16, Allocator.TempJob);
nativeMap.Add(1, 1.5f);
nativeMap.Add(2, 3.0f);
if (nativeMap.TryGetValue(1, out float val))
Debug.Log($"key 1의 값: {val}");
// 스레드 안전성 위반 시 에디터에서 즉시 예외 발생.
nativeMap.Dispose();
✔️ Unsafe 컬렉션
- Unsafe로 시작하는 컬렉션은 안전성 검사를 하지 않는다. 이러한 컬렉션은 더 유연하게 사용할 수 있지만, 잘못 사용하면 메모리 문제나 스레드 안전성 문제를 초래할 수 있다.
- 안전성 보장 없음 : 개발자가 안전하게 사용할 책임이 있다.
ex. UnsafeList, UnsafeHashMap
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
// 안전성 검사 없음.
var unsafeList = new UnsafeList<int>(8, Allocator.Temp);
unsafeList.Add(100);
unsafeList.Add(200);
for (int i = 0; i < unsafeList.Length; i++)
Debug.Log(unsafeList[i]);
// 해제하지 않아도 경고 없음 → 메모리 누수 위험.
unsafeList.Dispose();
var unsafeMap = new UnsafeHashMap<int, float>(16, Allocator.TempJob);
unsafeMap.Add(1, 9.9f);
unsafeMap.Add(2, 7.7f);
// 잘못된 스레드에서 접근해도 예외 발생 안 함 → 데이터 오염 가능.
if (unsafeMap.TryGetValue(2, out float result))
Debug.Log($"key 2의 값: {result}");
unsafeMap.Dispose();
✔️ 기타 컬렉션
- Native와 Unsafe로 시작하지 않는 타입은 작은 구조체 타입으로, 포인터가 없기 때문에 메모리 할당이 필요하지 않다. 이들 컬렉션은 메모리 해제도 필요하지 않으며, 스레드 안전성 문제도 발생하지 않는다.
// 스택에 직접 올라가는 구조체 — 메모리 할당·해제 불필요.
// 포인터 없음 → 스레드 안전성 문제 없음.
var fixedList = new FixedList64Bytes<int>();
fixedList.Add(1);
fixedList.Add(2);
fixedList.Add(3);
Debug.Log($"길이: {fixedList.Length}");
// Dispose() 호출 불필요 — 스코프를 벗어나면 자동 소멸.
🔹Native와 Unsafe 컬렉션의 차이점
- Native 컬렉션은 안전성을 보장하면서도 성능을 최적화할 수 있는 방법을 제공한다. 예를 들어, NativeList와 NativeHashMap은 메모리 관리와 스레드 안전성을 체크해주므로, 실수로 발생할 수 있는 문제를 예방할 수 있다.
- Unsafe 컬렉션은 성능을 더 중요시하고, 메모리 관리와 안전성 검사를 하지 않기 때문에 실수가 발생할 가능성이 높지만, 더 빠른 처리가 가능하다.
ex.
- NativeList<int> vs UnsafeList<int>
- NativeHashMap<int, float> vs UnsafeHashMap<int, float>
* 성능을 최적하하되, 안전성을 보장하고 싶다면 Native 컬렉션을 사용하는 것이 바람직하다. 가능하면 Unsafe 컬렉션은 최소화하고, 반드시 성능이 중요한 경우에만 사용해야 한다.
2. Mathematics 패키지
Mathematics 패키지는 Unity에서 고성능 수학 계산을 처리하는 라이브러리로, 벡터, 행렬, 쿼터니언 등 다양한 수학적 연산을 효율적으로 처리할 수 있다. 이 패키지는 버스트 컴파일러와 잡 시스템과 결합하여 고도로 최적화된 네이티브 코드를 생성할 수 있다.
🔹벡터 및 행렬 타입
- 벡터 타입: float3, float2, float4, quaternion 등 다양한 벡터 타입을 제공하며, 각종 벡터 연산을 효율적으로 처리한다.
- 행렬 타입: float3x3, float4x4 등의 행렬 타입을 제공하여, 3D 그래픽스 및 수학적 계산에 필요한 행렬 연산을 최적화한다.
🔹수학 메서드 및 연산자
- Mathematics 패키지에서는 HLSL(High-Level Shading Language) 식 규칙을 따르는 다양한 수학 메서드 및 연산자가 제공된다. 이로 인해 셰이더 코드와의 호환성이 높아지며, 셰이더 프로그래밍에서의 성능도 향상된다.
- 벡터 연산, 회전, 변환, 크로스 프로덕트 등 다양한 수학적 연산을 위한 메서드가 포함되어 있다.
🔹버스트 컴파일러 최적화
- 버스트 컴파일러는 C# 코드를 네이티브 코드로 변환하여 실행 속도를 대폭 향상시키는 기술이다. Mathematics 패키지 내에서 제공하는 메서드들은 대부분 버스트 컴파일러에 최적화되어 있어, 성능이 중요한 작업에 매우 유리하다.
- 특수 최적화 훅(hook)을 사용하여 더욱 최적화된 성능을 낼 수 있다.
🔹UnityEngine.Mathf와의 비교
Unity에서 제공하는 기존의 UnityEngine.Mathf 라이브러리 역시 수학 연산을 처리할 수 있지만, Mathematics 패키지의 타입과 메서드는 성능 면에서 더 뛰어난 경우가 많다. 예를 들어, float3와 같은 벡터 타입은 Mathf의 기본 타입보다 성능이 훨씬 뛰어나다.
- 성능 차이: Mathematics 패키지의 연산은 고도로 최적화된 네이티브 코드로 컴파일되기 때문에, 대규모 데이터셋이나 복잡한 계산에서 Mathf보다 빠른 성능을 보일 수 있다.
- 수학 연산의 최적화: Mathematics에서 제공하는 메서드들은 특히 벡터 및 행렬 연산에 최적화되어 있어, 게임 내 물리 엔진, 애니메이션 시스템 등에서 중요한 역할을 한다.
** 결론
- Collections 패키지는 메모리 관리와 성능 최적화에 매우 유용하며, 관리되지 않는 컬렉션을 사용하여 가비지 컬렉터의 부하를 줄일 수 있다. 하지만 메모리 해제와 스레드 안전성에 대한 주의가 필요하다.
- Mathematics 패키지는 수학적인 계산을 최적화하는 데 특화된 라이브러리로, 버스트 컴파일러와 함께 사용하면 성능이 중요한 시스템에서 매우 효율적이다.
◈ 유니티 공식 문서를 참고하여 작성하였습니다◈
반응형
'Unity' 카테고리의 다른 글
| [Unity] DOTS - Netcode for Entities (0) | 2026.06.27 |
|---|---|
| [Unity] DOTS - Entities (0) | 2026.06.27 |
| [Unity] DOTS - Job 시스템 (0) | 2026.06.25 |
| [Unity] DOTS - Burst Compiler (0) | 2026.06.25 |
| [Unity ] DOTS - DOTS가 필요한 이유 (0) | 2026.06.23 |