Comment faire du vrai parallèlisme
Posté : jeu. 06 avr. 2023 17:21
Autoit n'a pas été conçu pour le parallélisme.
Mais il est possible de programmer l'exécution de processus parallèles en AutoIt.
Pour ce faire, le logiciel en AutoIt doit être spécifiquement programmé en deux parties :
- Principal : initialisation, lancement des processus parallèles, attente des fins d'exécution, consolidation des résultats
- Proc : processus à exécuter en instances indépendantes lancées en parallèle
Il s'agit bien ici de programmer en AutoIt des lancements de processus qui vont s'exécuter en parallèle indépendamment les uns des autres en tant qu'acteurs d'un même projet, et d'en récupérer les résultats pour consolidation.
Comment c'est possible et avec quelle conception adaptée
1/ L'instruction Run d'AutoIt peut lancer un processus sur un cpu thread donné, directement via la commmande start de Windows avec un paramètre /Affinity ou via un utilitaire pour la même fonction.
Evidemment, en vue d'une exécution en plusieurs instances parallèles indépendantes, le processus ainsi lancé doit être dans sa forme compilée en exe files.
Exemples
En répétant l'instruction avec differents "affinity masks" dans $Mask correspondant chacun à un cpuid, on lance autant de proc.exe en instances parallèles.
Autre méthode en utilisant un utilitaire de lancement qui accepte directement un cpuid en paramètre :
2/ Chaque instance de processus lancé en parallèle doit évidemment être munie de paramètres spécifiques d'exécution, a minima son cpuid, soit via des paramètres de lancement dans l'instruction Run (récupérés en $CmdLine à l'intérieur de chaque instance) ou via quelques instructions envset avant l'instruction Run, dont les paramètres sont récupérés à l'intérieur de chaque instance par des déclarations envget de globals.
3/ En fin d'exécution, chaque instance de processus lancé en parallèle écrit ses résultats dans un fichier spécifique (par exemple sous un nom de fichier comportant le cpuid d'exécution).
4/ Après avoir lancé les processus parallèles, le logiciel principal attend la création des fichiers résultats pour consolidation.
Preuve expérimentale
Deux scripts AutoIt sont joints : Divisoptkim.au3 (Principal) and loopkim.au3 (Proc).
Leur but : trouver les diviseurs entiers d'un nombre entier.
Le script loopkim.au3 doit être compilé par le compilateur AutoIt sur votre machine.
Dans un même répertoire, installez Divisoptkim.au3 et loopkim.exe (plus l'utilitaire StartAffinity.exe seulement si vous utilisez Windows XP - voir in fine le lien pour le télécharger).
Lancez Divisoptkim.au3
(la compilation du script principal n'est pas nécessaire si l'extension au3 est associée à AutoIt sur votre machine).
Les processus loopkim vont s'exécuter en plusieurs instances indépendantes dès que vous aurez saisi un entier suffisamment grand pour justifier le parallélisme.
Quelques suggestions : 5040, 66049, 13 444 333 222 110, 133 444 333 222 110, 333 333 333 333 333.
N'hésitez pas devant les grands nombres, ils occuperont environ 10-15 seconds sur un dualcore, autrement le temps d'exécution sera pratiquement invisible.
Or, ce qui est intéressant, c'est justement de voir la charge de chaque cpu sur le Windows Task Manager (onglet Performances et Resources Monitor pour les versions Windows récentes).
Noter que le logiciel adapte le niveau de parallélisme en fonction de N. Concrètement, si N est relativement petit vis à vis du nombre de cpus disponibles, il réduit le nombre d'instances parallèles pour que chacune soit chargée raisonnablement (c'est-à-dire pour qu'elle s'exécute sur un segment minimum de 100 nombres candidats).
A la fin des processus parallèles, autant de fichiers Journal_x.txt sont créés que d'instances parallèles de loopkim.exe, (avec x = cpuid à partir de 0).
Une exécution du principal avec des paramètres standard (ceux qui sont définis en appuyant sur Return) allouera tous les cpus de la machine avec potentiellement une charge de 100% sur les cpus alloués. Vous pouvez évidemment déclarer un nombre de cpus plus faible que le nombre disponible sur votre machine, cela pourra vous faciliter l'observation de la charge générée via le Task Manager sur chaque cpu.
Si vous choisissez la deuxième méthode d'allocation, seulement les cpus pairs pourront être alloués, et la charge maximale ne pourra donc dépasser 50 %.
Avertissement. Ce logiciel a été testé sur plusieurs versions de Windows, de XP Home 32bit à Windows 11 64bit et sur diverses machines, du bicoeur simple au processeur à 20 threads. D'autres environments peuvent nécessiter des modifications du logiciel.
Pour XP spécialement.
Un utilitaire de lancement est indispensable car on ne peut pas utiliser la commande start, démunie sous XP du paramètre affinity.
Il existe au moins deux utilitaires disponibles.
StartAffinity http://www.adsciengineering.com/StartAffinity/.
Un autre utilitaire se trouve dans les "Heise software archiv" : chercher "launch".
Ces deux utilitaires fonctionnent par ailleurs très bien aussi sur les versions récentes de Windows.
Note. Divisoptkimv2 contient une instruction de rejet des entiers de longueur supérieure à 15 chiffres. C'est pour préserver la justesse des calculs internes. AutoIt gère automatiquement la conversion interne des représentations des entiers de 32 à 64 bits, mais aussi vers le format en virgule flottante, qui est incompatible avec les calculs tels qu'ils sont programmés dans mon logiciel de démo. Pour les très grands nombres, il faudrait utiliser la bibli BigNum, ce qui obligerait à reprogrammer tous les calculs... 05 mai 2023 : finalement, je renonce, mes procédures de division et modulo écrites à la main sont meilleures que les procédures plus génériques de la lib Bib Num...
La conclusion est qu'en cherchant à étendre un langage au-delà des limites de sa conception d'origine, on ne peut qu'engendrer un monstre. Mon petit logiciel de démo est scandaleux parce qu'il reste dans les limites du langage d'origine et démontre comment quelque chose d'impossible, à savoir le vrai parallélisme, peut être réalisé très simplement, mais au prix d'une discipline particulière. Cependant, si vous souhaitez "faire du parallélisme" facilement : il existe d'autres langages pour cela !
Mais il est possible de programmer l'exécution de processus parallèles en AutoIt.
Pour ce faire, le logiciel en AutoIt doit être spécifiquement programmé en deux parties :
- Principal : initialisation, lancement des processus parallèles, attente des fins d'exécution, consolidation des résultats
- Proc : processus à exécuter en instances indépendantes lancées en parallèle
Il s'agit bien ici de programmer en AutoIt des lancements de processus qui vont s'exécuter en parallèle indépendamment les uns des autres en tant qu'acteurs d'un même projet, et d'en récupérer les résultats pour consolidation.
Comment c'est possible et avec quelle conception adaptée
1/ L'instruction Run d'AutoIt peut lancer un processus sur un cpu thread donné, directement via la commmande start de Windows avec un paramètre /Affinity ou via un utilitaire pour la même fonction.
Evidemment, en vue d'une exécution en plusieurs instances parallèles indépendantes, le processus ainsi lancé doit être dans sa forme compilée en exe files.
Exemples
Run(@ComSpec & " /C start /affinity "&$Affinitymask&" proc.exe")
En répétant l'instruction avec differents "affinity masks" dans $Mask correspondant chacun à un cpuid, on lance autant de proc.exe en instances parallèles.
Autre méthode en utilisant un utilitaire de lancement qui accepte directement un cpuid en paramètre :
$slaunch="StartAffinity.exe proc.exe "&$cpuid
Run($slaunch)
2/ Chaque instance de processus lancé en parallèle doit évidemment être munie de paramètres spécifiques d'exécution, a minima son cpuid, soit via des paramètres de lancement dans l'instruction Run (récupérés en $CmdLine à l'intérieur de chaque instance) ou via quelques instructions envset avant l'instruction Run, dont les paramètres sont récupérés à l'intérieur de chaque instance par des déclarations envget de globals.
3/ En fin d'exécution, chaque instance de processus lancé en parallèle écrit ses résultats dans un fichier spécifique (par exemple sous un nom de fichier comportant le cpuid d'exécution).
4/ Après avoir lancé les processus parallèles, le logiciel principal attend la création des fichiers résultats pour consolidation.
Preuve expérimentale
Deux scripts AutoIt sont joints : Divisoptkim.au3 (Principal) and loopkim.au3 (Proc).
Leur but : trouver les diviseurs entiers d'un nombre entier.
Le script loopkim.au3 doit être compilé par le compilateur AutoIt sur votre machine.
Dans un même répertoire, installez Divisoptkim.au3 et loopkim.exe (plus l'utilitaire StartAffinity.exe seulement si vous utilisez Windows XP - voir in fine le lien pour le télécharger).
Lancez Divisoptkim.au3
(la compilation du script principal n'est pas nécessaire si l'extension au3 est associée à AutoIt sur votre machine).
Les processus loopkim vont s'exécuter en plusieurs instances indépendantes dès que vous aurez saisi un entier suffisamment grand pour justifier le parallélisme.
Quelques suggestions : 5040, 66049, 13 444 333 222 110, 133 444 333 222 110, 333 333 333 333 333.
N'hésitez pas devant les grands nombres, ils occuperont environ 10-15 seconds sur un dualcore, autrement le temps d'exécution sera pratiquement invisible.
Or, ce qui est intéressant, c'est justement de voir la charge de chaque cpu sur le Windows Task Manager (onglet Performances et Resources Monitor pour les versions Windows récentes).
Noter que le logiciel adapte le niveau de parallélisme en fonction de N. Concrètement, si N est relativement petit vis à vis du nombre de cpus disponibles, il réduit le nombre d'instances parallèles pour que chacune soit chargée raisonnablement (c'est-à-dire pour qu'elle s'exécute sur un segment minimum de 100 nombres candidats).
A la fin des processus parallèles, autant de fichiers Journal_x.txt sont créés que d'instances parallèles de loopkim.exe, (avec x = cpuid à partir de 0).
Une exécution du principal avec des paramètres standard (ceux qui sont définis en appuyant sur Return) allouera tous les cpus de la machine avec potentiellement une charge de 100% sur les cpus alloués. Vous pouvez évidemment déclarer un nombre de cpus plus faible que le nombre disponible sur votre machine, cela pourra vous faciliter l'observation de la charge générée via le Task Manager sur chaque cpu.
Si vous choisissez la deuxième méthode d'allocation, seulement les cpus pairs pourront être alloués, et la charge maximale ne pourra donc dépasser 50 %.
Avertissement. Ce logiciel a été testé sur plusieurs versions de Windows, de XP Home 32bit à Windows 11 64bit et sur diverses machines, du bicoeur simple au processeur à 20 threads. D'autres environments peuvent nécessiter des modifications du logiciel.
Pour XP spécialement.
Un utilitaire de lancement est indispensable car on ne peut pas utiliser la commande start, démunie sous XP du paramètre affinity.
Il existe au moins deux utilitaires disponibles.
StartAffinity http://www.adsciengineering.com/StartAffinity/.
Un autre utilitaire se trouve dans les "Heise software archiv" : chercher "launch".
Ces deux utilitaires fonctionnent par ailleurs très bien aussi sur les versions récentes de Windows.
Note. Divisoptkimv2 contient une instruction de rejet des entiers de longueur supérieure à 15 chiffres. C'est pour préserver la justesse des calculs internes. AutoIt gère automatiquement la conversion interne des représentations des entiers de 32 à 64 bits, mais aussi vers le format en virgule flottante, qui est incompatible avec les calculs tels qu'ils sont programmés dans mon logiciel de démo. Pour les très grands nombres, il faudrait utiliser la bibli BigNum, ce qui obligerait à reprogrammer tous les calculs... 05 mai 2023 : finalement, je renonce, mes procédures de division et modulo écrites à la main sont meilleures que les procédures plus génériques de la lib Bib Num...
La conclusion est qu'en cherchant à étendre un langage au-delà des limites de sa conception d'origine, on ne peut qu'engendrer un monstre. Mon petit logiciel de démo est scandaleux parce qu'il reste dans les limites du langage d'origine et démontre comment quelque chose d'impossible, à savoir le vrai parallélisme, peut être réalisé très simplement, mais au prix d'une discipline particulière. Cependant, si vous souhaitez "faire du parallélisme" facilement : il existe d'autres langages pour cela !