C언어로 컴파일하기
코드를 빠르게 하는 가장 쉬운 방법은 처리할 작업의 양을 줄이는 것이다. 작업의 양을 줄이는 방법은 최적의 알고리즘을 사용하고 수행할 명령의 수를 줄이는것이다.
이때 수행할 명령의 수를 줄이는 가장 쉬운 방법은 코드를 기계어로 컴파일 하는 것이다.
컴파일로 빨라지는 부분은 대체로 수학적인 부분이다.
같은 연산을 반보가는 코드를 포함할때 임시 객체를 많이 사용하기 때문이다.
수학 계산에 초점을 맞춘 코드라면 직접 작성한 포트란 루틴이 C로 작성한 루틴보다 더 빠를것이다.
하지만 이는 전문가적인 수준이고 보통 C코드만큼의 성능을 기대할수있다.
이렇게 컴파일을 할때 노력과 실행정도를 따져서 성능개선을 해야하는 부분도 있다.
컴파일 방식
AOT(사이썬) : 미리 컴파일
컴퓨터에 특화된 정적 라이브러리 생성
Numpy, scipy 같은 패키지를 내려받으면 컴퓨터에 맞게 컴파일 한다.
JIT(Numba, PyPy) : 적절한 때에 컴파일
콜드스타트 시작 but 직접적 노력 x
짧지만 자주 실행하는 스크립트에서는 사용하지 않는 편이 좋다.
타입 정보가 실행속도에 영향을 주는 이유
파이썬은 동적 타입 언어이기 때문에 가상머신에서 다음 연산에 사용할 데이터 타입을 알수 없다.
이에 기계어 수준의 최적화를 수행하기 어렵고, 이로인해 코드가 추상화 되어 실행속도가 느려진다.
파이썬 코드를 기계어로 번역하기 위해서는 많은 명령어가 관여하여야 하고,
이로인해 실행시간이 오래 걸린다. 만일 중간 계산 과정을 직접 수행하면 고수준이 함수가 불필요하고,
객체 참조 카운트 역시 필요없다. 직접 기계어 수준으로 내려가서 기계어오아 바이트를 사용해 계산하면,
큰 오버헤드를 초래하는 고수준의 파이썬 객체를 다루는 방식보다 훨씬 빠르게 계산 끝낼수 있다.
사이썬과 넘파이
파이썬에는 array 모듈이 있는데 이 모듈은 기본타입에 1차원 저장소를 제공한다.
넘파이의 numpy.array 모듈을 사용하면 다차원 배열과 다양한 기본타입(복소수 포함) 저장 가능하다.
array 객체를 미리 예측할수 있는 패턴으로 이터레이션 하면, 파이썬에서 다음주소를 요청해
받아오지 말고, 직접 다음 메모리 주소를 계산해 접근하도록 컴파일에게 지시할수 있다.
데이터가 연속된 블록에 놓여있으므로 오프셋을 사용해 C의 다음 항목 주소를 쉽게 계산하여,
파이썬에 주소를 물어볼 필요가 없다.(가상 머신을 역으로 호출해서 더 느리다)
Numba
numpy 에 특화된 JIT 컴파일러로, LLVM 컴파일러로 컴파일하다.
빠르고 편하게 성능 개선이 가능하며, 벡터화 하지 않은 코드가 있다면 빠르게 성능 개선 가능하다.
외부 C 라이브러리와 연동 불가능하지만 자동으로 GPU에 대한 코드를 생성해준다.
단점은 툴체인 으로써 LLVM 을 사용하므로 의존관계가 복잡하다. 모든게 준비된 아나콘다 추천
속도 향상 결과
각 기술의 사용 시점
동적 그래프 : 파이토치
파이토치는 정적 계산 그래프 텐서 라이브러리로 특히 Numpy 에 익숙한 사용자가 이용하기 쉬우며 API도 직관적이다.
또한 파이토치는 텐서 라이브러리 이므로 Numpy 와 같은 기능을 제공하며, 자체 정적 계산 그래프를 통해 함수 생성,
도함수를 autograd 메커니즘을 통해 계산해주는 기능으르 추가로 제공한다.
정적 계산 그래프는 파이토치 객체에 대한 연산을 수행하면 백그라운드에서
GPU 코드로 컴파일 될수있는 프로그램의 동적인 정의를 만들어낸다는 뜻이다.
동적이므로 파이썬 코드를 변경하면 자동으로 GPU 코드에 반영되며, 별도의 컴파일 단계가 필요하지 않다.
이 덕분에 텐서플로 같은 정적 그래프 라이브러리보다 디버깅이 쉽고 상호작용성이 늘었다.
'컴퓨터 공부 > 파이썬 공부' 카테고리의 다른 글
고성능 파이썬(6) (0) | 2021.07.05 |
---|---|
고성능 파이썬(5) (0) | 2021.07.04 |
고성능 파이썬(4) (0) | 2021.06.28 |
고성능 파이썬(3) (0) | 2021.06.27 |
고성능 파이썬(2) (0) | 2021.06.27 |