분류 전체보기 186

Task.Delay (vs Thread.Sleep)

개요 Task.Delay를 통해 진행중인 Task를 일시정지 할 수 있다. public static async Task DoSomethingAsync() { await Task.Delay(100); //100ms 이상 대기한다. return Thread.CurrentThread.ManagedThreadId; } 이를 이용하여 소프트 타임아웃을 구현할 수 있다. public static async Task TaskWithSoftTimeout() { Task someTask = DoSomethingAsync(); var timeoutTask = Task.Delay(100); //둘 중 하나가 완료되길 대기 var completeTask = Task.WhenAny(someTask, timeoutTask); i..

언어/C# 2024.04.10

동시성 개요

개념 정리 동시성 : 한 번에 두 가지 이상의 작업을 수행 멀티스레딩 : 다수의 실행 스레드를 사용하는 동시성의 한 형태 병렬 처리 : 많은 작업을 여러 스레드에 나눠 수행하는 멀티스레딩의 한 형태 비동기 프로그래밍 : 불필요한 스레드의 사용을 피하기 위해 퓨처나 콜백을 사용하는 동시성의 한 형태 리액티브 프로그래밍 : 앱이 이벤트에 대응하는 방식 병렬 프로그래밍 병렬 프로그래밍은 데이터 병렬과 작업 병렬로 나눌 수 있다. 데이터 병렬 : 처리해야 할 데이터들을 다른 데이터들과 독립적으로 처리할 수 있을 때 해당된다. 작업 병렬 : 작업 풀에 있는 작업들이 다른 작업과 독립적일 때 해당. 모든 작업이 독립적이면 동기화가 필요 없어지므로 병렬 처리가 극대화된다. 스레드 풀 스레드 풀은 알아서 작업을 잘 처..

언어/C# 2024.04.01

struct 와 in, readonly

struct의 복사 비용 struct는 단독으로 사용하면 힙에 생성되지 않는다는 장점이 있다. 그대신 다른 메서드의 매개변수 등으로 주어질 때 항상 값 복사가 일어난다. 당연히 struct 내부에 필드가 많으면 많을수록 복사 비용이 커지게 된다. public struct SomeStruct { public int A, B, C; } public static bool IsZero(SomeStruct s) { return (s.A | s.B | s.C) == 0; } 가령 IsZero메서드를 호출하면 SomeStruct의 복사가 일어난다. 이를 방지하고 싶으면 ref키워드를 쓸 수 있다.ref키워드로 값 타입을 넘길 땐, 해당 타입 전체를 스택에 복사하는 대신 해당 타입의 주소만을 복사한다. public s..

언어/C# 2024.03.20

GAME AI - LOD

2024.02.25 - [Game AI] - AI 스케줄링 AI 스케줄링 AI Scheduling 게임이 균등한 프레임을 뽑기 위해서는 다양한 작업들이 제한된 시간 내에 수행되어야 한다. AI역시 마찬가지인데, 이를 제한된 시간 내에 처리하기 위해서는 다음의 3가지 요소가 필 tsyang.tistory.com 개요 게임 그래픽에 LOD를 적용하듯, AI에도 LOD를 적용할 수 있다. 가령 어떤 캐릭터는 복잡하고 정교한 행동을 하고 어떤 캐릭터는 단순한 행동을 하도록 할 수 있다. 그러나 게임 AI의 LOD는 그래픽처럼 단순히 거리만으로 처리할 수 없다. 그래픽과 달리 AI 캐릭터들이 우리가 보고 있지 않을 때도 항상 행동하길 기대하기 때문이다. AI의 LOD는 그 캐릭터가 게임에서 어떤 역할을 하냐에 따..

Game AI 2024.03.03

AI 스케줄링

AI Scheduling 게임이 균등한 프레임을 뽑기 위해서는 다양한 작업들이 제한된 시간 내에 수행되어야 한다. AI역시 마찬가지인데, 이를 제한된 시간 내에 처리하기 위해서는 다음의 3가지 요소가 필요하다. AI 작업들에 적절한 시간을 분배하는 것 AI 작업을 여러 프레임에 걸쳐서 수행할 수 있는 알고리즘 AI 작업간에 우선순위 Frequency 작업을 스케줄링하는 가장 간단한 방법 중 하나는 빈도(frequency)를 이용하는 것이다. 스케줄러는 매 프레임마다 어떤 작업을 수행할 것인지를 결정한다. 이때 작업들은 각자 frequency를 가지고 있으며 스케줄러는 이 값을 이용하여 작업을 수행한다. 가령 어떤 작업의 frequency가 5프레임이라면, 스케줄러는 해당 작업을 5프레임마다 한 번 수행한..

Game AI 2024.02.25

의사 난수

의사 난수 프로그래밍에서 난수란 세 가지 카테고리로 나눌 수 있다. (거의) 진짜 난수 : 특별한 하드웨어로 만드는 난수들. 각종 물리 실험이나 장비등에 쓰임 암호학 난수(해시값 등) : 사실 난수는 아니지만 예측불가능하고 충분히 잘 분포됨. 보통의 의사난수 : Seed가 필요하며, 생성되는 난수들이 결정적(deterministic)임. 생성되는 난수들을 이용하여 역으로 Seed를 구할 수 있음 의사 난수 생성기는 Seed값에 따라 생성되는 난수들이 결정적이기 때문에, 이를 잘 활용하면 유용하다. 때로는 게임 전체에서 단 하나의 난수 생성기를 사용하기 보다는 분야별로 여러 개의 난수 생성기를 사용하는 것이 좋을 수 있다. 가령 절차적인 맵을 생성하는 게임에서 단 하나의 난수 생성기만 사용한다면 플레이어가..

Game AI 2024.02.18

엔진 지원 시스템

시스템 클래스 생성 게임에서 사용되는 각종 매니저와 같은 싱글톤 혹은 정적 클래스들은 어떻게 생성하고 파괴해야 할까? 이런 클래스들을 생성/파괴할 때는 클래스들끼리의 의존성을 고려해야 한다. 유일한 클래스를 생성하는 메서드를 정의한 다음 의존성에 맞게 호출. //class RenderManager //... static RenderManager& get() { static RenderManager sSingleton; return sSingleton; } RenderManager() { VideoManager::get(); TextureManager::get(); //... } //... 그러나 위와 같은 방법은 아래와 같은 단점이 있다. 파괴 순서를 제어할 수 없어 파괴 과정에서 의존성이 훼손될 수 있..

게임엔진/일반 2024.02.11

인공 신경망

기초 인공 신경망의 핵심은 한 네트워크에 있는 인공 뉴런들이 다른 인공 뉴런의 부분 집합과 상호작용 하는 것이다. mulit layer perceptron(MLP)은 인공 신경망 아키텍쳐 중 하나인데, perceptron은 인공 신경망에서 사용되는 인공 뉴런을 뜻한다. MLP는 이전 레이어의 모든 노드로부터 인풋을 받아 다음 레이어에 있는 모든 노드에 아웃풋을 전달한다. 이런 네트워크를 feedfoward 네트워크라 부른다. 프로그래머로부터 입력을 받는 레이어를 input layer로, 그리고 네트워크를 통해 쓸만한 정보를 출력하는 레이어를 output layer라 부른다. feedfoward 네트워크 내부의 레이어들끼리 루프가 있을 수 있는데 이런 경우 recurrent network라 부르며, 매우 ..

Game AI 2024.02.04

(간단) 분할 상환(amortized) 분석 (+확률적 분석)

개요 알고리즘이나 자료 구조의 성능을 볼 때 amortized analysis란 단어를 많이 보게 된다. 이걸 한국어로 번역하면 분할 상환 분석이라는 생소한 단어가 나와 헷갈리는데, 간단히 말하면... 성능을 분석함에 있어서 "N개의 시퀀스를 수행할 때의 평균 시간을 측정했다." 라는 의미이다. 왜 이러냐? dynamic array를 한번 생각해보자. dynamic array는 capacity가 꽉 찬 상태에서 add가 일어날 경우, 흔히 doubling 이라 불리우는 비싼 연산을 수행한다. 따라서 dynamic array의 Add 연산의 시간 복잡도는 얼마인가? 라고 묻는다면 대부분의 경우에는 O(1)이겠지만 doubling이 일어날 때는 O(n) (n은 현재 array에 있는 요소의 갯수)이라고 할 ..

알고리즘/일반 2024.01.28

가비지 없이 foreach 사용하기

문제foreach문은 syntax sugar이다. 내부적으로 해당 타입의 Enumerator를 받아 루프를 수행한다. public class SomeGenericClass : IEnumerable { public class SomeEnum : IEnumerator { public SomeEnum() { Console.WriteLine("Created"); } public bool MoveNext() { return false; } public void Reset() { throw new NotImplementedException(); } public T Current { get; } object IEnumerator.Current => Current; public void Dispose() { } } p..

언어/C# 2024.01.21