[유니티] Unity - Parallel 병렬처리로 반복작업 속도 향상시키기

2024. 12. 18. 16:17·프로그래밍/Unity
반응형
BIG

 

오늘은 무얼 소개해볼까 하다가..

회사에서 획기적으로 성능향상을 경험한 Parallel (병렬처리) 메서드 사용법에 대해 이야기해보고자 한다.

사건의 발단은 이렇다.

  • 유니티 내에서 에셋번들을 다운로드 받아서 정해진 위치에 생성시키는 컨텐츠가 있다.
  • 이 에셋번들이 30개를 넘어가자 하나의 쓰레드에서는 (코루틴도 아니었었다 처음엔)
  • 15초가 넘게 걸리는 불상사가 걸리고 만것이다.
  • <다운로드 -> 에셋생성 -> 에셋위치시키기 > (반복)

 

병렬처리는 많은 반복작업에 있어서 효율적이게 처리할 수 있다는 특징이 있다.

유니티에서는 Job시스템이나.. 매우 다수의 오브젝트를 처리하는 뭐 였는지는 기억 갑자기 안나는데 다른 시스템이

별개로 존재하지만

간단한 부분에서 사용하기에는 Parallel 메서드도 충분히 경쟁력있다.

일단 따로 공부를 안해도된다는 점이 어떻게 보면 장점이랄까.

 

물론 나는 결국에는 코루틴으로 처리하긴 했지만, 조금 더 다수의 반복호출이었다면 아마 병렬처리를 썼을 것이다.

 

https://learn.microsoft.com/ko-kr/dotnet/standard/parallel-programming/how-to-write-a-simple-parallel-foreach-loop

 

Parallel.ForEach를 사용하여 단순 병렬 프로그램 작성 - .NET

이 문서에서는 .NET에서 데이터 병렬 처리를 사용하도록 설정하는 방법을 알아봅니다. IEnumerable 또는 IEnumerable 데이터 소스에 대한 Parallel.ForEach 루프를 작성합니다.

learn.microsoft.com

 

 

Parallel은 for와 forEach 두개로 사용할 수 있다.

두개의 차이는 말그대로 for는 index라는 특정 변수로 훑을 것이냐와 foreach 로 IEnumrable한 객체를 훑을 것이냐의 차이이다.

유니티에서 for와 forEach의 차이랑 비슷하다고 보면 되겠다.

 

기존코드와 개선된 코드를 봐보자

//기존코드
private IEnumerator LoadDataCo(SpaceData datas)
{
	int cnt = datas.Length;
    
    for(int i = 0; i< cnt; i++)
    {
    	yield return 다운받고 생성시키는 함수 호출
    }
}

yield에 계속 걸리다보니 하나의 에셋이 다운받아지고 생성되고 위치시키는 것이 모두 완료된 후에야 

다음 작업으로 가다보니 갯수가 많아질수록 병목현상이 눈에 띄게 체감;

 

그러고나서 나온 두가지 솔루션..

 

private void ParallelLoad(MySpaceData spaceData)  //1번 코드
{

    _mySpaceData = spaceData;
    Parallel.ForEach(_mySpaceData.spaceObjects,data =>
    {
        UnityMainThreadDispatcher.Instance().Enqueue(() => StartCoroutine(ParallelLoadDataCo(data)));
        //이 부분은 코루틴 돌리는 부분인데 밑에서 설명..
    });

}

private IEnumerator LoadAssetsParallel(MySpaceData spaceData) //2번 코드
{

    _mySpaceData = spaceData;
    List<Coroutine> loadCo = new List<Coroutine>();
    yield return new WaitUntil(() => _mySpaceUIManager.GetBundleInfoList != null);

    foreach (var item in _mySpaceData.spaceObjects)
    {
        loadCo.Add(StartCoroutine(ParallelLoadDataCo(item)));
    }

    foreach(var item in loadCo)
    {
        yield return item;
    }

}

private IEnumerator ParallelLoadDataCo(SpaceObjectData spaceData)
{
    ...생략...대충 에셋 다운받고 위치시키는곳
}

 

1번코드는 Parallel 클래스를 사용하는 것이다.

2번 코드는 코루틴시작을 한번에 여러개를 돌리는 것이다.

StopWatch를 재서 해보면 3~40개정도론 체감이 안되지만

0.03초와 0.3초 정도 10배가량의 속도차이를 보여준다.

 

하지만 유니티의 작업 예를 들면 게임오브젝트 생성이라든지

메인스레드에서만 실행되야 한다는 점을 고려하면

결국에는

 UnityMainThreadDispatcher.Instance().Enqueue(() 이 부분은 밑의 코드와 유사하다고 보면 되는데..

public class CoManager : MonoBehaviour
{
    private Queue<IEnumerator> _coroutine = new Queue<IEnumerator>();

    public void AddCoroutine(IEnumerator co)
    {
        _coroutine.Enqueue(co);
    }
    
    private void Update()
    {
        if (_coroutine.Count > 0)
        {
            StartCoroutine(_coroutine.Dequeue());
        }
    }
}

이런 코루틴 전용 코드에서 돌아간다는 점이 같다고 볼 수 있다.

속도의 차이는 많은 오브젝트의 다운로드를 얼마나 효율적이게 시간을 활용하는가이다.

여러개의 스레드에서 다운받는것과

비동기 비스무리한 코루틴에서 (결국 한 스레드에서) 다운 받는 것의 차이.

 

당시 누군가는 Parallel을 모를 수도 있다고 판단하여 (유지보수할 사람들도 고려하여)

큰 차이가 없었어서 코루틴을 사용하였지만,

Parallel 병렬 처리를 하였어도 괜찮았을 법한 예시였었다.

반응형
BIG
저작자표시 비영리 동일조건 (새창열림)

'프로그래밍 > Unity' 카테고리의 다른 글

[유니티] Unity - DI (Dependency Injection) VContainer 간단사용법  (0) 2025.04.07
[유니티] Unity - ScriptableObject 잘 사용하기 (feat: json Editor)  (0) 2024.12.27
[유니티] Unity - 코루틴 리턴값 받기와 Action에 대하여.  (6) 2024.12.13
[유니티] Unity WebGL - React.js와 쌍방향 통신하기  (2) 2024.12.11
[유니티] Unity - NewInputSystem 새로운 인풋시스템 적용하기.  (0) 2024.12.10
'프로그래밍/Unity' 카테고리의 다른 글
  • [유니티] Unity - DI (Dependency Injection) VContainer 간단사용법
  • [유니티] Unity - ScriptableObject 잘 사용하기 (feat: json Editor)
  • [유니티] Unity - 코루틴 리턴값 받기와 Action에 대하여.
  • [유니티] Unity WebGL - React.js와 쌍방향 통신하기
dduR
dduR
글쓰는 프로그래머 뚜르입니다 :)
    백만원으로 1억 만들기
    상담 신청하기
    »
    • 분류 전체보기
      • 공지사항
      • 프로그래밍
        • Flutter
        • Backend
        • Unity
        • Frontend
      • 재테크 부수입
      • 편집툴
        • 포토샵
        • 애프터이펙트
      • 이공계지식
        • 미분적분학
        • 공업수학
        • IT
  • 블로그 메뉴

    • 홈
    • 방명록
  • dduR
    부수익 창출에 목마른 개발자
    dduR
  • 링크

  • 인기 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.2
dduR
[유니티] Unity - Parallel 병렬처리로 반복작업 속도 향상시키기
상단으로

티스토리툴바