IBM developerWorks.
Charming Python : Psyco로 파이썬을 C 만큼 빠르게!
Psyco (파이썬 컴파일러) |
난이도 : 초급 2002 년 10 월 01 일 어떤 면에서 파이썬 디자인은 자바 디자인과 닮았다. 두 개 모두 가상으로 컴파일된 바이트코드를 인터프리팅하는 가상 머신을 사용한다. JVM이 파이썬보다 나은 것은 바이트코드의 실행을 최적화하는데 있다. 파이썬 컴파일러인 Psyco이 이러한 차이를 줄이는데 도움이 될 것이다. 현재 Psyco는 외부 모듈이지만 언젠가는 파이썬에 포함 될 것이다. 파이썬은 웬만큼 빠르다. 파이썬 같은 인터프리팅/바이트-컴파일 언어의 실행 속도에 대해 미숙한 프로그래머가 표현하는 걱정의 90%는 순진하다. 요즘의 하드웨어에서 대부분의 최적화 되지 않은 파이썬 프로그램들은 충분히 빠르게 실행된다. 애플리케이션을 빠르게 만들고자 하는 가외의 프로그래밍 노력을 할 필요가 없다. 파이썬 프로그램의 속도를 높일 수 있는 많은 방법이 있다. 대부분의 개발자의 머리속에 떠오르는 그 첫 번째 기술은 알고리즘과 데이터 구조를 향상시키는 것이다. 비효율적인 알고리즘의 단계들을 최적화하는 것은 헛된일이다. 어셈블리에서 재작성하는 것도 마찬가지이다. 가장 먼저 고려해야할 두 번째 기술은 파이썬 애플리케이션을 프로파일링 하는 것이다. SWIG 같은 확장 래퍼를 사용하여 C 코드처럼 프로그램의 엘리먼트를 실행하는 C 확장을 만들 수 있다. 이런 방식을 사용하여 파이썬을 확장하는것은 비교적 간단하다. 하지만 배우는데는 시간이 걸린다. 세 번째 기술은 두 번째 기술을 기반으로 한다. Greg Ewing은 Pyrex라고 하는 언어를 만들었는데 이것은 파이썬과 C를 혼합한 것이다. 특히 Pyrex를 사용하기 위해서는 선택된 변수에 유형(type) 선언을 추가하는 파이썬 계열의 언어에 함수를 작성한다. Pyrex(툴)은 ".pyx" 파일을 ".c" 확장으로 처리한다. C 컴파일러로 컴파일되면 이 Pyrex(언어) 모듈은 파이썬 애플리케이션에 반입되어 사용될 수 있다. Pyrex가 파이썬과 같은 신택스를 사용하기 때문에 Pyrex 프로그래머는 확장을 작성하기위해 C를 배울 필요가 없다. 더욱이 Pyrex는 C 레벨 변수와 파이썬 레벨 변수를 같은 코드 내에서 완벽하게 혼합한다. 마지막 기술이 바로 이 글의 주제이다. 확장 모듈인 Psyco는 파이썬 인터프리터의 중심에 플러그인 될 수 있다. 그리고 파이썬의 인터프리팅 된 바이트코드 부분들을 최적화된 머신 코드로 대체한다. 위에 열거한 다른 기술들과는 다르게 Psyco는 파이썬 런타임을 철저하게 지켜 작동한다. 다시말해서 파이썬 소스 코드는
Psyco를 완전히 이해하려면 파이썬 인터프리터의 정식 파이썬에서 Psyco는
이 코드의 최적화 코드는 "x 변수/객체의 콘텐트"에 의해 각 작은 오퍼레이션을 위해 i386 스팩의 코드를 만드는 것 외에도 Psyco는 나중에 다시 사용할 목적으로 이 컴파일된 머신을 보관한다. Psyco가 특정 작동이 이전에 일어난 것과 같다는 것을 인식할 수 있다면 캐시된 코드에 의존할 수 있다. Psyco의 진짜 장점은 오퍼리이션의 카테고리를 세 가지 다른 레벨로 한다. Psyco에는 "런타임(run-time)", "컴파일 타임(compile-time)","가상 타임(virtual-time)" 변수들이 있다. Psyco는 필요할 때 레벨 간 변수를 승격/강등 시킨다. 런타임 변수는 미가공 바이트코드이고 정식 파이썬 인터프리터가 핸들하는 객체 구조이다. 컴파일 타임 변수는 머신 레지스터에 나타나고 메모리 로케이션에 직접 접근된다. 가장 재미있는 것은 가상 타임 변수이다. 내부적으로 파이썬 변수는 많은 멤버를 갖고있는 완벽한 구조이다. Psyco 가상 타임 변수는 필요할 때 구현될 수 있는 파이썬 객체들을 말한다 : x = 15 * (14 + (13 - (12 / 11))) 표준 파이썬은 이 값을 계산하기 위해 많은 객체들을 구현하고 파괴한다. 전체 정수 객체는
Psyco를 설명하기는 비교적 어렵지만 사용하는 것은 훨씬 쉽다. 파이썬 함수와 클래스에 어떤 코드 변화도 필요없다. Psyco가 해야할 일을 지정하는 두 가지 방법이 있다. 강제적 방법은 Psyco가 어디서나 "just-in-time" 작동하도록 하는 것이다. 이를 위해 다음의 라인들을 모듈의 상단에 놓아야한다:
첫 번째 라인은 Psyco가 모든 글로벌 함수에서 이 마법을 수행했음을 보여주고 있다. 두 번째 라인은 Psyco가 클래스 메소드와 같은 것을 수행했음을 보여주고 있다. Psyco의 작동을 좀더 자세히하려면 다음의 명령어를 사용한다:
두 번째 형식은
Psyco가 마법같은 것 처럼 이를 사용하는데에도 약간의 생각과 테스트가 필요하다. 이해해야 할 점은 Psyco가 여러번 루핑하는 블록들을 핸들링하는데 유용하다는 것이다. 그리고 Psyco는 정수와 부동소수점 숫자를 포함하는 작동을 최적화하는 방법을 알고있다. 비 루핑 함수와 다른 유형의 객체에서 작동하는 경우, Psyco는 분석과 내부 컴파일을 위해 오버헤드를 추가한다. 게다가 많은 함수와 클래스를 갖고있는 애플리케이션의 경우, Psyco 애플리케이션을 실행하는데에는 머신 코드 컴파일과 캐싱용 메모리 사용에 많은 노력이 들어간다. 그러한 함수들을 선택적으로 바인딩하는것이 Psyco 최적화에 도움이 된다. 매우 단순한 방식으로 테스트를 시작하겠다. 최근에 사용하는 것 중 속도 향상을 고려하지 않고 있는 애플리케이션을 선택했다. 첫 번째 예제는 텍스트 조작 프로그램이다. 앞으로 출간될 내 책을 LaTex 포맷으로 변환하는데 사용하는 것이다. 이 애플리케이션은 스트링 메소드, 정규식, 정규식과 스트링 매치로 운영되는 프로그램 로직을 사용한다. Psyco 테스트에는 끔찍한 후보 이지만 그래도 시작해보겠다. 우선 두 번째는 텍스트 프로세싱 후보이다. 좀더 신빙성있는 Psyco 테스트를 위해 neural network 코드를 선택했다. 이 "code_recognizer" 애플리케이션은 다른 프로그래밍 언어의 다양한 ASCII 값의 배포판을 인식하도록 훈련시킬 수 있다. 이는 파일 유형을 알아내는데 유용하다. 하지만 지극히 일반적이다. 이것은 얼굴, 소리, 주기적 패턴을 매우 쉽게 습득한다. "code_recognizer"는 파이썬 라이브러리인 이것 저것 테스트 한 후에 Psyco를 사용하는 방법에 대해 자세히 알게 되었다. 아주 적은 클래스와 함수를 갖고있는 이 애플리케이션의 경우 just-in-time을 사용하든 바인딩을 사용하든 큰 차이가 없다. 최상의 결과는 최적화할 수 있는 클래스를 선택적으로 바인딩할 때 이다. 하지만 Psyco 바인딩의 범위를 이해해야 한다.
bpnn 에서 NN 반입하기
Psyco의 관점에서 볼 때 재미있는 현상은 적절한 Psyco 바인딩의 세부사항이 만들어지면 결과 스피드업은 주목할 만하다. 반복을 10번으로 줄이면 그에 비례한 스피드업도 생긴다. 새 코드의 두 라인을 가지고 실행속도를 30분에서 10분으로 줄인것은 의미가 크다. 이러한 속도향상은 C의 비슷한 애플리케이션의 속도보다 빠르다.
Psyco는 지금 현재 내부 통계나 프로파일링을 수행하지 않으며 단지 생성된 머신 코드의 최소한의 최적화만 수행한다. 다음 버전에서는 그 효과를 극대화하는 것을 목표로 만들어 질 것이다. 앞으로의 Psyco는 최적화 범위를 확대시킬 것이다.
필자 의견 : |
'IBM CampusWizard > developerWorks' 카테고리의 다른 글
[IBM dW]Charming Python: 파이썬 참고서적 리뷰, Part 2 (0) | 2008.05.12 |
---|