Question

j'ai un numpy script qui passe environ 50 % de son temps d'exécution dans le code suivant :

s = numpy.dot(v1, v1)

v1 = v[1:]

et v est un 1D de 4000 éléments ndarray de float64 stocké dans la mémoire contiguë (v.strides est (8,)).

Des suggestions pour accélérer cela ?

modifier C'est sur le matériel Intel.Voici le résultat de mon numpy.show_config():

atlas_threads_info:
    libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/local/atlas-3.9.16/lib']
    language = f77
    include_dirs = ['/usr/local/atlas-3.9.16/include']

blas_opt_info:
    libraries = ['ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/local/atlas-3.9.16/lib']
    define_macros = [('ATLAS_INFO', '"\\"3.9.16\\""')]
    language = c
    include_dirs = ['/usr/local/atlas-3.9.16/include']

atlas_blas_threads_info:
    libraries = ['ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/local/atlas-3.9.16/lib']
    language = c
    include_dirs = ['/usr/local/atlas-3.9.16/include']

lapack_opt_info:
    libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/local/atlas-3.9.16/lib']
    define_macros = [('ATLAS_INFO', '"\\"3.9.16\\""')]
    language = f77
    include_dirs = ['/usr/local/atlas-3.9.16/include']

lapack_mkl_info:
  NOT AVAILABLE

blas_mkl_info:
  NOT AVAILABLE

mkl_info:
  NOT AVAILABLE
Était-ce utile?

La solution

Vos tableaux ne sont pas très grands, donc ATLAS ne fait probablement pas grand-chose.Quels sont vos horaires pour le programme Fortran suivant ?En supposant qu'ATLAS ne fait pas grand-chose, cela devrait vous donner une idée de la vitesse à laquelle dot() pourrait être s'il n'y avait pas de surcharge python.Avec gfortran -O3 j'obtiens des vitesses de 5 +/- 0,5 us.

    program test

    real*8 :: x(4000), start, finish, s
    integer :: i, j
    integer,parameter :: jmax = 100000

    x(:) = 4.65
    s = 0.
    call cpu_time(start)
    do j=1,jmax
        s = s + dot_product(x, x)
    enddo
    call cpu_time(finish)
    print *, (finish-start)/jmax * 1.e6, s

    end program test

Autres conseils

Peut-être que le coupable copie les tableaux transmis à point.

Comme l'a dit Sven, le point le produit repose sur les opérations BLAS.Ces opérations nécessitent des tableaux stockés dans un ordre C contigu.Si les deux tableaux sont passés à point êtes en C_CONTIGUOUS, vous devriez voir de meilleures performances.

Bien sûr, si vos deux tableaux passés au point sont effectivement 1D (8,), alors vous devriez voir les deux les indicateurs C_CONTIGUOUS ET F_CONTIGUOUS définis sur True ;mais s'ils le sont (1, 8), alors vous pouvez voir un ordre mixte.

>>> w = NP.random.randint(0, 10, 100).reshape(100, 1)
>>> w.flags
   C_CONTIGUOUS : True
   F_CONTIGUOUS : False
   OWNDATA : False
   WRITEABLE : True
   ALIGNED : True
   UPDATEIFCOPY : False


Une alternative:utilisez _GEMM de BLAS, qui est exposé via le module, scipy.linalg.fblas.(Les deux tableaux, A et B, sont évidemment dans l'ordre Fortran car fblas est utilisé.)

from scipy.linalg import fblas as FB
X = FB.dgemm(alpha=1., a=A, b=B, trans_b=True)

La seule chose à laquelle je peux penser pour accélérer cela est de m'assurer que votre installation NumPy est compilée avec une bibliothèque BLAS optimisée (comme ATLAS). numpy.dot() est l'une des rares fonctions NumPy à utiliser BLAS.

numpy.dot utilisera le multithreading s'il est compilé correctement.Assurez-vous que c'est le cas avec le dessus.Je connais des cas où les gens n'ont pas fait fonctionner le multithreading dans numpy avec atlas.De plus, cela vaut la peine d'essayer d'utiliser une version numpy compilée avec les bibliothèques Intel mkl.Ils incluent des routines blas qui sont censées être plus rapides qu'Atlas sur le matériel Intel.Vous pouvez essayer la distribution Python d'Enthought.Contient tout cela et est gratuit pour les personnes disposant d’un compte de messagerie edu.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top