A4 thread blockingisevil

Post on 23-Jun-2015

1.781 views 0 download

Transcript of A4 thread blockingisevil

Thread Blocking Is Evil

게임네트웍컴포넌트팀

김준현

Thread

Blocking

Non-Blocking

&

순차적 코드 작성

Why does

Multi-Thread

matter?

“The Free Lunch

is OVER.”

Herb Sutter

December 2004

Clock speed

Execution optimization

Cache

Cache

Hyperthreading

Multicore

Cache

Write Multithreaded

Application

MULTI

THREAD

CONCURRENCY

하지만 현실은?

줄을 서서 기다린다

도대체

왜?

Thread

Blocking

Starvation

Deadlock

Starvation

Task A Task B

1: Lock 1: Sleep 1msec

2: Sleep 2msec

3: Unlock

Deadlock Hold & Wait

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

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

My

Problem

로비-룸 형태의

게임을 제작

Remote Procedure Call

처리 로직을 함수 단위로

짜기 때문에 개발이 쉽다

Game Client Lobby Room 방 입장 RPC 인증 RPC

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

방 입장 RPC

처리 로직

인증 RPC

처리 로직

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

방 입장 RPC

처리 로직

인증 RPC

처리 로직

인증 RPC 반환

방 입장 RPC 반환

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

방 입장 RPC

처리 로직

인증 RPC

처리 로직 Lobby 응답 지연

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

방 입장 RPC

처리 로직

인증 RPC

처리 로직 Lobby 응답 지연

Room서버 throughput

저하

악의 축은?

Thread

Blocking

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

RPC의 태생적 한계

처리 로직을 함수 단위로

짜기 때문에 개발이 쉽다

처리 로직을 함수 단위로

짜기 때문에 찢을 수 없다

RPC::Result* JoinRoom(…)

{

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

….

return result;

}

우리가 원하는 것

RPC의 장점인

순차적 코드 작성

Non-Blocking

가능한 해결책은?

RPC 이원화

Game Client Lobby Room

방 입장 응답 RPC

인증 요청 RPC 방 입장 요청 RPC

인증 응답 RPC

Game Client Lobby Room

방 입장 응답 RPC

인증 요청 RPC 방 입장 요청 RPC

인증 응답 RPC

Non-Blocking O

순차적 코딩 X

RPC 이원화

Thread Pool 분리

Game Client Lobby TP#1

방 입장 RPC 인증 RPC Room

TP#2

기타 RPCs

Game Client Lobby TP#1

방 입장 RPC 인증 RPC Room

TP#2

기타 RPCs

순차적 코딩 O

Non-Blocking X

Thread Pool 분리

이대로 끝인 거야?

Solution

Asynchronous

Programming

Request(callback, …)

Pros: Non-Blocking

Cons: Can’t Write Sequential Code

Can’t Use Stack Variable

Can’t Split Programming Construct

어렵다!

이대로 끝인 거야?

Coroutine

Similar to Thread

Line of Execution

Stack

&

Local Variable

But

Non-preemptive

Instruction: Yield

Yield Break

Resume

Coroutine을

제공하는 언어는?

C#

Erlang

Haskell

JavaScript(since 1.7)

Lua

Perl

Python(since 2.5)

Ruby

C++은?

손수 구현해야 한다

Windows: Fiber

Linux:

getcontext/setcontext

makecontext

swapcontext

Asynchronous

Programming

+

Coroutine

Non-Blocking

&

순차적 코드 작성

Solution

for

Starvation

Task A Task B

1: Lock 1: Sleep 1msec

2: Sleep 2msec

3: Unlock

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

Solution for

Deadlock Hold & Wait

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

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

Solution

for

My Problem

Thread

Blocking

Game Client Lobby Room

방 입장 RPC 호출

인증 RPC 호출

인증 RPC 반환

방 입장 RPC 반환

룸 Thread 로비 서비스

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

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

3R: 방 입장 처리

룸 Thread 로비 서비스

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

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

3R: Yield

룸 Thread‟ (invoked by response)

4R’: Resume

5R’: 방 입장 처리

6R’: Yield Break

Non-Blocking

Sequential

Code

Request & Wait

Request & Yield

Non-Blocking

RPC의 장점인

순차적 코드 작성

Coroutine

(Fiber)

Thread

CPU CPU CPU CPU

User-mode Scheduling

Kernel-mode Scheduling

Coroutine

Pool

Network I/O

Thread Pool

RPC Task Queue

RPC

Execution

Thread Pool

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

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

RPC::Result* JoinRoom(…)

{

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

….

return result;

}

RPC::Result* JoinRoom(…)

{

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

….

return result;

}

TPS

쓰래드 갯수

Wrap-up

“The free lunch

is OVER.”

Write Multithreaded

Application

CONCURRENCY

Thread Blocking is Evil

Starvation Deadlock

Asynchronous

Programming

+

Coroutine

Non-Blocking

+

Writing

Sequential Code

Request & Wait

Request & Yield

Inspired by Jeffrey Richter

‘Simplified APM With

The AsyncEnumerator’

완벽함이란

더 이상 추가할 것이 없을

때가 아니라

더 이상 버릴 것이 없을

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