ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 고성능 파이썬 Chapter 07 - C 언어로 컴파일하기
    STUDY/고성능 파이썬 2024. 12. 22. 17:43

    들어가며

    파이썬을 처음 공부할때 파이썬의 장점으로 C언어와 궁합이 좋다는 얘기를 많이 들었던 것 같다. 특정 부분은 C언어로 구현하여 속도를 향상시키고, 다른 부분은 python으로 실행시켜 빠르게 작성하여 두 언어의 장점을 모두 사용할 수 있다는 점이었다.

     

    그러나 이후 직접 C언어로 파이썬 코드의 특정 부분을 작성해본 적이 없고, 어떻게 해야하는지도 잘 몰랐다. 이번 7장에서는 해당 부분에 대해서 다양한 접근 방식으로 c언어 코드를 이용하는 방법을 알려준다.

     


    이 장에서 배울 내용

    - 파이썬 코드를 저수준에서 동작하도록 만드는 방법

    - JIT 컴파일러와 AOT 컴파일러의 차이점

    - 순수 파이썬 코드보다 컴파일된 파이썬 코드가 좋은 이유

    - 타입 어노테이션이 파이썬 코드의 성능에 도움이 되는 이유

    - C나 포트란으로 파이썬 모듈을 작성하는 방법

    - C나 포트란으로 작성된 라이브러리를 파이썬에서 사용하는 방법


    기본적으로 python은 인터프리터 방식으로 코드를 실행시킨다. 이를 Cython, Numba, PyPy 같은 외부 모듈 등을 이용해서 JIT(Just In Time)컴파일러나 AOT(Ahead Of Time) 컴파일러를 이용하여 컴파일하면 기존보다 더욱 빠르게 코드를 수행할 수 있다.

    일반적으로 컴파일 할때 numpy를 포함하고 있으면 Numba, 파이썬 내장 라이브러리만 사용하면 PyPy(JIT)나 Cython(AOT)을 이용하면 된다.

     

    일반적으로 컴파일을 수행하여 빨라지는 부분은 수학적인 부분이다. 반면 외부 라이브러리나 I/O 바운딩 프로세스의 경우 속도 향상을 기대하기는 어렵다.

     

    JIT : 프로그램이 실행 된 후에 컴파일이 되고 수행이 됨. (cold start) 짧지만 자주 실행되는 스크립트에서는 사용하는것을 피하는게 좋음.

    AOT : 사용하기 전에 미리 컴파일하여 정적 라이브러리를 생성한다. 시작을 빠르게 할 수 있음.

     

    C언어는 정적 타입의 언어이고, Python은 동적 타입의 언어이므로(변수 선언시 type를 명시하지 않아도 됨) 기계어 수준에서의 최적화를 수행하기 어렵다. 따라서 타입을 명시해주면 컴파일시 최적화에 도움이 되어 속도 향상에 도움이 된다.

     

    Cython

    cython 예제 코드를 살펴보면 setup.py, 수행할 python 파일 (julia1.py), c언어로  컴파일할 함수를 정의한 코드(cythonfn.pyx) 가 있는것을 확인할 수 있다. setup.py를 이용하여 julia1.py에서 새로 생성할 모듈을 import 하도록 수정하면 된다.

    pyximport를 이용하면 단순화된 빌드를 수행할 수 있다.

     

    cython으로 빌드 시에 -a 옵션을 추가하면 어떻게 C언어로 컴파일이 되었는지 확인하는 HTML코드를 함께 생성해준다.

     

    OpenMP를 이용해서 병렬 프로그래밍을 수행하도록 하여 더욱 속도를 올릴 수 있다.

     

    Numby

    form numpy import jit을 하고, numpy로 작성된 함수에 @jit 데코레이터를 추가하여 numba로 컴파일 할 수 있다. 또한 prange를 이용하여 openMP 병렬화 지원을 추가할 수 있다. 예제

     

    PyPy

    Cpython과의 차이는 여기서 확인할 수 있다. pypy 명령어를 통해서 파이썬 스크립트를 수행하면 된다. 예제

     

    세 모듈의 성능을 비교한 표는 다음과 같다.

    <numpy 미사용> 속도(초)   <numpy와 수학 확장 사용> 속도(초)
    C파이썬 8.00   C파이썬 21.00
    Cython 0.49   Cython 0.18
    Cython + 수학 확장 0.19   Cython+OpenMP 0.05
    PyPy 0.90   Numba (두번째 이후 실행 결과) 0.17
    PyPy + 수학 확장 0.20   Numba+OpenMP 0.06

    --> 순수 파이썬 코드에서는 PyPY, numpy 코드에서는 Numba를 쓰는것이 좋음

     

      Cython Numba PyPy
    성숙함 O O O
    널리 사용 중 O - -
    numpy 지원 O O O
    기준 코드를 깨지 않음 - O O
    C언어 지식 필요 O - -
    OpenMP 지원 O O -

     


    Pytorch는 gpu를 이용하여 빠르게 코드 수행이 가능하도록 한다. 예제

    gpu 프로파일링은

    nvidia-smi 명령어의 GPU-Util, 전력 사용량을 확인하여 gpu가 얼마나 유휴상태로 보내지 않았는지, 계산을 얼마나 수행했는지 확인할 수 있다.

    gpustat 도구를 활용하여 확인할 수도 있다.

    python -m torch.utils.bottleneck 으로 코드를 실행하면 cpu와 gpu의 사용 시간 통계도 확인할 수 있다

    gpu를 이용할때는 메모리 양, 계산이 병렬적으로 수행되는지 등을 확인하고 쓰는것이 좋다.

     


    이외에 

    ctypes 예제

    cffi 예제

    f2py 예제

    Cpython 예제

    등을 이용해서 C, 포트란 등의 언어를 직접 이용하여 모듈을 작성할 수 있다.

    댓글

열심히 살자!