Numpy와 비교하여 Cython 루프 최적화

토마스 알레
#cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, language_level=3
cpdef int query(double[::1] q, double[:,::1] data) nogil:
    cdef:
        int n = data.shape[0]
        int dim = data.shape[1]
        int best_i = -1
        double best_ip = -1
        double ip
    for i in range(n):
        ip = 0
        for j in range(dim):
            ip += q[j] * data[i, j]
        if ip > best_ip:
            best_i = i
            best_ip = ip
    return best_i

컴파일 후 Python에서 코드 시간을 측정합니다.

import numpy as np
import ip
n, dim = 10**6, 10**2
X = np.random.randn(n, dim)
q = np.random.randn(dim)
%timeit ip.query(q, X)

약 100ms가 걸립니다. 한편 동등한 것 numpy code:

%timeit np.argmax(q @ X.T)

약 50ms가 걸립니다.

이것은 NumPy코드가 q @ X.Targmax를 취하기 전에 큰 배열을 할당해야 하기 때문에 이상합니다. 따라서 내가 부족한 최적화가 있는지 궁금합니다.

extra_compile_args=["-O3", '-march=native'],내 setup.py에 추가 했으며 함수 정의를 다음과 같이 변경하려고 시도했습니다.

cpdef int query(np.ndarray[double] q, np.ndarray[double, ndim=2] data):

그러나 성능에는 거의 차이가 없었습니다.

ead

이 작업 q @ X.TdgemvOpenBlas 또는 MKL (분포에 따라 다름) 의 행렬-벡터 곱셈 ( ) 구현에 매핑됩니다. 즉, 가장 최적화 된 알고리즘 중 하나에 반대한다는 의미입니다.

결과 벡터에는 1M 요소가 있으므로 약 8MB 메모리가됩니다. 8MB는 항상 L3 캐시에 맞지는 않지만 RAM조차도 약 15GB / s의 대역폭을 가지고 있으므로 8MB 쓰기 / 읽기에는 최대 1-2ms가 소요되며 전체 실행 시간의 약 50ms에 비해 큰 이득이 아닙니다.

코드의 가장 큰 문제는 q @X.T. 그것은 계산

((q[0]*data[i,0]+q[1]*data[i,1])+q[2]*data[i,2])+...

IEEE 754 때문에 컴파일러는 연산을 재정렬 할 수 없으며 최적이 아닌 순서로 실행합니다. 두 번째 합계를 계산하려면 첫 번째 합계가 수행 될 때까지 연산을 기다려야합니다. 이 접근 방식은 현대 아키텍처의 모든 잠재력을 사용하지 않습니다.

좋은 dgemv구현은 훨씬 더 나은 작업 순서를 선택합니다. 비슷한 문제가 있지만 합계가이 SO-post 에서 찾을 수 있습니다 .

필드 -ffast-math를 평준화하기 위해 컴파일러가 작업을 다시 수행하여 파이프 라인을 더 잘 사용할 수 있도록을 사용할 수 있습니다.

벤치 마크에 대한 내 컴퓨터의 결과는 다음과 같습니다.

%timeit query(q, X)            # 101 ms
%timeit query_ffastmath(q, X)  # 56.3 ms
%timeit np.argmax(q @ X.T)     # 50.2 ms

여전히 약 10 % 정도 더 나쁘지만 컴파일러가 특히 내 프로세서를 위해 전문가가 만든 수작업 버전을 이길 수 있다면 정말 놀랄 것입니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

루프 및 비교 최적화

분류에서Dev

for 루프를 사용하지 않고 numpy로 파이썬 함수 최적화

분류에서Dev

numpy 기능을 사용하여 배열 반복을 파이썬 루프로 최적화 또는 대체

분류에서Dev

Cython을 사용하여 scipy.stats.t.sf와 GSL 비교

분류에서Dev

linq / lambda와 비교하여 double for 루프의 코드 성능

분류에서Dev

Swift를 사용하여 여행 이중 for 루프 최적화

분류에서Dev

numpy 행렬 연산 최적화 (현재 for 루프 사용)

분류에서Dev

루프를 제거하여 Python 코드 최적화

분류에서Dev

R에서 두 데이터 프레임을 비교하기위한 FOR 루프 최적화

분류에서Dev

C ++ : 루프 최적화 및 루프 해제 (루프 또는 루프하지 않음)

분류에서Dev

Cython 최적화가 느림

분류에서Dev

Python에서 여러 열 참조로 반복 루프 최적화

분류에서Dev

for 루프 처리를 최적화 하시겠습니까?

분류에서Dev

컴파일러가 주장하는 while 루프 최적화

분류에서Dev

for 루프를 최적화하는 방법은 무엇입니까?

분류에서Dev

중첩 된 for 루프로 함수를 최적화하는 방법

분류에서Dev

Cython은 numpy 배열 합계의 중요한 부분을 최적화합니다.

분류에서Dev

Pandas 루프 최적화

분류에서Dev

`while` 루프 최적화

분류에서Dev

C for 루프 최적화

분류에서Dev

Java ArrayList for 루프 최적화

분류에서Dev

이 최적화 문제에서 여러 for 루프를 피하는 방법

분류에서Dev

C 컴파일러는 루프를 실행하여 최적화합니다.

분류에서Dev

루프에 넣는 대신 단일 쿼리로 변경하여 최적화

분류에서Dev

루프 / 중첩 루프 최적화

분류에서Dev

클래스 메서드의 cython 최적화는 기능에 비해 음울함

분류에서Dev

numpy 배열에서 두 개의 For 루프를 사용하지 않고 시간 복잡성을 개선하는 방법은 구조를 최적화합니까?

분류에서Dev

while 루프의 문제와 루비 기계화

분류에서Dev

이 방법을 최적화하고 foreach 루프를 피하는 방법

Related 관련 기사

  1. 1

    루프 및 비교 최적화

  2. 2

    for 루프를 사용하지 않고 numpy로 파이썬 함수 최적화

  3. 3

    numpy 기능을 사용하여 배열 반복을 파이썬 루프로 최적화 또는 대체

  4. 4

    Cython을 사용하여 scipy.stats.t.sf와 GSL 비교

  5. 5

    linq / lambda와 비교하여 double for 루프의 코드 성능

  6. 6

    Swift를 사용하여 여행 이중 for 루프 최적화

  7. 7

    numpy 행렬 연산 최적화 (현재 for 루프 사용)

  8. 8

    루프를 제거하여 Python 코드 최적화

  9. 9

    R에서 두 데이터 프레임을 비교하기위한 FOR 루프 최적화

  10. 10

    C ++ : 루프 최적화 및 루프 해제 (루프 또는 루프하지 않음)

  11. 11

    Cython 최적화가 느림

  12. 12

    Python에서 여러 열 참조로 반복 루프 최적화

  13. 13

    for 루프 처리를 최적화 하시겠습니까?

  14. 14

    컴파일러가 주장하는 while 루프 최적화

  15. 15

    for 루프를 최적화하는 방법은 무엇입니까?

  16. 16

    중첩 된 for 루프로 함수를 최적화하는 방법

  17. 17

    Cython은 numpy 배열 합계의 중요한 부분을 최적화합니다.

  18. 18

    Pandas 루프 최적화

  19. 19

    `while` 루프 최적화

  20. 20

    C for 루프 최적화

  21. 21

    Java ArrayList for 루프 최적화

  22. 22

    이 최적화 문제에서 여러 for 루프를 피하는 방법

  23. 23

    C 컴파일러는 루프를 실행하여 최적화합니다.

  24. 24

    루프에 넣는 대신 단일 쿼리로 변경하여 최적화

  25. 25

    루프 / 중첩 루프 최적화

  26. 26

    클래스 메서드의 cython 최적화는 기능에 비해 음울함

  27. 27

    numpy 배열에서 두 개의 For 루프를 사용하지 않고 시간 복잡성을 개선하는 방법은 구조를 최적화합니까?

  28. 28

    while 루프의 문제와 루비 기계화

  29. 29

    이 방법을 최적화하고 foreach 루프를 피하는 방법

뜨겁다태그

보관