mathtoum a écrit 1 commentaire

  • # Amélioration du script

    Posté par  . En réponse au journal ISS : le flim. Évalué à 8. Dernière modification le 12 août 2012 à 16:12.

    Je viens de jeter un petit coup d’œil à ton script.
    Ta méthode de détection est simple, concise, efficace, l'idéal quoi. Le seul reproche que je pourrai faire est sur le manque de commentaire explicatifs : on est obligé de se taper tout ton code juste pour comprendre ce que tu cherches à faire.

    Pour ton petit problème de performance, je pense que ça peut venir de 2 choses :
    - une mauvaise utilisation du cache
    - un mauvais choix de la valeur initiale pour LIMIT

    • Utilisation du cache :

    Avec les processeurs actuels, récupérer des données depuis la RAM est bien plus long que les lire depuis le cache (d'un facteur 10 à 20). Dès qu'on travaille avec des données qui risquent de ne pas totalement tenir dans le cache, le meilleur moyen d'avoir de bonnes performances c'est de s'arranger pour utiliser au maximum les données qui y sont déjà présentes avant d'effectuer le prochain chargement depuis la RAM.

    Le cache d'un processeur est de l'ordre de 2 à 4Mo.
    Tes images font 21Mpx, soit environ 60Mo en mémoire.
    Tu peux voir le problème que ça peut poser.

    Ta boucle principale, c'est :

        for x in xrange(W):
            for y in xrange(H):
                acc = sum(data[x+(y*W)])
    
    

    Ça veut dire qu'à chaque itération tu te déplaces de W éléments en mémoire.
    Quand on veut parcourir tous les pixels, c'est relativement peu efficace, mais il y a pire : rien que pour accumuler suivant chaque colonne tu fais défiler pratiquement toute ton image en mémoire.
    Au final, comme toute l'image ne peut pas tenir en cache, tu fais la fais charger en entier autant de fois qu'il y a de colonnes. Je te laisse imaginer le nombre de rechargements du cache que tu provoques.

    Je pense que tu pourrais significativement améliorer les performances en échangeant les 2 boucles :

        for y in xrange(H):
            for x in xrange(W):
                acc = sum(data[x+(y*W)])
    
    

    De cette manière la boucle ne se déplace que d'un élément à chaque itération.
    Tous les éléments présents dans le cache sont utilisés avant d'avoir besoin de charger depuis la RAM, et l'image entière n'est chargée qu'une seule fois.

    • Valeur initiale LIMIT :

    J'ai vu que si la valeur de LIMIT est trop haute tu recommences tout avec une valeur plus basse. Potentiellement tu peux donc multiplier ton temps d'exécution par un facteur 2 voire 3.
    Est-ce que tu saurais si ça arrive souvent ? Si c'est le cas tu devrais pouvoir baisser voire carrément supprimer cette valeur sans que ça influe trop sur les résultats.