ݺߣ

ݺߣShare a Scribd company logo
비동기 파일 로딩
1
목차
• 시작하며…
• 비동기 파일 로딩 과정
• 특정 스레드로 특정 작업을 위임하기
• 최종 데이터 가공 완료 통보하기
• 마치며…
2
시작하며…
개인 프로젝트에서 구현해본 비동기 파일 로딩 방식에 대해서 이야기 하고자
합니다.
주 스레드가 멈추지 않고 백그라운드에서 에셋 파일을 읽고 가공하여 전달하는
일련의 과정을 다룹니다.
3
비동기 파일 로딩 과정
에셋을 불러들이는 과정을 살펴보겠습니다.
주로 2개의 스레드가 사용되며 데이터 가공 과정에서 분산 처리를 위해 4개의
스레드가 사용됩니다.
Main thread
Filesystem thread
Storage
Worker threads(4개)
4
비동기 파일 로딩 과정
IOCP를 사용한 비동기 파일 I/O를 사용해서 구현했기 때문에 프로그램이
실행되면 파일시스템 스레드는 자신을 대기 큐에 등록합니다.
Main thread
Filesystem thread
Storage
Worker threads(4개)
스레드 시작부터
대기 상태로 진입
5
비동기 파일 로딩 과정
메인 스레드에서 에셋을 로딩하기 위해서 비동기 파일 읽기 함수를 호출하고
2차 저장장치에서 파일을 읽어 메인 메모리에 적재하게 됩니다.
Main thread
Filesystem thread
요청
Storage
파일 읽는 중
Worker threads(4개)
6
비동기 파일 로딩 과정
읽기 작업이 완료되면 대기하고 있던 파일시스템 스레드는 완료를 통보 받아
깨어납니다.
Main thread
Filesystem thread
요청
Storage
파일 읽기
깨어남
Worker threads(4개)
7
비동기 파일 로딩 과정
깨어난 파일시스템 스레드는 데이터의 버퍼와 크기를 메인 스레드로 전달한
다음 다시 자신을 대기 큐에 등록합니다.
Main thread
Filesystem thread
요청
Storage
파일 읽기
통보 후 재 대기
Worker threads(4개)
8
비동기 파일 로딩 과정
메인 스레드는 전달받은 데이터의 가공을 다른 워커 스레드로 위임합니다.
Main thread
Filesystem thread
요청
Storage
파일 읽기
통보 후 재 대기
가공 요청
Worker threads(4개)
에셋 가공
분산 처리 전용 스레드에서
처리하도록 위임
9
비동기 파일 로딩 과정
워커 스레드는 데이터를 게임에서 사용할 형태로 가공하면서 추가로 읽어야 할
파일이 있다면 이를 메인 스레드에 요청합니다.
Main thread
Filesystem thread
요청
Storage
파일 읽기
통보 후 재 대기
가공 요청
Worker threads(4개)
에셋 가공
파일 I/O에 대한 요청은
항상 메인 스레드에서
수행하도록
10
비동기 파일 로딩 과정
추가 파일에 대한 파일 읽기 진행 단계는 첫 요청과 동일합니다
Main thread
Filesystem thread
요청
Storage
파일 읽기
통보 후 재 대기
가공 요청
Worker threads(4개)
에셋 가공
요청
파일 읽기
통보 후 재 대기
가공 요청
에셋 가공
11
비동기 파일 로딩 과정
모든 읽기 작업이 완료되면 최종적으로 가공된 에셋 데이터가 메인 스레드로
전달됩니다.
Main thread
Filesystem thread
요청
Storage
파일 읽기
통보 후 재 대기
가공 요청
Worker threads(4개)
에셋 가공
요청
파일 읽기
통보 후 재 대기
가공 요청
가공 후 최종 데이터 전달
이후 로직 수행
12
비동기 파일 로딩 과정
일련의 로딩 과정에서 크게 2가지 이슈를 처리해야 했습니다.
1. 특정 스레드로 특정 작업을 위임할 수 있는 구조가 필요.
2. 추가 파일 데이터에 대한 읽기 작업 요청으로 인한 최종 완료 통보 시점 지연.
13
특정 스레드로 특정 작업 위임하기
기본적인 구현 방법은 태스크 시스템 형태의 스레드 풀입니다.
여러 개의 스레드를 역할을 나눠 미리 생성하였습니다.
14
특정 스레드로 특정 작업 위임하기
생성하는 스레드의 역할은 열거형으로 다음과 같이 정의되어 있습니다.
주 스레드인 GameThread를 제외한 6개의 스레드가 생성됩니다.
15
특정 스레드로 특정 작업 위임하기
그리고 태스크에는 workerAffinity 라는 변수를 통해서 어떤 스레드에서 작업을
수행할지 지정합니다.
workerAffinity는 스레드의 열거형을 기반으로 하여 비트 시프트를 통해 계산
합니다.
16
특정 스레드로 특정 작업 위임하기
이렇게 계산된 workerAffinityMask 와 스레드의 타입을 검사하여 해당 태스크를
스레드에서 실행할지를 결정합니다.
17
특정 스레드로 특정 작업 위임하기
실제 태스크 제출에는 다음과 같은 헬퍼 함수가 사용됩니다.
실제 호출 예시입니다. ( 주 스레드에서 실행되도록 작업을 위임 )
18
최종 데이터 가공 완료 통보하기
에셋의 종류에 따라서 추가적인 파일 읽기가 필요한 경우가 있습니다.
정적 메시 에셋의 클래스인 StaticMesh 클래스의 구조를 살펴보겠습니다.
모델 정점 데이터
재질 데이터
그 외
텍셀 데이터
텍스처
Vertex Shader
Pixel Shader
StaticMesh class Material class
DDSTexture class
버택스 셰이더
바이트 코드
VertexShader class
픽셀 셰이더
바이트 코드
PixelShader class
19
최종 데이터 가공 완료 통보하기
이런 구조로 인해서 모델 에셋을 온전하게 사용할 수 있는 시점은 모든 추가
파일의 데이터 읽기와 가공이 완료된 시점입니다.
추가 파일에 대한 처리의 완료를 기다리지 않고 로딩 완료 콜백을 호출한다면
필요한 데이터가 누락되는 등의 문제가 발생할 수 있습니다.
최종 완료 콜백은 이러한 처리가 모두 끝난 마지막에 호출되도록 적절하게
미뤄져야 합니다.
20
최종 데이터 가공 완료 통보하기
다음과 같은 단순한 선형 구조라면 완료 콜백을 지연시키기 위해 콜백체인을
이용할 수 있겠습니다.
A B C
21
최종 데이터 가공 완료 통보하기
하지만 이런 선형 구조는 추가 파일을 여러 개 로드해야 하는 경우에는 처리하기
어려워 집니다.
다음과 같은 구조에서 B 파일을 처리하고 난 다음 A 파일의 콜백을 바로 부를 수
없습니다. ( C, D를 아직 안 읽었기 때문 )
A C
B
D 22
최종 데이터 가공 완료 통보하기
이를 해결 하기 위해 종속 관계를 저장해서 콜백 호출을 무시하도록 하였습니다.
주요 변수 2개를 살펴보겠습니다.
A C
B
D
23
최종 데이터 가공 완료 통보하기
m_prerequisites 는 현재 에셋보다 먼저 처리되야 하는 에셋의 숫자입니다.
A C
B
D
Prerequisites : 3
Prerequisites : 0
Prerequisites : 0
Prerequisites : 0
24
최종 데이터 가공 완료 통보하기
m_prerequisites 이 0보다 큰 경우 다음과 같이 콜백의 호출이 무시됩니다.
A C
B
D
Prerequisites : 3
Prerequisites : 0
Prerequisites : 0
Prerequisites : 0
25
최종 데이터 가공 완료 통보하기
m_subSequentList 는 현재 에셋의 처리를 기다리고 있는 에셋 로더 핸들의
리스트입니다.
A C
B
D
subSequenceList = [A]
subSequenceList = [A]
subSequenceList = [A]
subSequenceList = []
26
최종 데이터 가공 완료 통보하기
현재 에셋의 처리가 끝나면 m_subSequentList 에 등록된 핸들에 대해
DecreasePrerequisite( ) 함수를 호출해서 m_prerequisites 를 감소 시킵니다.
A C
B
D
Prerequisites : 2
Prerequisites : 0
Prerequisites : 0
Prerequisites : 0
B 에셋의 처리가 끝나면
B에셋의 처리를 기다리는
A 에셋의 Prerequisites 값을 1 감소
27
최종 데이터 가공 완료 통보하기
종속된 모든 에셋의 처리가 끝나게 되면 m_prerequisites의 값이 0이 되어 최종
적으로 A 에셋의 콜백을 호출할 수 있게 됩니다.
A C
B
D
Prerequisites : 0
Prerequisites : 0
Prerequisites : 0
Prerequisites : 0
28
최종 데이터 가공 완료 통보하기
이런 식으로 완료 콜백을 지연합니다. 이제 에셋 간 종속 관계를 파일 처리
과정에서 적절하게 연결하면 됩니다.
저는 현재 처리중인 에셋에 대한 에셋 로더 핸들을 다음과 같이 저장하고
파일 시스템에 비동기 읽기 요청 시 연결해주는 형태로 구현하였습니다.
29
읽기 완료 후 에셋 가공을
워커 스레드로 위임하는 코드
최종 데이터 가공 완료 통보하기
지금까지의 과정은 DAG(Directed acyclic graph) 를 파일 읽기 과정에서
만드는 것입니다.
m_subSequentList 가 진입 간선( Incoming edge )의 개수 라고 생각하시면
될 것입니다.
30
마치며…
제가 구현해본 비동기 파일 로딩 과정은 이것이 전부입니다.
현재 로딩 중인 파일에 대한 읽기 요청이 또 들어 온 경우의 처리 등 자잘한 예외
처리 사항이 남아 있긴 하지만 핵심내용은 아니라 제외하였습니다.
31
더 자세한 코드를 보고 싶으시다면...
ppt의 코드는 설명을 위해 전체 코드의 일부분을 발췌하였습니다.
전체 코드는 아래 링크를 참조 바랍니다.
• https://github.com/xtozero/SSR/blob/multi-
thread/Source/Engine/Public/AssetLoader/AssetLoader.h
• https://github.com/xtozero/SSR/blob/multi-
thread/Source/Engine/Private/AssetLoader/AssetLoader.cpp
• https://github.com/xtozero/SSR/blob/multi-
thread/Source/Core/Public/TaskScheduler.h
• https://github.com/xtozero/SSR/blob/multi-
thread/Source/Core/Private/TaskScheduler.cpp
32

More Related Content

What's hot (20)

Multithread & shared_ptr
Multithread & shared_ptrMultithread & shared_ptr
Multithread & shared_ptr
내훈 정
LockFree Algorithm
LockFree AlgorithmLockFree Algorithm
LockFree Algorithm
Merry Merry
(2013 DEVIEW) 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
(2013 DEVIEW) 멀티쓰레드 프로그래밍이  왜이리 힘드나요? (2013 DEVIEW) 멀티쓰레드 프로그래밍이  왜이리 힘드나요?
(2013 DEVIEW) 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
내훈 정
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
내훈 정
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
sung ki choi
안드로이드 멀티스레딩 입문 송형주
안드로이드 멀티스레딩 입문 송형주안드로이드 멀티스레딩 입문 송형주
안드로이드 멀티스레딩 입문 송형주
iamhjoo (송형주)
07 스레드스케줄링,우선순위,그리고선호도
07 스레드스케줄링,우선순위,그리고선호도07 스레드스케줄링,우선순위,그리고선호도
07 스레드스케줄링,우선순위,그리고선호도
ssuser3fb17c
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. Job
Hyosung Jeon
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
내훈 정
Windws via c/c++ chapter 6
Windws via c/c++ chapter 6Windws via c/c++ chapter 6
Windws via c/c++ chapter 6
SukYun Yoon
Multi thread
Multi threadMulti thread
Multi thread
Nam Hyeonuk
Free rtos seminar
Free rtos seminarFree rtos seminar
Free rtos seminar
Cho Daniel
pyOpenCL 입문
pyOpenCL 입문pyOpenCL 입문
pyOpenCL 입문
Seongjun Kim
11웹서ѫ홵Ӛ
11웹서ѫ홵Ӛ11웹서ѫ홵Ӛ
11웹서ѫ홵Ӛ
noerror
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스
종빈 오
android_thread
android_threadandroid_thread
android_thread
handfoot
Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용
흥배 최
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2
도현 김
Multithread & shared_ptr
Multithread & shared_ptrMultithread & shared_ptr
Multithread & shared_ptr
내훈 정
(2013 DEVIEW) 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
(2013 DEVIEW) 멀티쓰레드 프로그래밍이  왜이리 힘드나요? (2013 DEVIEW) 멀티쓰레드 프로그래밍이  왜이리 힘드나요?
(2013 DEVIEW) 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
내훈 정
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
내훈 정
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
sung ki choi
안드로이드 멀티스레딩 입문 송형주
안드로이드 멀티스레딩 입문 송형주안드로이드 멀티스레딩 입문 송형주
안드로이드 멀티스레딩 입문 송형주
iamhjoo (송형주)
07 스레드스케줄링,우선순위,그리고선호도
07 스레드스케줄링,우선순위,그리고선호도07 스레드스케줄링,우선순위,그리고선호도
07 스레드스케줄링,우선순위,그리고선호도
ssuser3fb17c
windows via c++ Ch 5. Job
windows via c++ Ch 5. Jobwindows via c++ Ch 5. Job
windows via c++ Ch 5. Job
Hyosung Jeon
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
내훈 정
Windws via c/c++ chapter 6
Windws via c/c++ chapter 6Windws via c/c++ chapter 6
Windws via c/c++ chapter 6
SukYun Yoon
11웹서ѫ홵Ӛ
11웹서ѫ홵Ӛ11웹서ѫ홵Ӛ
11웹서ѫ홵Ӛ
noerror
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스
종빈 오
Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용
흥배 최
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2
도현 김

Similar to 비동기 파일 로딩 (20)

[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
sung ki choi
04 프로세스
04 프로세스04 프로세스
04 프로세스
ssuser3fb17c
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드
KwangSeob Jeong
Memcached의 확장성 개선
Memcached의 확장성 개선Memcached의 확장성 개선
Memcached의 확장성 개선
NAVER D2
ԲᅰᆸᄒƩᄉƳᄐƵᆼ
ԲᅰᆸᄒƩᄉƳᄐƵᆼԲᅰᆸᄒƩᄉƳᄐƵᆼ
ԲᅰᆸᄒƩᄉƳᄐƵᆼ
J.H Ahn
Golang Project Guide from A to Z: From Feature Development to Enterprise Appl...
Golang Project Guide from A to Z: From Feature Development to Enterprise Appl...Golang Project Guide from A to Z: From Feature Development to Enterprise Appl...
Golang Project Guide from A to Z: From Feature Development to Enterprise Appl...
Kyuhyun Byun
Hadoop distributed file system rev3
Hadoop distributed file system rev3Hadoop distributed file system rev3
Hadoop distributed file system rev3
Sung-jae Park
log-monitoring-architecture.pdf
log-monitoring-architecture.pdflog-monitoring-architecture.pdf
log-monitoring-architecture.pdf
Sungkyun Kim
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
ssuser0c2478
안드로이드 DB, 서버 연동하기
안드로이드 DB, 서버 연동하기안드로이드 DB, 서버 연동하기
안드로이드 DB, 서버 연동하기
은아 정
Windosw via c 스터디20장.pptx
Windosw via c 스터디20장.pptxWindosw via c 스터디20장.pptx
Windosw via c 스터디20장.pptx
HolyTak
제 9회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 9회 엑셈 수요 세미나 자료 연구컨텐츠팀제 9회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 9회 엑셈 수요 세미나 자료 연구컨텐츠팀
EXEM
Git - Level 2
Git - Level 2Git - Level 2
Git - Level 2
민태 김
Matlab guide
Matlab guideMatlab guide
Matlab guide
종언 최
[211] HBase 기반 검색 데이터 저장소 (공개용)
[211] HBase 기반 검색 데이터 저장소 (공개용)[211] HBase 기반 검색 데이터 저장소 (공개용)
[211] HBase 기반 검색 데이터 저장소 (공개용)
NAVER D2
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍
Yong Joon Moon
Multithread pattern 소개
Multithread pattern 소개Multithread pattern 소개
Multithread pattern 소개
Sunghyouk Bae
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdfOS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
Ho Jeong Im
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
sung ki choi
서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드서버 아키텍처 이해를 위한 프로세스와 쓰레드
서버 아키텍처 이해를 위한 프로세스와 쓰레드
KwangSeob Jeong
Memcached의 확장성 개선
Memcached의 확장성 개선Memcached의 확장성 개선
Memcached의 확장성 개선
NAVER D2
ԲᅰᆸᄒƩᄉƳᄐƵᆼ
ԲᅰᆸᄒƩᄉƳᄐƵᆼԲᅰᆸᄒƩᄉƳᄐƵᆼ
ԲᅰᆸᄒƩᄉƳᄐƵᆼ
J.H Ahn
Golang Project Guide from A to Z: From Feature Development to Enterprise Appl...
Golang Project Guide from A to Z: From Feature Development to Enterprise Appl...Golang Project Guide from A to Z: From Feature Development to Enterprise Appl...
Golang Project Guide from A to Z: From Feature Development to Enterprise Appl...
Kyuhyun Byun
Hadoop distributed file system rev3
Hadoop distributed file system rev3Hadoop distributed file system rev3
Hadoop distributed file system rev3
Sung-jae Park
log-monitoring-architecture.pdf
log-monitoring-architecture.pdflog-monitoring-architecture.pdf
log-monitoring-architecture.pdf
Sungkyun Kim
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
ssuser0c2478
안드로이드 DB, 서버 연동하기
안드로이드 DB, 서버 연동하기안드로이드 DB, 서버 연동하기
안드로이드 DB, 서버 연동하기
은아 정
Windosw via c 스터디20장.pptx
Windosw via c 스터디20장.pptxWindosw via c 스터디20장.pptx
Windosw via c 스터디20장.pptx
HolyTak
제 9회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 9회 엑셈 수요 세미나 자료 연구컨텐츠팀제 9회 엑셈 수요 세미나 자료 연구컨텐츠팀
제 9회 엑셈 수요 세미나 자료 연구컨텐츠팀
EXEM
[211] HBase 기반 검색 데이터 저장소 (공개용)
[211] HBase 기반 검색 데이터 저장소 (공개용)[211] HBase 기반 검색 데이터 저장소 (공개용)
[211] HBase 기반 검색 데이터 저장소 (공개용)
NAVER D2
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍
Yong Joon Moon
Multithread pattern 소개
Multithread pattern 소개Multithread pattern 소개
Multithread pattern 소개
Sunghyouk Bae
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdfOS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
OS Process, Thread, CPU Scheduling에 대해 알아봅시다.pdf
Ho Jeong Im

More from Bongseok Cho (10)

Light Propagation Volume.pdf
Light Propagation Volume.pdfLight Propagation Volume.pdf
Light Propagation Volume.pdf
Bongseok Cho
Spherical Harmonics.pdf
Spherical Harmonics.pdfSpherical Harmonics.pdf
Spherical Harmonics.pdf
Bongseok Cho
Reflective Shadow Maps
Reflective Shadow MapsReflective Shadow Maps
Reflective Shadow Maps
Bongseok Cho
Volumetric Fog
Volumetric FogVolumetric Fog
Volumetric Fog
Bongseok Cho
Temporal Anti-Aliasing
Temporal Anti-AliasingTemporal Anti-Aliasing
Temporal Anti-Aliasing
Bongseok Cho
C++20에서 리플렉션 기능 구현
C++20에서 리플렉션 기능 구현C++20에서 리플렉션 기능 구현
C++20에서 리플렉션 기능 구현
Bongseok Cho
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)
Bongseok Cho
Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)
Bongseok Cho
Screen space reflection
Screen space reflectionScreen space reflection
Screen space reflection
Bongseok Cho
Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)
Bongseok Cho
Light Propagation Volume.pdf
Light Propagation Volume.pdfLight Propagation Volume.pdf
Light Propagation Volume.pdf
Bongseok Cho
C++20에서 리플렉션 기능 구현
C++20에서 리플렉션 기능 구현C++20에서 리플렉션 기능 구현
C++20에서 리플렉션 기능 구현
Bongseok Cho
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)
Bongseok Cho
Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)
Bongseok Cho
Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)Game Physics Engine Development (게임 물리 엔진 개발)
Game Physics Engine Development (게임 물리 엔진 개발)
Bongseok Cho

비동기 파일 로딩

  • 2. 목차 • 시작하며… • 비동기 파일 로딩 과정 • 특정 스레드로 특정 작업을 위임하기 • 최종 데이터 가공 완료 통보하기 • 마치며… 2
  • 3. 시작하며… 개인 프로젝트에서 구현해본 비동기 파일 로딩 방식에 대해서 이야기 하고자 합니다. 주 스레드가 멈추지 않고 백그라운드에서 에셋 파일을 읽고 가공하여 전달하는 일련의 과정을 다룹니다. 3
  • 4. 비동기 파일 로딩 과정 에셋을 불러들이는 과정을 살펴보겠습니다. 주로 2개의 스레드가 사용되며 데이터 가공 과정에서 분산 처리를 위해 4개의 스레드가 사용됩니다. Main thread Filesystem thread Storage Worker threads(4개) 4
  • 5. 비동기 파일 로딩 과정 IOCP를 사용한 비동기 파일 I/O를 사용해서 구현했기 때문에 프로그램이 실행되면 파일시스템 스레드는 자신을 대기 큐에 등록합니다. Main thread Filesystem thread Storage Worker threads(4개) 스레드 시작부터 대기 상태로 진입 5
  • 6. 비동기 파일 로딩 과정 메인 스레드에서 에셋을 로딩하기 위해서 비동기 파일 읽기 함수를 호출하고 2차 저장장치에서 파일을 읽어 메인 메모리에 적재하게 됩니다. Main thread Filesystem thread 요청 Storage 파일 읽는 중 Worker threads(4개) 6
  • 7. 비동기 파일 로딩 과정 읽기 작업이 완료되면 대기하고 있던 파일시스템 스레드는 완료를 통보 받아 깨어납니다. Main thread Filesystem thread 요청 Storage 파일 읽기 깨어남 Worker threads(4개) 7
  • 8. 비동기 파일 로딩 과정 깨어난 파일시스템 스레드는 데이터의 버퍼와 크기를 메인 스레드로 전달한 다음 다시 자신을 대기 큐에 등록합니다. Main thread Filesystem thread 요청 Storage 파일 읽기 통보 후 재 대기 Worker threads(4개) 8
  • 9. 비동기 파일 로딩 과정 메인 스레드는 전달받은 데이터의 가공을 다른 워커 스레드로 위임합니다. Main thread Filesystem thread 요청 Storage 파일 읽기 통보 후 재 대기 가공 요청 Worker threads(4개) 에셋 가공 분산 처리 전용 스레드에서 처리하도록 위임 9
  • 10. 비동기 파일 로딩 과정 워커 스레드는 데이터를 게임에서 사용할 형태로 가공하면서 추가로 읽어야 할 파일이 있다면 이를 메인 스레드에 요청합니다. Main thread Filesystem thread 요청 Storage 파일 읽기 통보 후 재 대기 가공 요청 Worker threads(4개) 에셋 가공 파일 I/O에 대한 요청은 항상 메인 스레드에서 수행하도록 10
  • 11. 비동기 파일 로딩 과정 추가 파일에 대한 파일 읽기 진행 단계는 첫 요청과 동일합니다 Main thread Filesystem thread 요청 Storage 파일 읽기 통보 후 재 대기 가공 요청 Worker threads(4개) 에셋 가공 요청 파일 읽기 통보 후 재 대기 가공 요청 에셋 가공 11
  • 12. 비동기 파일 로딩 과정 모든 읽기 작업이 완료되면 최종적으로 가공된 에셋 데이터가 메인 스레드로 전달됩니다. Main thread Filesystem thread 요청 Storage 파일 읽기 통보 후 재 대기 가공 요청 Worker threads(4개) 에셋 가공 요청 파일 읽기 통보 후 재 대기 가공 요청 가공 후 최종 데이터 전달 이후 로직 수행 12
  • 13. 비동기 파일 로딩 과정 일련의 로딩 과정에서 크게 2가지 이슈를 처리해야 했습니다. 1. 특정 스레드로 특정 작업을 위임할 수 있는 구조가 필요. 2. 추가 파일 데이터에 대한 읽기 작업 요청으로 인한 최종 완료 통보 시점 지연. 13
  • 14. 특정 스레드로 특정 작업 위임하기 기본적인 구현 방법은 태스크 시스템 형태의 스레드 풀입니다. 여러 개의 스레드를 역할을 나눠 미리 생성하였습니다. 14
  • 15. 특정 스레드로 특정 작업 위임하기 생성하는 스레드의 역할은 열거형으로 다음과 같이 정의되어 있습니다. 주 스레드인 GameThread를 제외한 6개의 스레드가 생성됩니다. 15
  • 16. 특정 스레드로 특정 작업 위임하기 그리고 태스크에는 workerAffinity 라는 변수를 통해서 어떤 스레드에서 작업을 수행할지 지정합니다. workerAffinity는 스레드의 열거형을 기반으로 하여 비트 시프트를 통해 계산 합니다. 16
  • 17. 특정 스레드로 특정 작업 위임하기 이렇게 계산된 workerAffinityMask 와 스레드의 타입을 검사하여 해당 태스크를 스레드에서 실행할지를 결정합니다. 17
  • 18. 특정 스레드로 특정 작업 위임하기 실제 태스크 제출에는 다음과 같은 헬퍼 함수가 사용됩니다. 실제 호출 예시입니다. ( 주 스레드에서 실행되도록 작업을 위임 ) 18
  • 19. 최종 데이터 가공 완료 통보하기 에셋의 종류에 따라서 추가적인 파일 읽기가 필요한 경우가 있습니다. 정적 메시 에셋의 클래스인 StaticMesh 클래스의 구조를 살펴보겠습니다. 모델 정점 데이터 재질 데이터 그 외 텍셀 데이터 텍스처 Vertex Shader Pixel Shader StaticMesh class Material class DDSTexture class 버택스 셰이더 바이트 코드 VertexShader class 픽셀 셰이더 바이트 코드 PixelShader class 19
  • 20. 최종 데이터 가공 완료 통보하기 이런 구조로 인해서 모델 에셋을 온전하게 사용할 수 있는 시점은 모든 추가 파일의 데이터 읽기와 가공이 완료된 시점입니다. 추가 파일에 대한 처리의 완료를 기다리지 않고 로딩 완료 콜백을 호출한다면 필요한 데이터가 누락되는 등의 문제가 발생할 수 있습니다. 최종 완료 콜백은 이러한 처리가 모두 끝난 마지막에 호출되도록 적절하게 미뤄져야 합니다. 20
  • 21. 최종 데이터 가공 완료 통보하기 다음과 같은 단순한 선형 구조라면 완료 콜백을 지연시키기 위해 콜백체인을 이용할 수 있겠습니다. A B C 21
  • 22. 최종 데이터 가공 완료 통보하기 하지만 이런 선형 구조는 추가 파일을 여러 개 로드해야 하는 경우에는 처리하기 어려워 집니다. 다음과 같은 구조에서 B 파일을 처리하고 난 다음 A 파일의 콜백을 바로 부를 수 없습니다. ( C, D를 아직 안 읽었기 때문 ) A C B D 22
  • 23. 최종 데이터 가공 완료 통보하기 이를 해결 하기 위해 종속 관계를 저장해서 콜백 호출을 무시하도록 하였습니다. 주요 변수 2개를 살펴보겠습니다. A C B D 23
  • 24. 최종 데이터 가공 완료 통보하기 m_prerequisites 는 현재 에셋보다 먼저 처리되야 하는 에셋의 숫자입니다. A C B D Prerequisites : 3 Prerequisites : 0 Prerequisites : 0 Prerequisites : 0 24
  • 25. 최종 데이터 가공 완료 통보하기 m_prerequisites 이 0보다 큰 경우 다음과 같이 콜백의 호출이 무시됩니다. A C B D Prerequisites : 3 Prerequisites : 0 Prerequisites : 0 Prerequisites : 0 25
  • 26. 최종 데이터 가공 완료 통보하기 m_subSequentList 는 현재 에셋의 처리를 기다리고 있는 에셋 로더 핸들의 리스트입니다. A C B D subSequenceList = [A] subSequenceList = [A] subSequenceList = [A] subSequenceList = [] 26
  • 27. 최종 데이터 가공 완료 통보하기 현재 에셋의 처리가 끝나면 m_subSequentList 에 등록된 핸들에 대해 DecreasePrerequisite( ) 함수를 호출해서 m_prerequisites 를 감소 시킵니다. A C B D Prerequisites : 2 Prerequisites : 0 Prerequisites : 0 Prerequisites : 0 B 에셋의 처리가 끝나면 B에셋의 처리를 기다리는 A 에셋의 Prerequisites 값을 1 감소 27
  • 28. 최종 데이터 가공 완료 통보하기 종속된 모든 에셋의 처리가 끝나게 되면 m_prerequisites의 값이 0이 되어 최종 적으로 A 에셋의 콜백을 호출할 수 있게 됩니다. A C B D Prerequisites : 0 Prerequisites : 0 Prerequisites : 0 Prerequisites : 0 28
  • 29. 최종 데이터 가공 완료 통보하기 이런 식으로 완료 콜백을 지연합니다. 이제 에셋 간 종속 관계를 파일 처리 과정에서 적절하게 연결하면 됩니다. 저는 현재 처리중인 에셋에 대한 에셋 로더 핸들을 다음과 같이 저장하고 파일 시스템에 비동기 읽기 요청 시 연결해주는 형태로 구현하였습니다. 29 읽기 완료 후 에셋 가공을 워커 스레드로 위임하는 코드
  • 30. 최종 데이터 가공 완료 통보하기 지금까지의 과정은 DAG(Directed acyclic graph) 를 파일 읽기 과정에서 만드는 것입니다. m_subSequentList 가 진입 간선( Incoming edge )의 개수 라고 생각하시면 될 것입니다. 30
  • 31. 마치며… 제가 구현해본 비동기 파일 로딩 과정은 이것이 전부입니다. 현재 로딩 중인 파일에 대한 읽기 요청이 또 들어 온 경우의 처리 등 자잘한 예외 처리 사항이 남아 있긴 하지만 핵심내용은 아니라 제외하였습니다. 31
  • 32. 더 자세한 코드를 보고 싶으시다면... ppt의 코드는 설명을 위해 전체 코드의 일부분을 발췌하였습니다. 전체 코드는 아래 링크를 참조 바랍니다. • https://github.com/xtozero/SSR/blob/multi- thread/Source/Engine/Public/AssetLoader/AssetLoader.h • https://github.com/xtozero/SSR/blob/multi- thread/Source/Engine/Private/AssetLoader/AssetLoader.cpp • https://github.com/xtozero/SSR/blob/multi- thread/Source/Core/Public/TaskScheduler.h • https://github.com/xtozero/SSR/blob/multi- thread/Source/Core/Private/TaskScheduler.cpp 32