본문 바로가기

반응형

Computer

(114)
파이썬 코드 C언어로 컴파일하기 (1) 코드를 빠르게 하는 가장 쉬운 방법은 처리해야할 작업의 양, 데이터를 간소화하고 프로파일링을 통해 병목이 발생하는 구문을 최적화하는 것입니다. 특히, C 언어를 이용한 더 낮은 수준 (low level)으로 코드를 기계어로 컴파일하면 간단하게 큰 속도 향상을 얻을 수 있습니다. 특히, 같은 연산을 무수히 반복하는 루프를 포함하는 수학적인 코드에서는 임시 객체를 사용할 확률이 높기에 컴파일을 통해 큰 이득을 얻을 수 있습니다. 다만, 정규 표현식, 문자열 연산, 데이터베이스 등의 외부 라이브러리를 호출하는 코드는 속도 개선을 기대하기 어렵고 numpy 또한 벡터 연산을 집중해서 호출하고 임시 객체를 많이 생성하지 않아 컴파일이 별로 도움이 되지는 않습니다. (이미 C기반으로 최적화가 되어있기도 하고요) L..
행렬과 벡터 연산 (6) - numexpr 모듈 이용하기 행렬과 벡터 연산 (1) - 확산 방정식 예제 행렬과 벡터 연산 (2) - 확산 방정식 순수 파이썬 구현 행렬과 벡터 연산 (3) - 파이썬 리스트와 numpy 연산 속도 차이 행렬과 벡터 연산 (4) - numpy 배열을 이용한 확산 방정식 행렬과 벡터 연산 (5) - numpy 배열 메모리 최적화 지난 포스트를 거치면서 1) 메모리의 지역성, CPU 벡터 연산 활용을 지원하는 numpy 배열을 이용하고 2) 제자리 연산, numpy 함수 개량 등을 통해 확산 방정식의 속도를 크게 개선했습니다. 제자리 연산을 통해 메모리 재활용을 할 수 있어 캐시 미스를 줄일 수 있었지만 제자리 연산은 한 번에 하나의 연산에만 적용할 수 있는 단점이 있습니다. 예를 들어 A*B+C를 계산한다고 했을 때, 먼저 A*B ..
행렬과 벡터 연산 (5) - numpy 배열 메모리 최적화 행렬과 벡터 연산 (1) - 확산 방정식 예제 행렬과 벡터 연산 (2) - 확산 방정식 순수 파이썬 구현 행렬과 벡터 연산 (3) - 파이썬 리스트와 numpy 연산 속도 차이 행렬과 벡터 연산 (4) - numpy 배열을 이용한 확산 방정식 그렇다면 numpy 배열로 메모리 할당 횟수 (캐시 미스)를 줄인 이후에 메모리 할당 부분은 어떻게 최적화할 수 있을까요? 필요한 데이터를 캐시에서 찾지 못하면 메모리 할당은 단순히 메모리를 찾아보는 대시니 필요한 크기만큼의 데이터를 운영체제에 요청하게 됩니다. 캐시를 채우는 과정은 하드웨어적으로 최적화된 것에 반해 운영체제에 무언가를 요청할 때 발생하는 오버헤드는 (특히 메모리 할당) 커널과 통신해야 하므로 매우 큽니다. 제자리 연산 (in-place operat..
행렬과 벡터 연산 (4) - numpy 배열을 이용한 확산 방정식 행렬과 벡터 연산 (1) - 확산 방정식 예제 행렬과 벡터 연산 (2) - 확산 방정식 순수 파이썬 구현 행렬과 벡터 연산 (3) - 파이썬 리스트와 numpy 연산 속도 차이 지난 포스트에서 numpy 배열을 이용하면 메모리의 지역성과 CPU 벡터화 기능의 장점으로 행렬/벡터 연산에서 굉장한 성능 향상을 얻을 수 있음을 보았습니다. 그렇다면 지난 번에 파이썬 리스트로 구현했던 확산 방정식을 numpy 배열을 이용해 구현해 보겠습니다. 행렬과 벡터 연산 (2) - 확산 방정식 순수 파이썬 구현 [개발 잡학/Python] - 행렬과 벡터 연산 (1) - 확산 방정식 예제 지난 포스트의 의사 코드를 기반으로 순수 파이썬으로 (특히 리스트) 구현해 보겠습니다. 먼저 행렬을 받아 변화된 상태를 반환하는 e ho..
행렬과 벡터 연산 (3) - 파이썬 리스트와 numpy 연산 속도 차이 행렬과 벡터 연산 (1) - 확산 방정식 예제 행렬과 벡터 연산 (2) - 확산 방정식 순수 파이썬 구현 지난 포스트에서 확산 방정식을 파이썬 리스트로만 구현했습니다. 매 timestep 마다 확산을 모델링하기 위해서 grid 변수를 리스트의 리스트 형태로 구현했습니다. 하지만 파이썬의 리스트는 실제 데이터가 아닌 데이터가 저장된 위치를 가리키는 포인터를 저장합니다. 데이터 타입에 상관없이 리스트에 어떤 형태의 데이터도 저장할 수 있으나 이는 벡터, 행렬 연산에서 큰 성능 저하의 원인이 됩니다. 또한, 파이썬 바이트 코드는 벡터 연산에 최적화되지 않았기에 파이썬은 벡터 연산을 기본으로 제공하지 않습니다. Vectorization Numpy 연산이 매우 빠른 이유는 무엇일까요? 다음과 같이 50만개의 배열..
행렬과 벡터 연산 (2) - 확산 방정식 순수 파이썬 구현 행렬과 벡터 연산 (1) - 확산 방정식 예제 지난 포스트의 의사 코드를 기반으로 순수 파이썬으로 (특히 리스트) 구현해 보겠습니다. 먼저 행렬을 받아 변화된 상태를 반환하는 evolve 함수를 구현합니다. grid_shape = (640,640) def evolve(grid, dt, D=1.): xmax, ymax = grid_shape new_grid = [[0.,0.] * ymax for x in range(xmax)] for i in range(xmax): for j in range(ymax): grid_xx = grid[(i+1)%xmax][j] + grid[(i-1)%xmax][j] - 2. * grid[i][j] grid_yy = grid[i][(j+1)%ymax] + grid[i][(j-1..
행렬과 벡터 연산 (1) - 확산 방정식 예제 이번 시리즈 물에서는 순수 파이썬 구현과 numpy 구현의 속도 차이가 얼마만큼 나고 이러한 차이가 왜 발생하는지 알아보려 합니다. 순수 파이썬으로 문제를 구현한 이후 지난 포스트에서 살펴본 line profiler 를 이용해 연산 속도를 점진적으로 개선시킵니다. 이후 벡터 연산을 지원하는 numpy 배열을 이용해 구현하고 얼마만큼의 속도 개선을 이룰 수 있는지 보려고 합니다. 이를 살펴보기 위한 예제로는 메모리와 연산량을 매우 많이 잡아먹는 적절한 예제가 필요하겠죠. 바로 확산 방정식입니다. 확산 방정식 확산은 유체가 공간에서 퍼지는 양상을 나타낸 수식입니다. 예를 들어 실온의 물에 물감을 몇 방울 떨어뜨리면 물감이 천천히 퍼지면서 물과 완전히 섞일 때까지 움직이는데, 물을 젓는 등의 외부 유인이 없다..
제너레이터와 yield (3) - 지연 계산 제너레이터와 yield (1) 제너레이터와 yield (2) - 피보나치, 무한급수 현재값만 필요한 경우에 제너레이터가 속도/메모리 사용 측면에서 유리하나 제너레이터를 사용하게 되면 수열의 다른 값을 참조할 수 없기에 (현재값만 사용하여 처리하는 알고리즘을 단일 패스 (single pass) 혹은 온라인 (online) 이라 합니다) 사용하기 까다로울 수 있습니다. 이때 활용할 수 있는 모듈이 바로 itertools 입니다. itertools 모듈 이번 포스트에서는 파이썬의 itertools 내장 모듈에 대해 알아보려고 합니다. itertools는 효율적인 반복을 위한 반복기 빌딩 블록을 generator를 이용한 iterator 형태로 구성하여 빠르고 효율적으로 메 hongl.tistory.com 대용..

반응형