SlideShare a Scribd company logo
알파희
PyPy/RPython으로 20배 빨라지는 JIT 아희 인터프리터
PyCon Korea 2015 정윤원
2015-08-30
발표자
• 구름 입력기 (OS X, iOS)
• XChat Azure (OS X)
• 깐깐하게 배우는 파이썬 - 프로그래밍 입문서 (번역)
• OS X, iOS가 github에 많이 걸려 있지만

파이썬으로도 코딩합니다 ㅜㅜ
개요
• PyPy 기술로 인터프리터를 만들면
• 쉽고 빠르게 만들 수 있고
• 실행 속도도 빠릅니다!
개요
• PyPy 기술로 인터프리터를 만들면
• 쉽고 빠르게 만들 수 있고
• 실행 속도도 빠릅니다!
• 어떻게? 무엇을?
목차
1. 아희는 무엇인가요? (5분)

구현을 다루려면, 조금은 알면 편해요
2. PyPy는 무엇인가요? 그럼 RPython은? (15분)

순식간에 JIT 아희 인터프리터를 만들게 해줄 강력한 도구
3. RPython으로 인터프리터를 만들어 봅시다 (15분)

이렇게 쉽고 간단할수도 있어요!
1 아희
아희
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
아희
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
야! 신난다!
“한글로 쓰는 난해한 프로그래밍 언어”
아희
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
아희
“한글로 쓰는 난해한 프로그래밍 언어”
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
난해한 프로그래밍 언어는 몇몇 해커들 사이에서, 컴
퓨터 프로그래밍 언어의 한계를 테스트하기 위해서,
혹은 어떤 개념의 증명으로서, 혹은 장난으로 설계된
프로그래밍 언어이며, 실용적인 프로그래밍에 적용
하기 위한 의도로 만들어진 언어가 아니다.
(위키백과, [[난해한 프로그래밍 언어]])
난해한 프로그래밍 언어
• 보통의 프로그래밍 언어:

사용자가 쉽고 편하게 프로그래밍을 하도록 도와주자!
• 난해한 프로그래밍 언어:

실용적으로 프로그래밍하기보다는 특별한 목적을 가진 언어
• 아희:

읽고 쓰기는 어렵지만, 언어의 구조는 간단해요
“한글로 쓰는 난해한 프로그래밍 언어”
출력: Hello, World!
아희
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
순서대로 실행하지 않는 2차원 언어!
출력: Hello, World!
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
아희
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
ㅏㅏㅏㅏㅏㅏㅏㅜ
ㅏㅏㅏㅏㅏㅏㅜㅜ
ㅗㅏㅏㅏㅏㅜㅜㅜ
ㅗㅗㅏㅏㅜㅜㅜㅜ
ㅗㅗㅗㅢㅓㅜㅜㅜ
ㅗㅗㅗㅓㅓㅓㅜㅜ
ㅗㅗㅓㅓㅓㅓㅓㅜ
ㅗㅓㅓㅓㅓㅓㅓㅓ
아희
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
아희
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
ㅏ: 방향, 오른쪽으로 진행



ㅂ: 명령어, 값 저장하기
ㅁ: 피연산자, 정수 4
아희
밤밣따빠밣밟따뿌
빠맣파빨받밤뚜뭏
돋밬탕빠맣붏두붇
볻뫃박발뚷투뭏붖
뫃도뫃희멓뭏뭏붘
뫃봌토범더벌뿌뚜
뽑뽀멓멓더벓뻐뚠
뽀덩벐멓뻐덕더벅
스택 _
-
-
-
-
스택 _
4
-
-
-
스택 _
4
8
-
-
스택 _
32
-
-
-
스택 _
32
32
-
-
push 4

ㅂ ㅁ
push 8

ㅂ ㅀ
mult

ㄸ
dup

ㅃ
밤 밣 따 빠
아희 컨퍼런스가 아니므로
구글: “아희 표준”
이런걸 왜 PyPy로 구현했나요?
• 언어가 단순해야 인터프리터를 구현하기 쉽고!
• 인터프리터가 단순해야 최적화 결과도 보기 쉽고!
• 그래야 좋은 예제로 재미있는 이야기를 할 수 있고!
이런걸 왜 PyPy로 구현했나요?
• 언어가 단순해야 인터프리터를 구현하기 쉽고!
• 인터프리터가 단순해야 최적화 결과도 보기 쉽고!
• 그래야 좋은 예제로 재미있는 이야기를 할 수 있고!
• … 라고 해주세요
이런걸 왜 PyPy로 구현했나요?
• 쓸고퀄: 만우절 정신 (2015)
이런걸 왜 PyPy로 구현했나요?
• 쓸고퀄: 만우절 정신 (2015)
• ※ (우연히) 아희아희를 실행하는 데 특히 유용하게 쓰입니다!
• https://github.com/aheui/aheui.aheui
2 PyPy
PyPy
• PyPy: (흔히) 파이썬으로 만들어진 파이썬 구현체
인터프리터를 만들 도구
PyPy
• PyPy: (흔히) 파이썬으로 만들어진 파이썬 구현체
• CPython보다 빠르다던데?
• 파이썬으로 구현했는데 어떻게?
인터프리터를 만들 도구
PyPy
• PyPy: (흔히) 파이썬으로 만들어진 파이썬 구현체
• 인터프리터 작성을 위한 언어인 RPython
• RPython으로 작성된 파이썬 인터프리터
• PyPy는 두 가지를 *모두* 포함하는 프로젝트입니다
인터프리터를 만들 도구
PyPy
• PyPy: (흔히) 파이썬으로 만들어진 파이썬 구현체
• 인터프리터 작성을 위한 언어인 RPython
• RPython으로 작성된 파이썬 인터프리터
• PyPy는 두 가지를 *모두* 포함하는 프로젝트입니다
인터프리터를 만들 도구
RPython
• RPython: 정적으로 컴파일 되지만, 제약이 있는 파이썬
• 정적으로 컴파일 할 수 있는 코드만 지원합니다
• python2 의 부분집합(과 비슷)입니다
• 보너스! JIT 컴파일러 툴체인이 내장되어 있어요!
• 편리하고 강력한 언어로 빠르게 인터프리터를 만들어(RPython)
빠르게 실행(JIT)합니다. => PyPy
Restricted Python
JIT 컴파일러
• JIT 컴파일?
• 자주 사용되는 코드를 런타임에 추적해서,
• 최적화 후 컴파일 하여 실행시간에 바이너리를 생성합니다
• 런타임에만 알 수 있는 정보로 적극적인 최적화도 할 수 있어요
RPython
• RPython: 정적으로 컴파일 되지만, 제약이 있는 파이썬
• 제약이 있지만, C와 같은 언어보다 편리합니다.
• BigInt, Unicode 처리 등....
• RPython의 해당 기능을 이용하면 구현이 공짜!
Restricted Python
RPython
• RPython: 정적으로 컴파일 되지만, 제약이 있는 파이썬
• 게다가 JIT 컴파일러 툴체인이 내장되어 있다는데...
• CPython보다 PyPy가 더 빠른 비결
• 엄청나게 어려운 JIT 컴파일러 붙이기가 (거의) 공짜!
Restricted Python
PyPy, 정말 편리한가요?
Prolog
Smalltalk
JavaScript
Io
Scheme
Gameboy
PHP
Ruby
알려진 구현체가 있는 진지한 언어
PyPy, 얼마나 빠른가요?
• PyPy: 7.0x of CPython (2015)
• HippyVM: 7.3x of PHP / 2x of HHVM (2014)
PyPy, 얼마나 빠른가요?
• PyPy: 7.0x of CPython (2015)
• HippyVM: 7.3x of PHP / 2x of HHVM (2014)
• HHVM에 비해 적은 인원, 적은 코드로 더 좋은 성능
PyPy, 왜 빠른가요?
• RPython으로 인터프리터를 작성하고,
• 제공되는 툴체인으로 JIT를 하기 위한 힌트를 추가하면,
• 인터프리터가 실행추적 JIT로 변신!
PyPy, 왜 빠른가요?
• 실행추적(tracing) JIT
• 실용적으로 두 번째로 널리 쓰이는 JIT 기법입니다
• 실행추적 JIT는 실행시간에 추적한 루프 단위로 최적화합니다
• 전통적인 JIT
• 자주 함수되는 함수를 프로파일 해서 함수 단위로 컴파일합니다
메타 실행추적 JIT
• RPython을 이용해 실행추적 JIT를 구현한다. (X)
• 인터프리터를 구현하면 실행추적 JIT의 효과를 낸다. (O)
• 어떤 인터프리터라도 (잘 손질하면) 변신!
• “메타”
– Arthur C. Clarke,
“Any sufficiently advanced technology is
indistinguishable from magic.”
메타 실행추적 JIT
코드 읽기
실행
결과 저장
인터프리터
…
다음 코드로
JIT
루프 추적
최적화
컴파일
최적화 대상
직접 작성하는 부분JIT 생성기
메타 실행추적 JIT
코드 읽기
실행
결과 저장
인터프리터
…
다음 코드로
JIT
루프 추적
최적화
컴파일
실행 코드
블랙박스
인터프리터 코드가 실행코드를 포함한 정보에 따라

최적화되어서 실행 코드를 최적화하는 효과 발생
PyPy, 왜 빠른가요?
• RPython: 메타 실행추적 JIT를 구현한 JIT 툴체인을 포함
• RPython으로 인터프리터를 구현하면

구현된 인터프리터에 실행추적 JIT 컴파일러를 적용합니다
• RPython으로 만들어진 파이썬(PyPy)은

컴파일된 인터프리터가 실행추적 JIT로 실행이 되고

따라서 이 인터프리터로 코드를 실행하면

인터프리터를 JIT하는 과정에서 코드 정보를 포함해서 최적화!
• HippyVM이 작은 코드로 HHVM보다 빨랐던 비결
3 알파희
알파희
• 아희에 적용해 보자!
• (실행추적 JIT를 위해) 루프 추적을 도와주는 것이 핵심
• RPython으로 구현도 하고, RPython으로 구현하기 쉽게 다른
일도 조금 하고...
알파희 1 - 전처리
• 2차원 언어는 런타임이 복잡해지므로 코드 분석 후 선형화
• 본심: RPython을 잘 모르니 가능하면 런타임을 작게 유지하자
• 밯망희
L0: PUSHCHAR ; 밯
BRPOP1 L4 ; ‘망’을 실행할 스택이
충분하지 않으면 L4
로 점프
POPNUM ; 망
HALT ; 희
L4: JMP L0 ;
알파희 2 - 인터프리터
코드 읽기
실행
결과 저장
인터프리터
…
다음 코드로
JIT
루프 추적
최적화
컴파일
실행 코드
블랙박스
알파희 2 - 인터프리터
• 직접 코드를 짜 넣을 부분
• 쉬워요! - 전처리 단계에서 귀찮은걸 많이 해결했으니까~
알파희 2 - 인터프리터
# program: 직렬화된 아희 바이트코드의 리스트
def mainloop(program, debug):
s = Storage()
pc = 0
while pc < len(program): # 코드를 한 줄씩 실행
op, value = program[pc]
if op == OP_ADD:
r1, r2 = s.selected.pop(), s.selected.pop()
s.selected.push(r2 + r1)
elif op == OP_SUB:
…
알파희 2 - 인터프리터
• ※ RPython으로 구현하기는 했지만 아직 JIT를 적용하기 전
$ rpython aheui.py # 컴파일 후 aheui-c 를 생성한다
$ time aheui-c logo.aheui => 23.5s
$ time caheui logo.aheui => 21.5s
• caheui보다 10% 정도 느린 정도로, 상당히 빠른 편
• “시작이 반이다” => 단순히 구현했을 뿐인데 이미 어느정도 빠르다!
• RPython은 파이썬 코드이지만, 네이티브 바이너리로 컴파일 가능하기 때문
알파희 3 - JitDriver
코드 읽기
실행
결과 저장
인터프리터
…
다음 코드로
JIT
루프 추적
최적화
컴파일
실행 코드
블랙박스
알파희 3 - JitDriver
from rpython.rlib.jit import JitDriver
driver = JitDriver(greens=['pc', 'program'], reds=['storage'])
def mainloop(program):
# initialization codes
pc = 0; storage = Stoarge()
while <cond>:
driver.jit_merge_point(
pc=pc, program=program, storage=storage)
<actual codes>
알파희 3 - JitDriver
from rpython.rlib.jit import JitDriver
driver = JitDriver(greens=['pc', 'program'], reds=['storage'])
def mainloop():
# initialization codes
pc = 0; storage = Stoarge()
while <cond>:
driver.jit_merge_point(
pc=pc, program=program, storage=storage)
<actual codes>
코드의 실행조건을 결정하는 상수 실행 결과 변경되는 산출물
루프 맨 앞에 삽입하는 것만으로 JIT 동작 시작!
알파희 4 - 루프 추적
코드 읽기
실행
결과 저장
인터프리터
…
다음 코드로
JIT
루프 추적
최적화
컴파일
실행 코드
블랙박스
알파희 4 - 루프 추적
• 루프 추적에 성공해야 최적화가 가능하다
1. green이 모두 같으면 같은 자리로 돌아온 것(루프)으로 판단
2. 같은 경로가 반복되면 최적화 시도
3. 가정이 맞는 동안 계속 최적화 된 코드를 실행
=> 가정이 깨진다면? 최적화에 실패하거나 최적화 된 코드를 버림
알파희 4 - 루프 추적
• jit_merge_point: 핫루프 판단의 기준이 되는 기준점
• 규칙: jit_merge_point 앞에 나타나는 모든 변수는 green 또는
red로 표시해야 합니다
• 동작: green이 모두 일치하면 같은 문맥으로 간주합니다.

같은 문맥이 기준 이상 반복되면 핫루프로 간주합니다.
알파희 4 - 루프 추적
• 이득: 최적화된 코드를 실행하는 만큼 실행 시간 이득을 얻습니다.
• 손실: jit_merge_point에서 코드를 추적하고 최적화를 시도하는
비용이 발생합니다. 최적화 이후에는 최적화된 코드가 올바른 코
드인지 점검하는 실행비용이 발생합니다.
알파희 4 - 루프 추적
프로그램 (코드)
L0: PUSHCHAR
BRPOP1 L4
POPNUM
HALT
L4: JMP L0
프로그램 카운터

현재 코드: L0
메모리 (스택)
_: []
ㄱ: []
···
ㅎ: []
불변
변하지만
같은 값이면

같은 코드 실행
변하고

다른 값이어도 

같은 코드 실행
green green red
알파희 4 - 루프 추적
코드
L0: PUSHCHAR
BRPOP1 L4
POPNUM
HALT
L4: JMP L0
프로그램 카운터

현재 코드: L0
메모리 (스택)
_: []
ㄱ: []
···
ㅎ: []
불변
변하지만
같은 값이면

같은 코드 실행
변하고

다른 값이어도 

같은 코드 실행
green green red
정말?
알파희 4 - 루프 추적
x = 0
while True:
x += 1
if x < 1000000:
print ‘a’
else:
print ‘b’
<- 메모리에 해당하는 x가

코드 흐름에 영향
알파희 4 - 루프 추적
• 저장공간은 정말 실행에 영향을 끼치지 않을까?
• 저장공간이 스택인지, 큐인지
• 저장공간에서 뽑아낼 값이 충분한지
• 저장공간의 변수가 비교문을 참으로 만드는지
• … 와 같은 이슈가 있지만, “아희”에 대해 파고 들지 말고 통과!
알파희 5 - 루프 추적 최적화
• 기본 동작: 매 명령을 실행할 때마다 jit_merge_point에서 루프
를 찾으려 시도한다
• 수정: “루프가 될 수 있는 지점”을 힌트로 줘서 추적 비용을 줄인
다 (can_enter_jit)
• “루프가 될 수 있는 지점” = jump가 발생하는 지점
• ~= PC가 1씩 늘어나면 절대로 루프가 생기지 않으니까
알파희 5 - 루프 추적 최적화
def mainloop(program, debug):
pc = 0; storage = init_storage()
while pc < program.size:
driver.jit_merge_point(pc=pc, proram=program)
op, operand = program[pc]
if needs_jump(op, operand, storage):
driver.can_enter_jit(pc=pc, program=program)
pc = operand
else:
# other operations
pc += 1
알파희 5 - 루프 추적 최적화
밦밦따빠뚜
뿌뚜뻐뚜뻐
따ㅇㅇㅇ우
ㅇㅇ아ㅇ분
ㅇㅇ초뻐터
ㅇㅇ망희
……
L1: DUP ; L1 뻐
BRZ L6 ; L2 초
PUSH 2 ; L3 아 / 분
SUB ; L4 터
JMP L1 ; L5
L6: POPNUM ; L6 망
HALT ; L7 희
테스트 코드 선형화 코드
5개의 명령어를 반복한다
알파희 5 - 루프 추적 최적화
[220a6f122e0a] {jit-log-noopt-loop
# Loop 0 () : noopt with 55 ops
…
debug_merge_point(0, 0, '#2(s1)_BRZ_14')
i17 = int_add(i4, -1)
setfield_gc(p2, p6, descr=<FieldP aheui.Stack.inst_head 8>)
i19 = int_sub(i12, 1)
setfield_gc(p2, i19, descr=<FieldS aheui.Stack.inst_size 16>)
i20 = int_is_zero(i7)
guard_false(i20)
i22 = int_le(0, i17)
guard_value(i22, 1)
debug_merge_point(0, 0, '#3(s1)_PUSH_2')
i25 = int_add(i17, 1)
p27 = new_with_vtable(4297581752)
setfield_gc(p27, 2, descr=<FieldS aheui.Link.inst_value 16>)
setfield_gc(p27, p6, descr=<FieldP aheui.Link.inst_next 8>)
setfield_gc(p2, p27, descr=<FieldP aheui.Stack.inst_head 8>)
i30 = int_add(i19, 1)
setfield_gc(p2, i30, descr=<FieldS aheui.Stack.inst_size 16>)
i32 = int_le(2, i25)
guard_value(i32, 1)
debug_merge_point(0, 0, '#4(s1)_SUB_-1')
i35 = int_add(i25, -1)
setfield_gc(p2, p6, descr=<FieldP aheui.Stack.inst_head 8>)
i37 = int_sub(i30, 1)
setfield_gc(p2, i37, descr=<FieldS aheui.Stack.inst_size 16>)
i38 = getfield_gc(p6, descr=<FieldS aheui.Link.inst_value 16>)
p39 = new(descr=<SizeDescr 24>)
setfield_gc(p39, 2, descr=<FieldS tuple2.item0 8>)
setfield_gc(p39, i38, descr=<FieldS tuple2.item1 16>)
i40 = int_sub(i38, 2)
setfield_gc(p6, i40, descr=<FieldS aheui.Link.inst_value 16>)
i42 = int_le(0, i35)
guard_value(i42, 1)
debug_merge_point(0, 0, '#5(s1)_JMP_19')
[225dee4ac3ea] {jit-log-opt-loop
# Loop 0 ((jitdriver: get_printable_location disabled, no debug_print)) : loop w
…
debug_merge_point(0, 0, '#2(s1)_BRZ_14')
+199: setfield_gc(p2, i8, descr=<FieldS aheui.Stack.inst_size 16>)
+203: i13 = int_is_zero(i7)
guard_false(i13, descr=<Guard0x100750230>) [i0, p2, p1, None, None]
debug_merge_point(0, 0, '#3(s1)_PUSH_2')
+213: setfield_gc(p2, i10, descr=<FieldS aheui.Stack.inst_size 16>)
+217: i16 = int_le(2, i4)
+229: guard_true(i16, descr=<Guard0x100750288>) [i4, i16, p2, p1, None, p6]
debug_merge_point(0, 0, '#4(s1)_SUB_-1')
+238: i18 = int_sub(i7, 2)
debug_merge_point(0, 0, '#5(s1)_JMP_19')
debug_merge_point(0, 0, '#1(s1)_DUP_-1')
+242: setfield_gc(p2, i8, descr=<FieldS aheui.Stack.inst_size 16>)
+246: setfield_gc(p6, i18, descr=<FieldS aheui.Link.inst_value 16>)
+250: label(i0, p1, p2, i18, p6, descr=TargetToken(4302594152))
debug_merge_point(0, 0, '#1(s1)_DUP_-1')
debug_merge_point(0, 0, '#2(s1)_BRZ_14')
+256: i19 = int_is_zero(i18)
guard_false(i19, descr=<Guard0x1007502e0>) [i0, p2, p1]
debug_merge_point(0, 0, '#3(s1)_PUSH_2')
debug_merge_point(0, 0, '#4(s1)_SUB_-1')
+266: i20 = int_sub(i18, 2)
debug_merge_point(0, 0, '#5(s1)_JMP_19')
(기타 등등을 생략한) 결과
$ time AHEUI=../rpaheui/aheui-c ./test.sh logo/
real 0m1.795s
user 0m1.087s
sys 0m1.262s
$ time AHEUI=../caheui/aheui ./test.sh logo/
real 0m23.953s
user 0m23.843s
sys 0m0.058s
PyPy/RPython: 짧고 쉬운 코드로 빠른 인터프리터 완성!
생략된 내용
• 작업 로그: https://github.com/aheui/rpaheui/blob/
master/LOG.md
핵심
• PyPy 툴킷이 자동으로 붙여주는 JIT 컴파일러가 핫 루프를 찾아
내 가속합니다.
• 정확하게 찾도록 도와줍시다.
• 불필요하게 깐깐하면: 추적 비용이 증가
• 허술해서 guard가 틀리면: 최적화 비용 낭비
• 쉽게 찾도록 도와줍시다.
RPython으로 뭐든 빠르게?
• RPython을 쓰니 아희 인터프리터가 이만큼 빨라졌어요!
• 그럼 내가 만드는 파이썬 프로그램이나 라이브러리 OOO도
RPython으로 짠다면!?
• => 안됩니다.
• http://rpython.readthedocs.org/en/latest/faq.html#do-
i-have-to-rewrite-my-programs-in-rpython
의의
• 아희에 JIT 컴파일을 지원하는 인터프리터가 생겼다
• 아희아희를 실용적인 속도로 실행할 수 있는 인터프리터가 생겼다
• …??
의의
• 구전, 예제, PyPy 코드로만 전해지는 빈약한 문서에 예제 하나
• RPython의 버그 발견 및 수정!
• 쓰는 사람들은 이미 RPython 사용에 익숙하고
• 프로그래밍 언어가 유니코드를 잔뜩 쓰는 경우가 드물어서
참조
• 아희의 표준과 헬로 월드

- http://aheui.github.io/specification.ko/
• PyPy로 구현된 언어 - http://pypy.org/features.html
• PyPy의 속도 - http://speed.pypy.org/
• HHVM의 속도 - http://hippyvm.com/#performance
도움 주신 분들
• Freenode/#pypy
• arigato (Armin Rigo), fijal (Maciej Fijalkowski)
• sanxiyn (서상현)
궁금한게 있나요?
• irc://irc.ozinger.org/#aheui
• https://twitter.com/youknowone_

More Related Content

PPTX
文字列照合アルゴリズム(中学3年生向け)
PPTX
【DL輪読会】Emergent World Representations: Exploring a Sequence ModelTrained on a...
PPTX
Spatial Temporal Graph Convolutional Networks for Skeleton-Based Action Recog...
PDF
libpgenでパケット操作
PDF
게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델
PDF
카카오톡으로 여친 만들기 2013.06.29
PDF
[DL輪読会]Understanding Black-box Predictions via Influence Functions
PDF
[DL輪読会]EdgeConnect: Generative Image Inpainting with Adversarial Edge Learning
文字列照合アルゴリズム(中学3年生向け)
【DL輪読会】Emergent World Representations: Exploring a Sequence ModelTrained on a...
Spatial Temporal Graph Convolutional Networks for Skeleton-Based Action Recog...
libpgenでパケット操作
게임서버프로그래밍 #0 - TCP 및 이벤트 통지모델
카카오톡으로 여친 만들기 2013.06.29
[DL輪読会]Understanding Black-box Predictions via Influence Functions
[DL輪読会]EdgeConnect: Generative Image Inpainting with Adversarial Edge Learning

What's hot (20)

PDF
不揮発性メモリ(PMEM)を利用したストレージエンジンの話 #mysql_jp #myna会 #yahoo #mysql #pmem #不揮発性メモリ
PDF
CTF for ビギナーズ ネットワーク講習資料
PPTX
Excel でパケット分析 - グラフ化
PPTX
【DL輪読会】Toolformer: Language Models Can Teach Themselves to Use Tools
PDF
ゼロから始める転移学習
PDF
Random Thoughts on Paper Implementations [KAIST 2018]
PPTX
[研究室論文紹介用スライド] Adversarial Contrastive Estimation
PDF
ELBO型VAEのダメなところ
PDF
RISC-Vの可能性
PDF
プログラミングコンテストでの動的計画法
PDF
【DL輪読会】GPT-4Technical Report
PDF
Cosine Based Softmax による Metric Learning が上手くいく理由
PDF
SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法
PPTX
【DL輪読会】言語以外でのTransformerのまとめ (ViT, Perceiver, Frozen Pretrained Transformer etc)
PDF
プログラミングコンテストでのデータ構造
PPTX
알기쉬운 Variational autoencoder
PDF
Kaggle Happywhaleコンペ優勝解法でのOptuna使用事例 - 2022/12/10 Optuna Meetup #2
PDF
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
PPTX
[논문리뷰] Data Augmentation for 1D 시계열 데이터
PPTX
C#とILとネイティブと
不揮発性メモリ(PMEM)を利用したストレージエンジンの話 #mysql_jp #myna会 #yahoo #mysql #pmem #不揮発性メモリ
CTF for ビギナーズ ネットワーク講習資料
Excel でパケット分析 - グラフ化
【DL輪読会】Toolformer: Language Models Can Teach Themselves to Use Tools
ゼロから始める転移学習
Random Thoughts on Paper Implementations [KAIST 2018]
[研究室論文紹介用スライド] Adversarial Contrastive Estimation
ELBO型VAEのダメなところ
RISC-Vの可能性
プログラミングコンテストでの動的計画法
【DL輪読会】GPT-4Technical Report
Cosine Based Softmax による Metric Learning が上手くいく理由
SSII2021 [OS2-01] 転移学習の基礎:異なるタスクの知識を利用するための機械学習の方法
【DL輪読会】言語以外でのTransformerのまとめ (ViT, Perceiver, Frozen Pretrained Transformer etc)
プログラミングコンテストでのデータ構造
알기쉬운 Variational autoencoder
Kaggle Happywhaleコンペ優勝解法でのOptuna使用事例 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
[논문리뷰] Data Augmentation for 1D 시계열 데이터
C#とILとネイティブと
Ad

Viewers also liked (20)

PDF
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
PDF
Go로 새 프로젝트 시작하기
PDF
파이썬을 배워야하는 이유 발표자료 - 김연수
PDF
Dsl로 만나는 groovy
PPTX
PyCon Korea 2015
PDF
The state of PyPy
PDF
Understanding PyPy - PyConEs 14
PPTX
PDF
PPTX
파이썬 언어 기초
PDF
Baekjoon Online Judge 1451번 풀이
PDF
Baekjoon Online Judge 10986번 풀이
PDF
Baekjoon Online Judge 1201번 풀이
PDF
Baekjoon Online Judge 1648번 풀이
PDF
Baekjoon Online Judge 2873번 풀이
PDF
Baekjoon Online Judge 3015번 풀이
PDF
Baekjoon Online Judge 1019번 풀이
PDF
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
PDF
Coder’s High 2014 풀이
PDF
2014 ACM-ICPC Daejeon 인터넷 예선 해설
GopherCon Korea 2015 - Python 개발자를 위한 Go (이경찬)
Go로 새 프로젝트 시작하기
파이썬을 배워야하는 이유 발표자료 - 김연수
Dsl로 만나는 groovy
PyCon Korea 2015
The state of PyPy
Understanding PyPy - PyConEs 14
파이썬 언어 기초
Baekjoon Online Judge 1451번 풀이
Baekjoon Online Judge 10986번 풀이
Baekjoon Online Judge 1201번 풀이
Baekjoon Online Judge 1648번 풀이
Baekjoon Online Judge 2873번 풀이
Baekjoon Online Judge 3015번 풀이
Baekjoon Online Judge 1019번 풀이
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
Coder’s High 2014 풀이
2014 ACM-ICPC Daejeon 인터넷 예선 해설
Ad

Similar to 알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터 (20)

PDF
모두의 JIT 컴파일러
PPTX
Python 생태계의 이해
PPTX
Hello python 오리엔테이션(파이썬 스터디, 발표자료)
PPTX
Python study 1강 (오픈소스컨설팅 내부 강의)
PPTX
파이선 실전공략-1
PDF
파이썬 소개
PPTX
문과생 대상 파이썬을 활용한 데이터 분석 강의
PDF
파이썬 데이터 분석 (18년)
PDF
파이썬2.7 기초 공부한 것 정리
PDF
파이썬 생존 안내서 (자막)
PDF
1 Python기초 오리엔테이션
PDF
Python 01
PDF
파이썬으로 익히는 딥러닝
PDF
1.Introduction to Python and TensorFlow
PPTX
141103 최창원 파이썬 확장 프로그래밍
PDF
검색엔진에 적용된 ChatGPT
PDF
H3 2011 파이썬으로 클라우드 하고 싶어요
 
PDF
2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요
PDF
H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호
PDF
PyCon 12월 세미나 - 실전 파이썬 프로그래밍 책 홍보
모두의 JIT 컴파일러
Python 생태계의 이해
Hello python 오리엔테이션(파이썬 스터디, 발표자료)
Python study 1강 (오픈소스컨설팅 내부 강의)
파이선 실전공략-1
파이썬 소개
문과생 대상 파이썬을 활용한 데이터 분석 강의
파이썬 데이터 분석 (18년)
파이썬2.7 기초 공부한 것 정리
파이썬 생존 안내서 (자막)
1 Python기초 오리엔테이션
Python 01
파이썬으로 익히는 딥러닝
1.Introduction to Python and TensorFlow
141103 최창원 파이썬 확장 프로그래밍
검색엔진에 적용된 ChatGPT
H3 2011 파이썬으로 클라우드 하고 싶어요
 
2011 H3 컨퍼런스-파이썬으로 클라우드 하고 싶어요
H3 2011 파이썬으로 클라우드 하고 싶어요_분산기술Lab_하용호
PyCon 12월 세미나 - 실전 파이썬 프로그래밍 책 홍보

알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터

  • 1. 알파희 PyPy/RPython으로 20배 빨라지는 JIT 아희 인터프리터 PyCon Korea 2015 정윤원 2015-08-30
  • 2. 발표자 • 구름 입력기 (OS X, iOS) • XChat Azure (OS X) • 깐깐하게 배우는 파이썬 - 프로그래밍 입문서 (번역) • OS X, iOS가 github에 많이 걸려 있지만
 파이썬으로도 코딩합니다 ㅜㅜ
  • 3. 개요 • PyPy 기술로 인터프리터를 만들면 • 쉽고 빠르게 만들 수 있고 • 실행 속도도 빠릅니다!
  • 4. 개요 • PyPy 기술로 인터프리터를 만들면 • 쉽고 빠르게 만들 수 있고 • 실행 속도도 빠릅니다! • 어떻게? 무엇을?
  • 5. 목차 1. 아희는 무엇인가요? (5분)
 구현을 다루려면, 조금은 알면 편해요 2. PyPy는 무엇인가요? 그럼 RPython은? (15분)
 순식간에 JIT 아희 인터프리터를 만들게 해줄 강력한 도구 3. RPython으로 인터프리터를 만들어 봅시다 (15분)
 이렇게 쉽고 간단할수도 있어요!
  • 9. “한글로 쓰는 난해한 프로그래밍 언어” 아희 밤밣따빠밣밟따뿌 빠맣파빨받밤뚜뭏 돋밬탕빠맣붏두붇 볻뫃박발뚷투뭏붖 뫃도뫃희멓뭏뭏붘 뫃봌토범더벌뿌뚜 뽑뽀멓멓더벓뻐뚠 뽀덩벐멓뻐덕더벅
  • 10. 밤밣따빠밣밟따뿌 빠맣파빨받밤뚜뭏 돋밬탕빠맣붏두붇 볻뫃박발뚷투뭏붖 뫃도뫃희멓뭏뭏붘 뫃봌토범더벌뿌뚜 뽑뽀멓멓더벓뻐뚠 뽀덩벐멓뻐덕더벅 아희 “한글로 쓰는 난해한 프로그래밍 언어” 밤밣따빠밣밟따뿌 빠맣파빨받밤뚜뭏 돋밬탕빠맣붏두붇 볻뫃박발뚷투뭏붖 뫃도뫃희멓뭏뭏붘 뫃봌토범더벌뿌뚜 뽑뽀멓멓더벓뻐뚠 뽀덩벐멓뻐덕더벅 난해한 프로그래밍 언어는 몇몇 해커들 사이에서, 컴 퓨터 프로그래밍 언어의 한계를 테스트하기 위해서, 혹은 어떤 개념의 증명으로서, 혹은 장난으로 설계된 프로그래밍 언어이며, 실용적인 프로그래밍에 적용 하기 위한 의도로 만들어진 언어가 아니다. (위키백과, [[난해한 프로그래밍 언어]])
  • 11. 난해한 프로그래밍 언어 • 보통의 프로그래밍 언어:
 사용자가 쉽고 편하게 프로그래밍을 하도록 도와주자! • 난해한 프로그래밍 언어:
 실용적으로 프로그래밍하기보다는 특별한 목적을 가진 언어 • 아희:
 읽고 쓰기는 어렵지만, 언어의 구조는 간단해요
  • 12. “한글로 쓰는 난해한 프로그래밍 언어” 출력: Hello, World! 아희 밤밣따빠밣밟따뿌 빠맣파빨받밤뚜뭏 돋밬탕빠맣붏두붇 볻뫃박발뚷투뭏붖 뫃도뫃희멓뭏뭏붘 뫃봌토범더벌뿌뚜 뽑뽀멓멓더벓뻐뚠 뽀덩벐멓뻐덕더벅
  • 13. 순서대로 실행하지 않는 2차원 언어! 출력: Hello, World! 밤밣따빠밣밟따뿌 빠맣파빨받밤뚜뭏 돋밬탕빠맣붏두붇 볻뫃박발뚷투뭏붖 뫃도뫃희멓뭏뭏붘 뫃봌토범더벌뿌뚜 뽑뽀멓멓더벓뻐뚠 뽀덩벐멓뻐덕더벅 아희 밤밣따빠밣밟따뿌 빠맣파빨받밤뚜뭏 돋밬탕빠맣붏두붇 볻뫃박발뚷투뭏붖 뫃도뫃희멓뭏뭏붘 뫃봌토범더벌뿌뚜 뽑뽀멓멓더벓뻐뚠 뽀덩벐멓뻐덕더벅
  • 18. 이런걸 왜 PyPy로 구현했나요? • 언어가 단순해야 인터프리터를 구현하기 쉽고! • 인터프리터가 단순해야 최적화 결과도 보기 쉽고! • 그래야 좋은 예제로 재미있는 이야기를 할 수 있고!
  • 19. 이런걸 왜 PyPy로 구현했나요? • 언어가 단순해야 인터프리터를 구현하기 쉽고! • 인터프리터가 단순해야 최적화 결과도 보기 쉽고! • 그래야 좋은 예제로 재미있는 이야기를 할 수 있고! • … 라고 해주세요
  • 20. 이런걸 왜 PyPy로 구현했나요? • 쓸고퀄: 만우절 정신 (2015)
  • 21. 이런걸 왜 PyPy로 구현했나요? • 쓸고퀄: 만우절 정신 (2015) • ※ (우연히) 아희아희를 실행하는 데 특히 유용하게 쓰입니다! • https://github.com/aheui/aheui.aheui
  • 23. PyPy • PyPy: (흔히) 파이썬으로 만들어진 파이썬 구현체 인터프리터를 만들 도구
  • 24. PyPy • PyPy: (흔히) 파이썬으로 만들어진 파이썬 구현체 • CPython보다 빠르다던데? • 파이썬으로 구현했는데 어떻게? 인터프리터를 만들 도구
  • 25. PyPy • PyPy: (흔히) 파이썬으로 만들어진 파이썬 구현체 • 인터프리터 작성을 위한 언어인 RPython • RPython으로 작성된 파이썬 인터프리터 • PyPy는 두 가지를 *모두* 포함하는 프로젝트입니다 인터프리터를 만들 도구
  • 26. PyPy • PyPy: (흔히) 파이썬으로 만들어진 파이썬 구현체 • 인터프리터 작성을 위한 언어인 RPython • RPython으로 작성된 파이썬 인터프리터 • PyPy는 두 가지를 *모두* 포함하는 프로젝트입니다 인터프리터를 만들 도구
  • 27. RPython • RPython: 정적으로 컴파일 되지만, 제약이 있는 파이썬 • 정적으로 컴파일 할 수 있는 코드만 지원합니다 • python2 의 부분집합(과 비슷)입니다 • 보너스! JIT 컴파일러 툴체인이 내장되어 있어요! • 편리하고 강력한 언어로 빠르게 인터프리터를 만들어(RPython) 빠르게 실행(JIT)합니다. => PyPy Restricted Python
  • 28. JIT 컴파일러 • JIT 컴파일? • 자주 사용되는 코드를 런타임에 추적해서, • 최적화 후 컴파일 하여 실행시간에 바이너리를 생성합니다 • 런타임에만 알 수 있는 정보로 적극적인 최적화도 할 수 있어요
  • 29. RPython • RPython: 정적으로 컴파일 되지만, 제약이 있는 파이썬 • 제약이 있지만, C와 같은 언어보다 편리합니다. • BigInt, Unicode 처리 등.... • RPython의 해당 기능을 이용하면 구현이 공짜! Restricted Python
  • 30. RPython • RPython: 정적으로 컴파일 되지만, 제약이 있는 파이썬 • 게다가 JIT 컴파일러 툴체인이 내장되어 있다는데... • CPython보다 PyPy가 더 빠른 비결 • 엄청나게 어려운 JIT 컴파일러 붙이기가 (거의) 공짜! Restricted Python
  • 32. PyPy, 얼마나 빠른가요? • PyPy: 7.0x of CPython (2015) • HippyVM: 7.3x of PHP / 2x of HHVM (2014)
  • 33. PyPy, 얼마나 빠른가요? • PyPy: 7.0x of CPython (2015) • HippyVM: 7.3x of PHP / 2x of HHVM (2014) • HHVM에 비해 적은 인원, 적은 코드로 더 좋은 성능
  • 34. PyPy, 왜 빠른가요? • RPython으로 인터프리터를 작성하고, • 제공되는 툴체인으로 JIT를 하기 위한 힌트를 추가하면, • 인터프리터가 실행추적 JIT로 변신!
  • 35. PyPy, 왜 빠른가요? • 실행추적(tracing) JIT • 실용적으로 두 번째로 널리 쓰이는 JIT 기법입니다 • 실행추적 JIT는 실행시간에 추적한 루프 단위로 최적화합니다 • 전통적인 JIT • 자주 함수되는 함수를 프로파일 해서 함수 단위로 컴파일합니다
  • 36. 메타 실행추적 JIT • RPython을 이용해 실행추적 JIT를 구현한다. (X) • 인터프리터를 구현하면 실행추적 JIT의 효과를 낸다. (O) • 어떤 인터프리터라도 (잘 손질하면) 변신! • “메타”
  • 37. – Arthur C. Clarke, “Any sufficiently advanced technology is indistinguishable from magic.”
  • 38. 메타 실행추적 JIT 코드 읽기 실행 결과 저장 인터프리터 … 다음 코드로 JIT 루프 추적 최적화 컴파일 최적화 대상 직접 작성하는 부분JIT 생성기
  • 39. 메타 실행추적 JIT 코드 읽기 실행 결과 저장 인터프리터 … 다음 코드로 JIT 루프 추적 최적화 컴파일 실행 코드 블랙박스 인터프리터 코드가 실행코드를 포함한 정보에 따라
 최적화되어서 실행 코드를 최적화하는 효과 발생
  • 40. PyPy, 왜 빠른가요? • RPython: 메타 실행추적 JIT를 구현한 JIT 툴체인을 포함 • RPython으로 인터프리터를 구현하면
 구현된 인터프리터에 실행추적 JIT 컴파일러를 적용합니다 • RPython으로 만들어진 파이썬(PyPy)은
 컴파일된 인터프리터가 실행추적 JIT로 실행이 되고
 따라서 이 인터프리터로 코드를 실행하면
 인터프리터를 JIT하는 과정에서 코드 정보를 포함해서 최적화! • HippyVM이 작은 코드로 HHVM보다 빨랐던 비결
  • 42. 알파희 • 아희에 적용해 보자! • (실행추적 JIT를 위해) 루프 추적을 도와주는 것이 핵심 • RPython으로 구현도 하고, RPython으로 구현하기 쉽게 다른 일도 조금 하고...
  • 43. 알파희 1 - 전처리 • 2차원 언어는 런타임이 복잡해지므로 코드 분석 후 선형화 • 본심: RPython을 잘 모르니 가능하면 런타임을 작게 유지하자 • 밯망희 L0: PUSHCHAR ; 밯 BRPOP1 L4 ; ‘망’을 실행할 스택이 충분하지 않으면 L4 로 점프 POPNUM ; 망 HALT ; 희 L4: JMP L0 ;
  • 44. 알파희 2 - 인터프리터 코드 읽기 실행 결과 저장 인터프리터 … 다음 코드로 JIT 루프 추적 최적화 컴파일 실행 코드 블랙박스
  • 45. 알파희 2 - 인터프리터 • 직접 코드를 짜 넣을 부분 • 쉬워요! - 전처리 단계에서 귀찮은걸 많이 해결했으니까~
  • 46. 알파희 2 - 인터프리터 # program: 직렬화된 아희 바이트코드의 리스트 def mainloop(program, debug): s = Storage() pc = 0 while pc < len(program): # 코드를 한 줄씩 실행 op, value = program[pc] if op == OP_ADD: r1, r2 = s.selected.pop(), s.selected.pop() s.selected.push(r2 + r1) elif op == OP_SUB: …
  • 47. 알파희 2 - 인터프리터 • ※ RPython으로 구현하기는 했지만 아직 JIT를 적용하기 전 $ rpython aheui.py # 컴파일 후 aheui-c 를 생성한다 $ time aheui-c logo.aheui => 23.5s $ time caheui logo.aheui => 21.5s • caheui보다 10% 정도 느린 정도로, 상당히 빠른 편 • “시작이 반이다” => 단순히 구현했을 뿐인데 이미 어느정도 빠르다! • RPython은 파이썬 코드이지만, 네이티브 바이너리로 컴파일 가능하기 때문
  • 48. 알파희 3 - JitDriver 코드 읽기 실행 결과 저장 인터프리터 … 다음 코드로 JIT 루프 추적 최적화 컴파일 실행 코드 블랙박스
  • 49. 알파희 3 - JitDriver from rpython.rlib.jit import JitDriver driver = JitDriver(greens=['pc', 'program'], reds=['storage']) def mainloop(program): # initialization codes pc = 0; storage = Stoarge() while <cond>: driver.jit_merge_point( pc=pc, program=program, storage=storage) <actual codes>
  • 50. 알파희 3 - JitDriver from rpython.rlib.jit import JitDriver driver = JitDriver(greens=['pc', 'program'], reds=['storage']) def mainloop(): # initialization codes pc = 0; storage = Stoarge() while <cond>: driver.jit_merge_point( pc=pc, program=program, storage=storage) <actual codes> 코드의 실행조건을 결정하는 상수 실행 결과 변경되는 산출물 루프 맨 앞에 삽입하는 것만으로 JIT 동작 시작!
  • 51. 알파희 4 - 루프 추적 코드 읽기 실행 결과 저장 인터프리터 … 다음 코드로 JIT 루프 추적 최적화 컴파일 실행 코드 블랙박스
  • 52. 알파희 4 - 루프 추적 • 루프 추적에 성공해야 최적화가 가능하다 1. green이 모두 같으면 같은 자리로 돌아온 것(루프)으로 판단 2. 같은 경로가 반복되면 최적화 시도 3. 가정이 맞는 동안 계속 최적화 된 코드를 실행 => 가정이 깨진다면? 최적화에 실패하거나 최적화 된 코드를 버림
  • 53. 알파희 4 - 루프 추적 • jit_merge_point: 핫루프 판단의 기준이 되는 기준점 • 규칙: jit_merge_point 앞에 나타나는 모든 변수는 green 또는 red로 표시해야 합니다 • 동작: green이 모두 일치하면 같은 문맥으로 간주합니다.
 같은 문맥이 기준 이상 반복되면 핫루프로 간주합니다.
  • 54. 알파희 4 - 루프 추적 • 이득: 최적화된 코드를 실행하는 만큼 실행 시간 이득을 얻습니다. • 손실: jit_merge_point에서 코드를 추적하고 최적화를 시도하는 비용이 발생합니다. 최적화 이후에는 최적화된 코드가 올바른 코 드인지 점검하는 실행비용이 발생합니다.
  • 55. 알파희 4 - 루프 추적 프로그램 (코드) L0: PUSHCHAR BRPOP1 L4 POPNUM HALT L4: JMP L0 프로그램 카운터
 현재 코드: L0 메모리 (스택) _: [] ㄱ: [] ··· ㅎ: [] 불변 변하지만 같은 값이면
 같은 코드 실행 변하고
 다른 값이어도 
 같은 코드 실행 green green red
  • 56. 알파희 4 - 루프 추적 코드 L0: PUSHCHAR BRPOP1 L4 POPNUM HALT L4: JMP L0 프로그램 카운터
 현재 코드: L0 메모리 (스택) _: [] ㄱ: [] ··· ㅎ: [] 불변 변하지만 같은 값이면
 같은 코드 실행 변하고
 다른 값이어도 
 같은 코드 실행 green green red 정말?
  • 57. 알파희 4 - 루프 추적 x = 0 while True: x += 1 if x < 1000000: print ‘a’ else: print ‘b’ <- 메모리에 해당하는 x가
 코드 흐름에 영향
  • 58. 알파희 4 - 루프 추적 • 저장공간은 정말 실행에 영향을 끼치지 않을까? • 저장공간이 스택인지, 큐인지 • 저장공간에서 뽑아낼 값이 충분한지 • 저장공간의 변수가 비교문을 참으로 만드는지 • … 와 같은 이슈가 있지만, “아희”에 대해 파고 들지 말고 통과!
  • 59. 알파희 5 - 루프 추적 최적화 • 기본 동작: 매 명령을 실행할 때마다 jit_merge_point에서 루프 를 찾으려 시도한다 • 수정: “루프가 될 수 있는 지점”을 힌트로 줘서 추적 비용을 줄인 다 (can_enter_jit) • “루프가 될 수 있는 지점” = jump가 발생하는 지점 • ~= PC가 1씩 늘어나면 절대로 루프가 생기지 않으니까
  • 60. 알파희 5 - 루프 추적 최적화 def mainloop(program, debug): pc = 0; storage = init_storage() while pc < program.size: driver.jit_merge_point(pc=pc, proram=program) op, operand = program[pc] if needs_jump(op, operand, storage): driver.can_enter_jit(pc=pc, program=program) pc = operand else: # other operations pc += 1
  • 61. 알파희 5 - 루프 추적 최적화 밦밦따빠뚜 뿌뚜뻐뚜뻐 따ㅇㅇㅇ우 ㅇㅇ아ㅇ분 ㅇㅇ초뻐터 ㅇㅇ망희 …… L1: DUP ; L1 뻐 BRZ L6 ; L2 초 PUSH 2 ; L3 아 / 분 SUB ; L4 터 JMP L1 ; L5 L6: POPNUM ; L6 망 HALT ; L7 희 테스트 코드 선형화 코드 5개의 명령어를 반복한다
  • 62. 알파희 5 - 루프 추적 최적화 [220a6f122e0a] {jit-log-noopt-loop # Loop 0 () : noopt with 55 ops … debug_merge_point(0, 0, '#2(s1)_BRZ_14') i17 = int_add(i4, -1) setfield_gc(p2, p6, descr=<FieldP aheui.Stack.inst_head 8>) i19 = int_sub(i12, 1) setfield_gc(p2, i19, descr=<FieldS aheui.Stack.inst_size 16>) i20 = int_is_zero(i7) guard_false(i20) i22 = int_le(0, i17) guard_value(i22, 1) debug_merge_point(0, 0, '#3(s1)_PUSH_2') i25 = int_add(i17, 1) p27 = new_with_vtable(4297581752) setfield_gc(p27, 2, descr=<FieldS aheui.Link.inst_value 16>) setfield_gc(p27, p6, descr=<FieldP aheui.Link.inst_next 8>) setfield_gc(p2, p27, descr=<FieldP aheui.Stack.inst_head 8>) i30 = int_add(i19, 1) setfield_gc(p2, i30, descr=<FieldS aheui.Stack.inst_size 16>) i32 = int_le(2, i25) guard_value(i32, 1) debug_merge_point(0, 0, '#4(s1)_SUB_-1') i35 = int_add(i25, -1) setfield_gc(p2, p6, descr=<FieldP aheui.Stack.inst_head 8>) i37 = int_sub(i30, 1) setfield_gc(p2, i37, descr=<FieldS aheui.Stack.inst_size 16>) i38 = getfield_gc(p6, descr=<FieldS aheui.Link.inst_value 16>) p39 = new(descr=<SizeDescr 24>) setfield_gc(p39, 2, descr=<FieldS tuple2.item0 8>) setfield_gc(p39, i38, descr=<FieldS tuple2.item1 16>) i40 = int_sub(i38, 2) setfield_gc(p6, i40, descr=<FieldS aheui.Link.inst_value 16>) i42 = int_le(0, i35) guard_value(i42, 1) debug_merge_point(0, 0, '#5(s1)_JMP_19') [225dee4ac3ea] {jit-log-opt-loop # Loop 0 ((jitdriver: get_printable_location disabled, no debug_print)) : loop w … debug_merge_point(0, 0, '#2(s1)_BRZ_14') +199: setfield_gc(p2, i8, descr=<FieldS aheui.Stack.inst_size 16>) +203: i13 = int_is_zero(i7) guard_false(i13, descr=<Guard0x100750230>) [i0, p2, p1, None, None] debug_merge_point(0, 0, '#3(s1)_PUSH_2') +213: setfield_gc(p2, i10, descr=<FieldS aheui.Stack.inst_size 16>) +217: i16 = int_le(2, i4) +229: guard_true(i16, descr=<Guard0x100750288>) [i4, i16, p2, p1, None, p6] debug_merge_point(0, 0, '#4(s1)_SUB_-1') +238: i18 = int_sub(i7, 2) debug_merge_point(0, 0, '#5(s1)_JMP_19') debug_merge_point(0, 0, '#1(s1)_DUP_-1') +242: setfield_gc(p2, i8, descr=<FieldS aheui.Stack.inst_size 16>) +246: setfield_gc(p6, i18, descr=<FieldS aheui.Link.inst_value 16>) +250: label(i0, p1, p2, i18, p6, descr=TargetToken(4302594152)) debug_merge_point(0, 0, '#1(s1)_DUP_-1') debug_merge_point(0, 0, '#2(s1)_BRZ_14') +256: i19 = int_is_zero(i18) guard_false(i19, descr=<Guard0x1007502e0>) [i0, p2, p1] debug_merge_point(0, 0, '#3(s1)_PUSH_2') debug_merge_point(0, 0, '#4(s1)_SUB_-1') +266: i20 = int_sub(i18, 2) debug_merge_point(0, 0, '#5(s1)_JMP_19')
  • 63. (기타 등등을 생략한) 결과 $ time AHEUI=../rpaheui/aheui-c ./test.sh logo/ real 0m1.795s user 0m1.087s sys 0m1.262s $ time AHEUI=../caheui/aheui ./test.sh logo/ real 0m23.953s user 0m23.843s sys 0m0.058s PyPy/RPython: 짧고 쉬운 코드로 빠른 인터프리터 완성!
  • 64. 생략된 내용 • 작업 로그: https://github.com/aheui/rpaheui/blob/ master/LOG.md
  • 65. 핵심 • PyPy 툴킷이 자동으로 붙여주는 JIT 컴파일러가 핫 루프를 찾아 내 가속합니다. • 정확하게 찾도록 도와줍시다. • 불필요하게 깐깐하면: 추적 비용이 증가 • 허술해서 guard가 틀리면: 최적화 비용 낭비 • 쉽게 찾도록 도와줍시다.
  • 66. RPython으로 뭐든 빠르게? • RPython을 쓰니 아희 인터프리터가 이만큼 빨라졌어요! • 그럼 내가 만드는 파이썬 프로그램이나 라이브러리 OOO도 RPython으로 짠다면!? • => 안됩니다. • http://rpython.readthedocs.org/en/latest/faq.html#do- i-have-to-rewrite-my-programs-in-rpython
  • 67. 의의 • 아희에 JIT 컴파일을 지원하는 인터프리터가 생겼다 • 아희아희를 실용적인 속도로 실행할 수 있는 인터프리터가 생겼다 • …??
  • 68. 의의 • 구전, 예제, PyPy 코드로만 전해지는 빈약한 문서에 예제 하나 • RPython의 버그 발견 및 수정! • 쓰는 사람들은 이미 RPython 사용에 익숙하고 • 프로그래밍 언어가 유니코드를 잔뜩 쓰는 경우가 드물어서
  • 69. 참조 • 아희의 표준과 헬로 월드
 - http://aheui.github.io/specification.ko/ • PyPy로 구현된 언어 - http://pypy.org/features.html • PyPy의 속도 - http://speed.pypy.org/ • HHVM의 속도 - http://hippyvm.com/#performance
  • 70. 도움 주신 분들 • Freenode/#pypy • arigato (Armin Rigo), fijal (Maciej Fijalkowski) • sanxiyn (서상현)
  • 71. 궁금한게 있나요? • irc://irc.ozinger.org/#aheui • https://twitter.com/youknowone_