TIL(2024,07,23)기술 면접 대비

김보근·2024년 7월 23일

Unity

목록 보기
46/113
post-thumbnail

기술 면접 대비

확인 문제

1. 프로세스와 스레드의 차이는 무엇인가요?
2. Unity에서 Main Thread가 아닌 다른 스레드에서 Transform을 변경할 수 있을까요?
3. 왜 모든 작업을 비동기로 처리하지 않는 걸까요?

답변

  1. 프로세스와 스레드의 차이는 무엇인가요?
    프로세스는 실행 중인 프로그램의 인스턴스를 의미하며, 독립된 메모리 공간을 가집니다. 각 프로세스는 자체의 메모리 공간(코드, 데이터, 힙, 스택)을 가지며, 다른 프로세스와 직접적으로 메모리를 공유하지 않습니다. 운영 체제는 프로세스 간의 통신을 위해 IPC(Inter-Process Communication) 메커니즘을 제공합니다.

스레드는 프로세스 내에서 실행되는 가장 작은 실행 단위입니다. 하나의 프로세스는 여러 스레드를 가질 수 있으며, 이 스레드들은 동일한 메모리 공간을 공유합니다. 스레드들은 코드, 데이터, 힙을 공유하지만, 각 스레드는 자신만의 스택을 가지고 있습니다. 이로 인해 스레드 간의 통신은 프로세스 간의 통신보다 더 빠르고 효율적입니다.

  1. Unity에서 Main Thread가 아닌 다른 스레드에서 Transform을 변경할 수 있을까요?
    Unity에서는 Main Thread(메인 스레드) 외의 다른 스레드에서 Transform을 직접 변경할 수 없습니다. Unity의 대부분의 API는 메인 스레드에서만 안전하게 호출될 수 있도록 설계되었습니다. 메인 스레드에서 실행되는 Unity 엔진은 게임 오브젝트의 상태, 렌더링, 물리 계산 등을 관리합니다. 메인 스레드 외의 다른 스레드에서 Transform을 변경하면 예기치 않은 동작이나 크래시가 발생할 수 있습니다. 다른 스레드에서 작업을 수행하고 싶다면, 메인 스레드로 결과를 전달하여 Transform을 변경하는 방식을 사용해야 합니다. 이를 위해 Unity는 UnityMainThreadDispatcher와 같은 유틸리티를 제공하거나 Task와 SynchronizationContext를 활용할 수 있습니다.

  2. 왜 모든 작업을 비동기로 처리하지 않는 걸까요?
    모든 작업을 비동기로 처리하지 않는 이유는 다음과 같습니다:

복잡성 증가: 비동기 프로그래밍은 코드의 복잡성을 증가시킵니다. 개발자는 비동기 작업의 완료 시점을 관리하고, 오류 처리 및 예외 관리를 신경 써야 합니다. 이는 동기 프로그래밍보다 더 어려운 작업일 수 있습니다.

디버깅 어려움: 비동기 코드의 디버깅은 동기 코드보다 더 어렵습니다. 비동기 작업은 여러 스레드에서 실행될 수 있어, 디버깅 시점에서 문제가 발생한 지점을 파악하기 힘들 수 있습니다.

오버헤드: 모든 작업을 비동기로 처리하면 스레드 관리 및 컨텍스트 전환과 같은 오버헤드가 발생할 수 있습니다. 이는 성능 저하를 초래할 수 있습니다.

불필요한 비동기화: 모든 작업이 비동기적으로 처리될 필요는 없습니다. 단순하고 짧은 작업은 동기적으로 처리하는 것이 더 효율적일 수 있습니다. 비동기 작업은 주로 I/O 바운드 작업(예: 파일 읽기/쓰기, 네트워크 통신)에서 성능 이점을 제공합니다.

리소스 제한: 비동기 작업은 시스템 리소스를 효율적으로 사용해야 합니다. 무분별한 비동기 작업 생성은 시스템 자원을 고갈시키고, 오히려 성능 저하를 초래할 수 있습니다.

이와 같은 이유로, 비동기 작업은 필요에 따라 신중하게 선택적으로 사용해야 합니다.

설명 문제

1. Unity에서 멀티스레딩을 구현하기 위한 방법에 대해 설명해주세요.
2. CPU와 GPU의 작동 방법은 어떤 차이가 있는지 설명해주세요.

답변

  1. Unity에서 멀티스레딩을 구현하기 위한 방법
    Unity에서 멀티스레딩을 구현하는 방법에는 여러 가지가 있습니다. 다음은 그 중 주요한 방법들입니다:

C#의 Thread 클래스와 Task 병렬 라이브러리 (TPL):

Thread 클래스: System.Threading.Thread를 사용하여 기본적인 스레드를 생성하고 관리할 수 있습니다. 이는 간단한 스레드 작업에 적합합니다.

Thread thread = new Thread(SomeFunction);
thread.Start();

void SomeFunction()
{
    // 스레드 작업
}

Task 병렬 라이브러리 (TPL): System.Threading.Tasks.Task를 사용하면 더 높은 수준의 비동기 프로그래밍을 할 수 있습니다. async와 await 키워드를 사용하여 비동기 작업을 쉽게 관리할 수 있습니다.

async void Start()
{
    await Task.Run(() => SomeFunction());
}

void SomeFunction()
{
    // 비동기 작업
}

Job System:
Unity의 Job System은 멀티스레딩을 쉽게 구현할 수 있도록 돕는 고성능 병렬 처리 시스템입니다. 이를 통해 데이터 중심의 병렬 처리를 구현할 수 있습니다.

using Unity.Jobs;

public struct MyJob : IJob
{
    public void Execute()
    {
        // 병렬 처리 작업
    }
}

void Start()
{
    MyJob job = new MyJob();
    JobHandle handle = job.Schedule();
    handle.Complete();
}

Burst Compiler:
Unity의 Burst Compiler는 Job System과 함께 사용되어 성능을 극대화합니다. Burst는 C# 코드를 네이티브 코드로 컴파일하여 실행 성능을 향상시킵니다.

using Unity.Burst;
using Unity.Jobs;

[BurstCompile]
public struct MyBurstJob : IJob
{
    public void Execute()
    {
        // 고성능 병렬 처리 작업
    }
}

void Start()
{
    MyBurstJob job = new MyBurstJob();
    JobHandle handle = job.Schedule();
    handle.Complete();
}

Unity C# Job System과 ECS(Entity Component System):
Unity의 ECS는 데이터 중심의 설계를 통해 게임 객체 관리를 효율화합니다. ECS와 Job System을 결합하면 멀티스레딩 성능을 극대화할 수 있습니다.

using Unity.Entities;

public struct MyComponent : IComponentData
{
    public float Value;
}

public class MySystem : SystemBase
{
    protected override void OnUpdate()
    {
        Entities.ForEach((ref MyComponent component) =>
        {
            component.Value += 1f;
        }).ScheduleParallel();
    }
}
  1. CPU와 GPU의 작동 방법은 어떤 차이가 있는지 설명해주세요.
    CPU (Central Processing Unit)GPU (Graphics Processing Unit)는 모두 데이터 처리를 담당하는 프로세서이지만, 그 구조와 작동 방식은 매우 다릅니다.

CPU (중앙 처리 장치):

구조: CPU는 소수의 고성능 코어를 가지고 있으며, 각 코어는 복잡한 명령어를 빠르게 처리할 수 있습니다. 일반적으로 CPU는 강력한 제어 장치와 캐시 메모리를 가지고 있습니다.

작동 방식: CPU는 복잡한 작업을 빠르게 처리할 수 있는 능력을 갖추고 있으며, 주로 순차적인 작업에 최적화되어 있습니다. 이는 운영 체제 관리, 애플리케이션 실행, 로직 처리 등 다양한 범용 작업을 처리하는 데 적합합니다.

병렬 처리: CPU는 동시에 적은 수의 스레드를 처리하지만, 각 스레드는 매우 빠르게 실행됩니다. 이는 복잡한 논리 연산과 연속적인 데이터 처리에 유리합니다.

GPU (그래픽 처리 장치):

구조: GPU는 수천 개의 작은 코어를 가지고 있으며, 각 코어는 단순한 명령어를 병렬로 처리할 수 있습니다. 이는 대량의 데이터 처리를 동시에 수행하는 데 적합한 구조입니다.

작동 방식: GPU는 간단한 연산을 매우 빠르게 병렬로 처리할 수 있어, 주로 그래픽 렌더링, 이미지 처리, 딥러닝 연산 등 대량의 데이터 병렬 처리가 필요한 작업에 최적화되어 있습니다.

병렬 처리: GPU는 수천 개의 코어를 이용하여 동시에 많은 스레드를 처리할 수 있습니다. 이는 그래픽 처리와 같이 동일한 작업을 반복적으로 수행하는 경우에 매우 효과적입니다.

요약:

CPU: 소수의 고성능 코어로 복잡하고 순차적인 작업에 최적화됨. 다목적 프로세싱에 적합.
GPU: 수많은 저성능 코어로 단순하고 병렬적인 작업에 최적화됨. 대량의 데이터 병렬 처리에 적합.
각 프로세서는 그 특성에 맞는 작업에 최적화되어 있어, 현대의 컴퓨팅 환경에서는 CPU와 GPU를 함께 사용하는 이종 컴퓨팅(Heterogeneous Computing) 환경이 점점 더 중요해지고 있습니다.

profile
게임개발자꿈나무

0개의 댓글