Partage
  • Partager sur Facebook
  • Partager sur Twitter

asyncio et parallelisation

Sujet résolu
    26 décembre 2021 à 21:36:04

    Bonjour, à tous, J'aimerais paralléliser hautement mon programme avec asyncio. Actuellement j'utilise du multiprocessing, ce qui me d'avoir une parallélisation de mon programme x12 (nb cœurs logiques de ma machines ). J'aimerais pouvoir le paralléliser plus que ça et donc je me suis penché sur asyncio. J’utilise donc asyncio.gather afin de lancer des coroutines en parallèles. Voici le code et sa sortie :

    import asyncio
    import time
    
    
    class Market:
    
        def __init__(self, value, ID):
            self.value = value
            self.ID = ID
            self.LOOP = 10000000
    
        async def run_my_loop_function(self):
            print(f'start : {self.ID}')
            await self.add_value()
            print(f'end : {self.ID}')
    
        async def add_value(self):
            await asyncio.sleep(0)
            for i in range(self.LOOP):
                self.value += 1
    
    
    async def run_markets():
        list_market = []
        print(f'##### ASYNC ####\n')
        T0 = time.time()
        for i in range(5):
            list_market.append(Market(i, i).run_my_loop_function())
    
        await run_parallel(*list_market)
        T1 = time.time()
    
        list_market = []
    
        print(f'\n##### SYNCRO ####\n')
        T2 = time.time()
    
        for i in range(5):
            list_market.append(Market(i, i).run_my_loop_function())
    
        await run_sequences(*list_market)
    
        T3 = time.time()
    
        print(f'async time : {T1 - T0}\n')
        print(f'sync time : {T3 - T2}\n')
    
    
    async def run_sequences(*functions):
        for function in functions:
            await function
    
    
    async def run_parallel(*functions) -> None:
        await asyncio.gather(*functions)
    
    
    if __name__ == '__main__':
        asyncio.run(run_markets())
    

    Sortie : 

    ##### ASYNC ####

    start : 0

    start : 1

    start : 2

    start : 3

    start : 4

    end : 0

    end : 1

    end : 2

    end : 3

    end : 4

    ##### SYNCRO ####

    start : 0

    end : 0

    start : 1

    end : 1

    start : 2

    end : 2

    start : 3

    end : 3

    start : 4

    end : 4

    async time : 3.8460402488708496

    sync time : 3.7708089351654053

    J’effectue un comparatif du temps d’exécution par rapport à un run en séquentiel. Comme le montre la sortie, le temps d’exécution parallèle/séquentiel est le même. Le programme à l’air d’exécuter les taches de manière concurrentes mais pas de manière parallèle. Je me demande donc s’il est réellement possible d’exécuter du code en parallèle avec asyncio ? Ou alors, sommes-nous limiter aux cœurs logiques de notre machine?


    • Partager sur Facebook
    • Partager sur Twitter
      26 décembre 2021 à 22:54:52

      EmileGuimard1 a écrit:

      Le programme à l’air d’exécuter les taches de manière concurrentes mais pas de manière parallèle. Je me demande donc s’il est réellement possible d’exécuter du code en parallèle avec asyncio ?

      asyncio n'est pas fait pour utiliser la capacité de plusieurs processeurs. Voir le tuto Python sur le sujet.

      • Partager sur Facebook
      • Partager sur Twitter
        27 décembre 2021 à 0:04:13

        Je pense que je me suis mal exprimé, et je m'y connais surement mal en informatique pur. Admettons que je n'ai qu'un seul processeur et 5 tâches indépendantes à exécuter.  J'aimerais exécuter mon programme de manière concurrente, afin d'exécuter plus rapidement mon programme. Cela est -t-il possible avec asyncio ? (ou bien avec du multithreading ?)
        • Partager sur Facebook
        • Partager sur Twitter
          27 décembre 2021 à 3:04:48

          Quand tu dis que tu n'as qu'un processeur, veux-tu dire qu'il n'a qu'un seul coeur?
          J'ai un processeur 4 coeurs roulant à 4 GHZ.
          Crois-tu que je pourais exécuter l'équivalent de 16 GHZ?
          On ne peut pas aller plus vite que le processeur.
          Les specs de mon ordi disent que le processeur fait du "multti-threading", et qu'il a 8 threads.
          Ça veut dire qu'il passe d'un coeur à l'autre à tous les demi-cycles.
          En mode turbo, les cycles sont ramenés sur le même coeur et les autres ne font presque rien.

          J'ai récupéré ceci d'un autre topic:

          https://docs.python.org/3/library/multiprocessing.html

          -
          Edité par PierrotLeFou 27 décembre 2021 à 3:09:46

          • Partager sur Facebook
          • Partager sur Twitter

          Le Tout est souvent plus grand que la somme de ses parties.

            27 décembre 2021 à 9:33:56

            EmileGuimard1 a écrit:

            Admettons que je n'ai qu'un seul processeur et 5 tâches indépendantes à exécuter.  J'aimerais exécuter mon programme de manière concurrente, afin d'exécuter plus rapidement mon programme. Cela est -t-il possible avec asyncio ? (ou bien avec du multithreading ?)

            Avec le Python actuel, plus rapide en consommant la capacité de plusieurs processerrs ne peut se faire qu'avec multiprocessing.

            S'il n'y a qu'un seul processeur, asyncio (et les threads) ne permettront d'avoir qu'une seule tache "active" (qui consomme du processeur) les autres étant en attente de la disponibilité du processeur, de la fin d'une entrée sortie ou d'un délai.

            Si on en a plusieurs, asyncio n'apporte rien: tout s'exécute dans un thread et un thread sera la tache executée par un des processeurs à l'instant T.

            Plusieurs threads pourraient permettre d'utiliser les capacités de plusieurs processeurs, mais le Python actuel ne le permet pas (ça ne consommera que la capacité d'un seul processeur).

            -
            Edité par mps 27 décembre 2021 à 9:34:32

            • Partager sur Facebook
            • Partager sur Twitter
              27 décembre 2021 à 15:03:53

              PierrotLeFou a écrit:

              Quand tu dis que tu n'as qu'un processeur, veux tu dire qu'il n'a qu'un seul cœur?

              Oui je voulais dire un seul cœur logique. C'était juste pour illustrer mon exemple. Mais mps m'a donné la réponse : 

              S'il n'y a qu'un seul processeur, asyncio (et les threads) ne permettront d'avoir qu'une seule tache "active". 

              Pour mon problème actuel je suis donc limité par python,  Ducoup je pense que je vais écrire quelque partie de mon programme dans un autre langage plus rapide et qui donne un meilleur accès à la gestion de mémoire. 

              Merci à vous deux pour votre aide, passez une bonne journée ! 

              • Partager sur Facebook
              • Partager sur Twitter

              asyncio et parallelisation

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              • Editeur
              • Markdown