¿Cómo se escala el rendimiento de las operaciones de matriz Python / Numpy con el aumento de las dimensiones de la matriz?

21

¿Cómo se escalan las matrices Python / Numpy con el aumento de las dimensiones de la matriz?

Esto se basa en un comportamiento que noté al comparar el código Python para esta pregunta: cómo expresar esta expresión complicada usando cortes numpy

El problema consistía principalmente en la indexación para llenar una matriz. Descubrí que las ventajas de usar versiones de Cython y Numpy (no muy buenas) sobre un bucle de Python variaban según el tamaño de las matrices involucradas. Tanto Numpy como Cython experimentan una ventaja de rendimiento creciente hasta cierto punto (en algún lugar, en general, alrededor de para Cython y para Numpy en mi computadora portátil), después de lo cual sus ventajas disminuyeron (la función Cython siguió siendo la más rápida).N = 2000N=500N=2000

¿Está definido este hardware? En términos de trabajar con matrices grandes, ¿cuáles son las mejores prácticas a las que se debe adherir para el código donde se aprecia el rendimiento?

Trazado de tiempo de ejecución relativo al código en bucle para implementaciones vectorizadas y de Cython

Esta pregunta ( ¿Por qué no está mi Escala de multiplicación de matriz-vector? ) Puede estar relacionada, pero estoy interesado en saber más acerca de cómo las diferentes formas de tratar las matrices en la escala de Python se relacionan entre sí.

Nat Wilson
fuente
¿Has probado numexpr ? También hay, por ejemplo, esta charla que apunta a blosc y CArray , todo destinado a acelerar las cosas aún más (y posiblemente pasando por alto las limitaciones de ancho de banda de memoria).
0 0
1
¿Puedes publicar el código utilizado para el perfil? Probablemente hay algunas cosas pasando aquí.
meawoppl

Respuestas:

5

416kB

def timeit(size):
     t0 = time.time()
     for _ in xrange(10):
         np.random.random(size)
     return time.time() - t0

sizes = np.logspace(1, 6, 40)
times = [timeit(s) for s in sizes]

Hay algunas cosas que están mal con este punto de referencia, para empezar, no estoy desactivando la recolección de basura y estoy tomando la suma, no es el mejor momento, pero tengan paciencia conmigo.

800064kB

¿Debería preocuparse por el tamaño del caché? Como regla general, digo que no. Optimizarlo en Python significa hacer que el código sea mucho más complicado, para obtener dudosas ganancias de rendimiento. No olvide que los objetos de Python agregan varios gastos generales que son difíciles de rastrear y predecir. Solo puedo pensar en dos casos en los que este es un factor relevante:

  • Operaciones básicas en matrices grandes (como evaluar un polinomio), limitadas por el ancho de banda de la memoria. Use Numexpr o (si los datos son mucho más grandes) Pytables . Están optimizados para tener en cuenta el tamaño de la memoria caché, entre otras optimizaciones.
  • Código crítico de rendimiento: si desea exprimir cada microsegundo, no debe usar Python en primer lugar. Escribir Cython vectorizado y dejar que el compilador haga lo que mejor sabe hacer es probablemente la forma más sencilla de hacerlo.

En los comentarios, Evert mencionó CArray. Tenga en cuenta que, incluso trabajando, el desarrollo se ha detenido y se ha abandonado como un proyecto independiente. La funcionalidad se incluirá en Blaze , un proyecto en curso para hacer una "nueva generación Numpy".

Davidmh
fuente