99
Thread Blocking Is Evil 게임네트웍컴포넌트팀 김준현

A4 thread blockingisevil

Embed Size (px)

Citation preview

Page 1: A4 thread blockingisevil

Thread Blocking Is Evil

게임네트웍컴포넌트팀

김준현

Page 2: A4 thread blockingisevil

Thread

Blocking

Page 3: A4 thread blockingisevil

Non-Blocking

&

순차적 코드 작성

Page 4: A4 thread blockingisevil

Why does

Multi-Thread

matter?

Page 5: A4 thread blockingisevil

“The Free Lunch

is OVER.”

Herb Sutter

December 2004

Page 6: A4 thread blockingisevil

Clock speed

Execution optimization

Cache

Page 7: A4 thread blockingisevil

Cache

Hyperthreading

Multicore

Cache

Page 8: A4 thread blockingisevil

Write Multithreaded

Application

Page 9: A4 thread blockingisevil

MULTI

THREAD

Page 10: A4 thread blockingisevil

CONCURRENCY

Page 11: A4 thread blockingisevil

하지만 현실은?

Page 12: A4 thread blockingisevil

줄을 서서 기다린다

Page 13: A4 thread blockingisevil

도대체

왜?

Page 14: A4 thread blockingisevil

Thread

Blocking

Page 15: A4 thread blockingisevil

Starvation

Deadlock

Page 16: A4 thread blockingisevil

Starvation

Page 17: A4 thread blockingisevil

Task A Task B

1: Lock 1: Sleep 1msec

2: Sleep 2msec

3: Unlock

Page 18: A4 thread blockingisevil
Page 19: A4 thread blockingisevil

Deadlock Hold & Wait

Page 20: A4 thread blockingisevil

Thread A Thread B

1A: Lock 1B: Lock

2A: Request 2B: Send Response

3A: Wait for Response 3B: Unlock

4A: Do something with Response

5A: Unlock

Page 21: A4 thread blockingisevil

Thread A Thread B

1A: Lock 1B: Lock

2A: Request 2B: Send Response

3A: Wait for Response 3B: Unlock

4A: Do something with Response

5A: Unlock

Page 22: A4 thread blockingisevil

My

Problem

Page 23: A4 thread blockingisevil

로비-룸 형태의

게임을 제작

Page 24: A4 thread blockingisevil

Remote Procedure Call

Page 25: A4 thread blockingisevil

처리 로직을 함수 단위로

짜기 때문에 개발이 쉽다

Page 26: A4 thread blockingisevil

Game Client Lobby Room 방 입장 RPC 인증 RPC

Page 27: A4 thread blockingisevil

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

방 입장 RPC

처리 로직

인증 RPC

처리 로직

Page 28: A4 thread blockingisevil

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

방 입장 RPC

처리 로직

인증 RPC

처리 로직

인증 RPC 반환

방 입장 RPC 반환

Page 29: A4 thread blockingisevil

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

방 입장 RPC

처리 로직

인증 RPC

처리 로직 Lobby 응답 지연

Page 30: A4 thread blockingisevil

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

방 입장 RPC

처리 로직

인증 RPC

처리 로직 Lobby 응답 지연

Room서버 throughput

저하

Page 31: A4 thread blockingisevil

악의 축은?

Page 32: A4 thread blockingisevil

Thread

Blocking

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

Page 33: A4 thread blockingisevil

RPC의 태생적 한계

Page 34: A4 thread blockingisevil

처리 로직을 함수 단위로

짜기 때문에 개발이 쉽다

Page 35: A4 thread blockingisevil

처리 로직을 함수 단위로

짜기 때문에 찢을 수 없다

Page 36: A4 thread blockingisevil

RPC::Result* JoinRoom(…)

{

RPC::Result answer = RPC::SyncCall(“VerifyLobbyUserToken”, …);

….

return result;

}

Page 37: A4 thread blockingisevil

우리가 원하는 것

Page 38: A4 thread blockingisevil

RPC의 장점인

순차적 코드 작성

Non-Blocking

Page 39: A4 thread blockingisevil

가능한 해결책은?

Page 40: A4 thread blockingisevil

RPC 이원화

Page 41: A4 thread blockingisevil

Game Client Lobby Room

방 입장 응답 RPC

인증 요청 RPC 방 입장 요청 RPC

인증 응답 RPC

Page 42: A4 thread blockingisevil

Game Client Lobby Room

방 입장 응답 RPC

인증 요청 RPC 방 입장 요청 RPC

인증 응답 RPC

Non-Blocking O

순차적 코딩 X

Page 43: A4 thread blockingisevil

RPC 이원화

Page 44: A4 thread blockingisevil

Thread Pool 분리

Page 45: A4 thread blockingisevil

Game Client Lobby TP#1

방 입장 RPC 인증 RPC Room

TP#2

기타 RPCs

Page 46: A4 thread blockingisevil

Game Client Lobby TP#1

방 입장 RPC 인증 RPC Room

TP#2

기타 RPCs

순차적 코딩 O

Non-Blocking X

Page 47: A4 thread blockingisevil

Thread Pool 분리

Page 48: A4 thread blockingisevil

이대로 끝인 거야?

Page 49: A4 thread blockingisevil

Solution

Page 50: A4 thread blockingisevil

Asynchronous

Programming

Page 51: A4 thread blockingisevil

Request(callback, …)

Page 52: A4 thread blockingisevil

Pros: Non-Blocking

Page 53: A4 thread blockingisevil

Cons: Can’t Write Sequential Code

Can’t Use Stack Variable

Can’t Split Programming Construct

Page 54: A4 thread blockingisevil

어렵다!

Page 55: A4 thread blockingisevil

이대로 끝인 거야?

Page 56: A4 thread blockingisevil

Coroutine

Page 57: A4 thread blockingisevil

Similar to Thread

Page 58: A4 thread blockingisevil

Line of Execution

Page 59: A4 thread blockingisevil

Stack

&

Local Variable

Page 60: A4 thread blockingisevil

But

Page 61: A4 thread blockingisevil

Non-preemptive

Page 62: A4 thread blockingisevil

Instruction: Yield

Yield Break

Resume

Page 63: A4 thread blockingisevil

Coroutine을

제공하는 언어는?

Page 64: A4 thread blockingisevil

C#

Erlang

Haskell

JavaScript(since 1.7)

Lua

Perl

Python(since 2.5)

Ruby

Page 65: A4 thread blockingisevil

C++은?

Page 66: A4 thread blockingisevil
Page 67: A4 thread blockingisevil

손수 구현해야 한다

Page 68: A4 thread blockingisevil

Windows: Fiber

Linux:

getcontext/setcontext

makecontext

swapcontext

Page 69: A4 thread blockingisevil

Asynchronous

Programming

+

Coroutine

Page 70: A4 thread blockingisevil

Non-Blocking

&

순차적 코드 작성

Page 71: A4 thread blockingisevil

Solution

for

Starvation

Page 72: A4 thread blockingisevil

Task A Task B

1: Lock 1: Sleep 1msec

2: Sleep 2msec

3: Unlock

Page 73: A4 thread blockingisevil

Task A Task B

Thread A 1: Sleep 1msec

1: Create & Resume Coroutine

2: Request Lock

3: Yield

Thread A‟

4: Resume

5: Sleep 2msec

6: Yield Break

7: Unlock

Non-Blocking

Sequential

Code

Page 74: A4 thread blockingisevil
Page 75: A4 thread blockingisevil
Page 76: A4 thread blockingisevil

Solution for

Deadlock Hold & Wait

Page 77: A4 thread blockingisevil

Thread A Thread B

1A: Lock 1B: Lock

2A: Request 2B: Send Response

3A: Wait for Response 3B: Unlock

4A: Do something with Response

5A: Unlock

Page 78: A4 thread blockingisevil

Thread A Thread B

1A: Lock 1B: Lock

2A: Create & Resume Coroutine 2B: Send Response

3A: Request 3B: Unlock

4A: Yield

5A: Unlock

Thread A‟ (invoked by response)

6A’: Lock

7A’: Resume

8A’: Do something

with response

9A’: Yield Break

10A’: Unlock

Non-Blocking

Sequential

Code

Page 79: A4 thread blockingisevil

Solution

for

My Problem

Page 80: A4 thread blockingisevil

Thread

Blocking

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

Page 81: A4 thread blockingisevil

룸 Thread 로비 서비스

1R: 인증 요청 1L: 인증 요청 처리

2R: 인증 응답 대기 2L: 인증 응답 보내기

3R: 방 입장 처리

Page 82: A4 thread blockingisevil

룸 Thread 로비 서비스

1R: Create & Resume Coroutine 1L: 인증 요청 처리

2R: 인증 요청 2L: 인증 응답 보내기

3R: Yield

룸 Thread‟ (invoked by response)

4R’: Resume

5R’: 방 입장 처리

6R’: Yield Break

Non-Blocking

Sequential

Code

Page 83: A4 thread blockingisevil

Request & Wait

Request & Yield

Page 84: A4 thread blockingisevil

Non-Blocking

RPC의 장점인

순차적 코드 작성

Page 85: A4 thread blockingisevil

Coroutine

(Fiber)

Thread

CPU CPU CPU CPU

User-mode Scheduling

Kernel-mode Scheduling

Page 86: A4 thread blockingisevil

Coroutine

Pool

Network I/O

Thread Pool

RPC Task Queue

RPC

Execution

Thread Pool

Page 87: A4 thread blockingisevil

RPC Task

Queue RPC Execution

Thread Network I/O

Thread

enqueue

task

dequeue

task

acquire coroutine

enqueue

resume

task

dequeue

resume

task

resume

yield break

release coroutine

Network

Event

Network

Event

Coroutine

Pool

pooling

coroutine

RPC

Execution

yield return

start

Page 88: A4 thread blockingisevil

RPC Task

Queue RPC Execution

Thread 1 Coroutine

Pool

RPC

Execution

enqueue

task

dequeue

task

acquire coroutine

coroutine

yield return

enqueue

resume

task

dequeue

resume

task

release coroutine

Network

Event

Network

Event

pooling

RPC Execution

Thread 2

resume

yield break

resume

Network I/O

Thread

Page 89: A4 thread blockingisevil

RPC::Result* JoinRoom(…)

{

RPC::Result answer = RPC::SyncCall(“VerifyLobbyUserToken”, …);

….

return result;

}

Page 90: A4 thread blockingisevil

RPC::Result* JoinRoom(…)

{

RPC::Result answer = RPC::SyncCallYield(“VerifyLobbyUserToken”, …);

….

return result;

}

Page 91: A4 thread blockingisevil

TPS

쓰래드 갯수

Page 92: A4 thread blockingisevil

Wrap-up

Page 93: A4 thread blockingisevil

“The free lunch

is OVER.”

Write Multithreaded

Application

CONCURRENCY

Page 94: A4 thread blockingisevil

Thread Blocking is Evil

Starvation Deadlock

Page 95: A4 thread blockingisevil

Asynchronous

Programming

+

Coroutine

Page 96: A4 thread blockingisevil

Non-Blocking

+

Writing

Sequential Code

Page 97: A4 thread blockingisevil

Request & Wait

Request & Yield

Page 98: A4 thread blockingisevil

Inspired by Jeffrey Richter

‘Simplified APM With

The AsyncEnumerator’

Page 99: A4 thread blockingisevil

완벽함이란

더 이상 추가할 것이 없을

때가 아니라

더 이상 버릴 것이 없을

때 완성된다. „성당과 시장‟에서