Como o desempenho das operações de array Python / Numpy é escalado com o aumento das dimensões do array?

21

Como as matrizes Python / Numpy escalam com o aumento das dimensões da matriz?

Isso se baseia em algum comportamento que notei ao comparar o código Python para esta pergunta: Como expressar essa expressão complicada usando fatias numpy

O problema envolveu principalmente a indexação para preencher uma matriz. Descobri que as vantagens de usar as versões Cython e Numpy (não muito boas) em um loop Python variavam dependendo do tamanho das matrizes envolvidas. Tanto o Numpy quanto o Cython experimentam uma vantagem crescente de desempenho até certo ponto (algo em torno de para Cython e N = 2000 para Numpy no meu laptop), após o qual suas vantagens diminuíram (a função Cython permaneceu a mais rápida).N=500N=2000

Esse hardware está definido? Em termos de trabalho com matrizes grandes, quais são as práticas recomendadas que se deve aderir ao código em que o desempenho é apreciado?

Gráfico do tempo de execução relativo ao código em loop para implementações vetorizadas e Cython

Esta pergunta ( por que o meu Matrix-Vector Multiplication Scaling? ) Pode estar relacionada, mas estou interessado em saber mais sobre como as diferentes maneiras de tratar matrizes em Python escalam em relação uma à outra.

Nat Wilson
fonte
Você já tentou o numexpr ? Há também, por exemplo, essa conversa que aponta para blosc e CArray , todos destinados a acelerar ainda mais as coisas (e possivelmente ignorando as limitações de largura de banda da memória).
0 0
11
Você pode postar o código usado para criar um perfil. Provavelmente há algumas coisas acontecendo aqui.
meawoppl

Respostas:

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]

Há algumas coisas erradas nessa referência, para começar, não estou desativando a coleta de lixo e estou pegando a soma, não o melhor momento, mas tenha paciência comigo.

800064kB

Deveria se preocupar com o tamanho do cache? Como regra geral, eu digo não. Otimizá-lo em Python significa tornar o código muito mais complicado, para ganhos de desempenho duvidosos. Não esqueça que os objetos Python adicionam várias despesas gerais difíceis de rastrear e prever. Só consigo pensar em dois casos em que esse é um fator relevante:

  • Operações básicas em matrizes grandes (como avaliar um polinômio), limitadas pela largura de banda da memória. Use Numexpr ou (se os dados forem muito maiores) Pytables . Eles são otimizados para levar em consideração o tamanho do cache, entre outras otimizações.
  • Código crítico de desempenho: se você deseja espremer cada microssegundo, não deve usar o Python em primeiro lugar. Escrever Cython vetorizado e deixar o compilador fazer o que é melhor é provavelmente o caminho mais fácil.

Nos comentários, Evert mencionou o CArray. Observe que, mesmo trabalhando, o desenvolvimento parou e foi abandonado como um projeto independente. A funcionalidade será incluída no Blaze , um projeto em andamento para criar uma "nova geração Numpy".

Davidmh
fonte