IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Des algorithmes de tri qui pourraient révolutionner les fondements de l'informatique sont découverts,
Par les chercheurs de Deepmind et Google

Le , par Bruno

50PARTAGES

6  1 
Des algorithmes de tri qui pourraient révolutionner les fondements de l'informatique sont découverts,
par les chercheurs de Deepmind et Google

Des algorithmes de tri qui pourraient révolutionner les fondements de l'informatique sont découverts par les chercheurs de Deepmind et Google, les performances des algorithmes découverts ont été comparées avec des algorithmes de tri par insertion, de tri rapide ou de tri introspectif. Les chercheurs montrent comment l’intelligence artificielle peut aller au-delà de l’état de l’art actuel en découvrant des routines inconnues jusqu’à présent. Pour ce faire, ils ont formulé la tâche de trouver une meilleure routine de tri comme un jeu à un seul joueur. Ils ont ensuite entraîné un nouvel agent d’apprentissage par renforcement profond (DRL), AlphaDev, à jouer à ce jeu.

Les chercheurs ont formulé la tâche de trouver un meilleur algorithme de tri comme un jeu à un seul joueur, et ont entraîné un nouvel agent DRL, AlphaDev, à jouer à ce jeu. AlphaDev a découvert à partir de zéro de petits algorithmes de tri qui ont surpassé les références humaines connues. Ces algorithmes ont été intégrés dans la bibliothèque standard C++ LLVM 3. Les auteurs présentent également des résultats dans des domaines supplémentaires, montrant la généralité de l’approche.

Des algorithmes fondamentaux tels que le tri ou le hachage sont utilisés des milliards de fois chaque jour. La demande de calcul augmentant, il est devenu essentiel que ces algorithmes soient aussi performants que possible. Bien que des progrès remarquables aient été réalisés dans le passé, l'amélioration de l'efficacité de ces routines s'est avérée difficile, tant pour les scientifiques que pour les approches informatiques. Les chercheurs montrent comment l'intelligence artificielle peut aller au-delà de l'état actuel de la technique en découvrant des routines jusqu'alors inconnues.


Pour ce faire, ils ont formulé la tâche consistant à trouver une meilleure routine de tri sous la forme d'un jeu à un seul joueur. Ils ont ensuite entraîné un nouvel agent d'apprentissage par renforcement profond, AlphaDev, à jouer ce jeu. AlphaDev a découvert de petits algorithmes de tri à partir de zéro qui ont surpassé les références humaines précédemment connues.

Ces algorithmes ont été intégrés dans la bibliothèque de tri standard C++ de LLVM3. Cette modification de cette partie de la bibliothèque de tri représente le remplacement d'un composant par un algorithme qui a été découvert automatiquement à l'aide de l'apprentissage par renforcement.

AlphaDev utilise une architecture d’apprentissage par renforcement profond basée sur l’acteur-critique, qui apprend une politique (acteur) et une fonction de valeur (critique) à partir d’expériences générées par interaction avec l’environnement. L’environnement est constitué d’un compilateur LLVM et d’un processeur x86-64. L’agent reçoit en entrée une séquence d’entiers à trier et produit en sortie un programme C++ qui implémente un algorithme de tri.

Le programme est compilé et exécuté sur le processeur, et le temps d’exécution est mesuré comme la latence du programme. La récompense est une fonction inversement proportionnelle à la latence, qui encourage l’agent à trouver des programmes plus rapides. L’agent utilise également un mécanisme d’exploration basé sur l’entropie pour encourager la diversité des programmes générés.

Les auteurs ont évalué AlphaDev sur plusieurs tailles de séquences à trier, allant de 4 à 16 éléments. Ils ont comparé les performances des algorithmes découverts par AlphaDev avec celles des algorithmes humains connus, tels que le tri par insertion, le tri rapide ou le tri introspectif. Ils ont constaté qu’AlphaDev était capable de trouver des algorithmes plus rapides que les références humaines pour toutes les tailles de séquences testées.

Par exemple, pour une séquence de 16 éléments, AlphaDev a trouvé un algorithme qui était 11% plus rapide que le tri introspectif, qui est considéré comme l’un des algorithmes de tri les plus efficaces en pratique. Les auteurs ont également testé AlphaDev sur d’autres domaines que le tri, tels que le hachage ou la recherche binaire. Ils ont montré qu’AlphaDev pouvait également trouver des algorithmes plus performants que les références humaines pour ces domaines.

Les chercheurs démontrent que l’intelligence artificielle peut découvrir des algorithmes fondamentaux qui surpassent les connaissances humaines actuelles. Ils soulignent que leur méthode est générale et peut être appliquée à d’autres domaines que le tri ou le hachage. Ils suggèrent également que leur approche pourrait être combinée avec des techniques de synthèse de programmes classiques ou basées sur l’apprentissage profond pour générer des programmes corrects et performants.

L'intuition et le savoir-faire humains ont joué un rôle crucial dans l'amélioration des algorithmes. Cependant, de nombreux algorithmes ont atteint un stade où les experts humains n'ont pas été en mesure de les optimiser davantage, ce qui a conduit à un goulot d'étranglement informatique de plus en plus important. Les travaux de la littérature classique sur la synthèse de programmes, qui s'étendent sur plusieurs décennies, visent à générer des programmes corrects et/ou à optimiser les programmes à l'aide d'indicateurs de latence.

Il s'agit notamment de techniques de recherche énumérative et de recherche stochastique ainsi que de la tendance plus récente consistant à utiliser l'apprentissage profond dans la synthèse de programmes pour générer des programmes corrects. En utilisant l'apprentissage par renforcement profond (DRL), nous pouvons aller plus loin en générant des algorithmes corrects et performants en optimisant la latence réelle mesurée au niveau des instructions du processeur, en recherchant et en considérant plus efficacement l'espace des programmes corrects et rapides par rapport aux travaux antérieurs.

Représentation des algorithmes sous forme d'instructions de l'unité centrale de bas niveau


a. Implémentation en C++ d'une fonction de tri variable 2 qui trie toute séquence d'entrée comportant jusqu'à deux éléments. b. L'implémentation en C++ en a est compilée dans cette représentation équivalente en assembleur de bas niveau.

Lors de la compilation d'algorithmes en code machine à partir d'un langage de haut niveau tel que le C++ (par exemple, la fonction de tri de la figure a ci-dessus), l'algorithme est d'abord compilé en langage assembleur (figure b). L'assembleur convertit ensuite le programme d'assemblage en code machine exécutable.

Dans ce travail, les chercheurs optimisent les algorithmes au niveau de l'assemblage. Dans un programme d'assemblage typique, les valeurs sont copiées de la mémoire vers les registres, manipulées entre les registres, puis réinscrites dans la mémoire. L'ensemble des instructions d'assemblage prises en charge dépend de l'architecture du processeur. Dans le cadre de ce travail, nous les chercheurs se concentrent sur un sous-ensemble d'instructions d'assemblage supportées par l'architecture de processeur x86 utilisant la syntaxe AT&T. Chaque instruction se présente sous la forme Opcode⟨OperandA, OperandB⟩.

Un exemple d'instruction est mov, qui se définit comme le déplacement d'une valeur de la source (A) vers la destination (B). D'autres définitions d'instructions telles que la comparaison (cmp), le déplacement conditionnel (cmovX) et le saut (jX) figurent dans le tableau de données étendu. Dans l'exemple de la figure b, %eax, %ecx, %edx, %edi correspondent à quatre emplacements de registre différents et (%rsi), (%rsi) correspondent à deux emplacements de mémoire différents. Le symbole $2 est un espace réservé pour une valeur constante, qui correspond à la longueur du vecteur dans cet exemple.

Les termes programme d'assemblage et algorithme d'assemblage sont utilisés de manière interchangeable dans ce travail. Ceci est dû au fait qu'AlphaDev construit un programme d'assemblage à partir de zéro, à partir d'un ensemble d'instructions initialement non ordonnées, chaque fois qu'il joue à AssemblyGame, en définissant un nouvel algorithme efficace.

Apprentissage par renforcement profond pour découvrir des algorithmes plus rapides


a, AssemblyGame est joué par AlphaDev, qui reçoit en entrée l'algorithme d'assemblage courant généré jusqu'à présent St et joue le jeu en sélectionnant une action à exécuter. Dans cet exemple, l'action est une instruction d'assemblage mov<Register0,Memory1>, qui est ajoutée à l'algorithme actuel. L'agent reçoit une récompense qui est fonction de la correction de l'algorithme, discutée en b, ainsi que de la latence de l'algorithme. Le jeu est remporté par le joueur qui découvre un algorithme correct et à faible latence. b) Les calculs de correction et de latence du programme sont utilisés pour calculer la récompense rt. Dans cet exemple, des séquences de test sont introduites dans l'algorithme ; par exemple, dans le cas du tri de trois éléments, les entrées de test comprennent toutes les séquences d'éléments non triés de longueur 3. Pour chaque séquence, la sortie de l'algorithme est comparée à la sortie attendue (dans le cas du tri, la sortie attendue est constituée par les éléments triés). Dans cet exemple, la sortie D′ ne correspond pas à la sortie attendue B′ et l'algorithme est donc incorrect.

L'optimisation des algorithmes au niveau des instructions du processeur est formulée comme un problème d'apprentissage par renforcement, dans lequel l'environnement est modélisé comme un jeu à un seul joueur que nous appelons AssemblyGame. Chaque état dans ce jeu est défini comme un vecteur St = ⟨Pt, Zt⟩Pt est une représentation de l'algorithme généré jusqu'à présent dans le jeu et Zt représente l'état de la mémoire et des registres après l'exécution de l'algorithme actuel sur un ensemble d'entrées prédéfinies. Comme le montre la figure a ci-dessus 2, à l'étape t, le joueur reçoit l'état actuel St et exécute une action at.

Cette action consiste à ajouter une instruction d'assemblage légale (par exemple, mov<A,B>) à l'algorithme actuel généré jusqu'à présent. Le joueur reçoit une récompense r qui comprend à la fois une mesure de l'exactitude de l'algorithme et du temps de latence. L'exactitude de l'algorithme (figure b ci-dessus) implique l'entrée d'un ensemble de N séquences de test dans l'algorithme actuel Pt pour générer N sorties. Ces résultats sont ensuite comparés aux résultats attendus et une récompense de correction rt est calculée.

Les récompenses pour la latence peuvent être générées soit en pénalisant l'agent pour avoir augmenté la longueur de l'algorithme (lorsque la longueur et la latence sont fortement corrélées), ce que nous appelons la récompense pour la longueur de l'algorithme, soit en mesurant la latence réelle de l'algorithme. Le jeu est exécuté pendant un nombre limité d'étapes, après quoi il est terminé. Gagner le jeu correspond à la génération d'un algorithme correct et à faible latence à l'aide d'instructions d'assemblage. Perdre le jeu correspond à la génération d'un algorithme incorrect ou d'un algorithme...
La fin de cet article est réservée aux abonnés. Soutenez le Club Developpez.com en prenant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de SpiceGuid
Membre émérite https://www.developpez.com
Le 08/06/2023 à 22:20
Les résultats de ces travaux de recherche sont-ils pertinents ?

Trier rapidement jusqu'à 4 éléments ça n'est pas le but du jeu

Le but du jeu c'est de trier un (très) grand nombre d'éléments le plus vite possible.
Et là l'article ne nous donne aucune recette
Bilan: zéro algorithme découvert.
Sérieusement, qui aurait besoin de Deepmind pour trier 4 élements ? C'est juste ridicule.
7  2 
Avatar de kriska
Membre du Club https://www.developpez.com
Le 09/06/2023 à 12:01
Etonné par les "Experts" du forums. En algorithmie, l'un des concepts qui marche bien c'est le "diviser pour régner".
Lorsque l'on fait un algo, on aime bien retomber dans un sous espace restreint dans lequel on va pouvoir appliquer des traitements simples et rapides voir des look up table.
Si on revient aux algos de tri, prenons le plus populaire - Quick sort - cela paraît évident qu'optimiser un tri à quelques éléments va être utile.

Là où je suis déçu c'est que je pensais en lisant le titre de l'article que ce serait vraiment sur le philosophie/concept de l'algo, hors là c'est plus spécifique à de l'algorithmie ASM.
5  0 
Avatar de sergio_is_back
Expert confirmé https://www.developpez.com
Le 09/06/2023 à 9:17
Citation Envoyé par Bruno Voir le message
....Les chercheurs montrent comment l'intelligence artificielle peut aller au-delà de l'état actuel de la technique en découvrant des routines jusqu'alors inconnues.
La vache... Ils ont découvert la programmation hier ?

Quand on voit la routine si dessous on ne peut que rigoler !

Citation Envoyé par Bruno Voir le message

Représentation des algorithmes sous forme d'instructions de l'unité centrale de bas niveau


a. Implémentation en C++ d'une fonction de tri variable 2 qui trie toute séquence d'entrée comportant jusqu'à deux éléments. b. L'implémentation en C++ en a est compilée dans cette représentation équivalente en assembleur de bas niveau.
Y'a des gens qui ont tant de temps à perdre que ça ? Qui aurait l'idée saugrenue de coder une routine uniquement capable de trier deux éléments ? Puis une pour 3 éléments, une pour 4 éléments, etc...

Ils connaissent vraiment l'algorithmie ces gens là ?

Je m'explique maintenant mieux la performance désastreuse de certains logiciels et l'énorme consommation mémoire de certains processus !
4  1 
Avatar de sergio_is_back
Expert confirmé https://www.developpez.com
Le 09/06/2023 à 9:06

C'est complétement nul !
Moi après 35 ans de développement j'en suis déjà à Length=16879951457855 ? -> Sort16879951457855
Ils sont pas prêts de me rattraper !
4  2 
Avatar de foxzoolm
Membre habitué https://www.developpez.com
Le 11/06/2023 à 23:59
Comme souvent l'article est écrit a l'arrache...
certainement MAL traduit de l'anglais ? ou alors du chatgpt avant l'heure ?

de memoire j'ai vue passé un article sur l'utilisation des instruction AVx pour faire du tri qui me semblait LARGEMENT plus efficace...

Ok, l'hisoitre ressemble plus a un proof of concept...
WAS
2  0 
Avatar de jo_link_noir
Membre expert https://www.developpez.com
Le 20/07/2023 à 14:08
Citation Envoyé par sergio_is_back Voir le message
Y'a des gens qui ont tant de temps à perdre que ça ? Qui aurait l'idée saugrenue de coder une routine uniquement capable de trier deux éléments ? Puis une pour 3 éléments, une pour 4 éléments, etc...
Les mêmes personnes qui s'occupent des optimisations. Justement parce que les cas de petit ensemble d'élément sont les plus fréquents, les plus coûteux et les plus faciles à optimiser. Concernant les algos de tri rapide, ils sont moins efficaces sur de petit groupe qu'un naïf, on peut facilement avoir du bubble sort plus rapide qu'un quick sort et c'est pour ça que la plupart des implémentations utilisent 2 algos de tri. Pour finir, comme les algos de tri vont découper sur en plus petit ensemble, ces fonctions spécialisées vont être souvent utilisées.

Ce n'est pas indiqué ici (ou j'ai lu trop vite), mais la vitesse de tri sur 5 éléments a était amélioré de 70% et les séquences de 250000 on bénéficiait d'un petit 1.7%.

À défaut de connaître l'algorithmie, ils savent la différence entre complexité théorique et réel

Citation Envoyé par sergio_is_back Voir le message
de memoire j'ai vue passé un article sur l'utilisation des instruction AVx pour faire du tri qui me semblait LARGEMENT plus efficace...
Le problème avec AVX ou autres instructions vectorisés, est qu'il faut en avoir le support. Mais la grosse contrainte est qu'ils ne fonctionnent bien que pour trier des nombres ; ce qui en fait des algos spécialisés et non génériques (même si je suis d'accord pour dire que le tri de nombre est probablement le plus fréquent).
1  0 
Avatar de Guesset
Expert confirmé https://www.developpez.com
Le 06/06/2024 à 10:11
Bonjour,

Le texte de l'article se répète plusieurs fois pour finalement ne pas dire grand chose.

Ce qui est montré, me semble-t-il, n'est pas un algorithme mais une implémentation. Il est vrai qu'une bonne implémentation peut accélérer sensiblement les processus, notamment en utilisant bien les ports de traitements, les interdépendances d'opérations et la multiplicité des cœurs. Cependant cela ne change en rien l'ordre de complexité lié à l'algorithme implémenté.

Il y a un autre aspect potentiellement négatif de cette démarche. Elle privilégie mécaniquement un accroissement du nombre d'instructions pour favoriser leur potentiel de parallélisation (entre autres au sein d'un même cœur entre les ports de traitement). Cela accélère certes le traitement mais augmente la consommation.

C'est quelque chose qui se rencontre dans le traitement d'image, où il peut être intéressant de traiter identiquement deux vecteurs couleurs séparés avant de les fusionner, au lieu de les fusionner et de faire le traitement sur la fusion.

Un autre problème de ces optimisations est leur dépendance au matériel. Pas de portabilité et peu de pérennité (une nouvelle génération de CPU pourra remettre en cause l'optimisation de la veille).

Rien de nouveau sous le soleil .

Salutations
1  0 
Avatar de dourouc05
Responsable Qt & Livres https://www.developpez.com
Le 12/06/2023 à 0:42
Citation Envoyé par foxzoolm Voir le message
de memoire j'ai vue passé un article sur l'utilisation des instruction AVx pour faire du tri qui me semblait LARGEMENT plus efficace...
Et si tu n'as pas AVX (par exemple, sur ARM ou RISC-V) ? Ce travail pourrait aussi servir à définir de nouvelles instructions dans la famille AVX pour du tri plus efficace, vu qu'on cible exactement ces tailles de problème.

Citation Envoyé par foxzoolm Voir le message
Ok, l'hisoitre ressemble plus a un proof of concept...
Pas du tout : ça fait un an que c'est dans LLVM, un peu plus que c'est déployé chez Google.
0  0 
Avatar de Guesset
Expert confirmé https://www.developpez.com
Le 06/06/2024 à 10:25
Bonjour,

Avec mes petits moyens, pas Chat GPT mais chat persan, je remarque, entre autres, que ce code optimal fait deux fois le même test.

Heureusement que le compilateur optimise cela avec un seul test et un bon entrelacement de code. On peut juste déplorer la création de l'équivalent de la variable intermédiaire même quand il n'y a pas de permutation. A comparer peut être avec un branchement et un xchg (1 ou 2 instructions en moins mais un branchement).

Salutations
0  0 
Avatar de Guesset
Expert confirmé https://www.developpez.com
Le 07/06/2024 à 15:14
Bonjour,

En testant le tri selon le code optimal vs le code de base suivant avec une boucle n de 0 à 100 000 000 - 1 et en prenant a0 = n et a1 = n ^1 (donc alternance > et <), le code non optimal est meilleur de 0.03 %. C'est à dire que les deux ont des performances identiques.
Code ASM : Sélectionner tout
1
2
3
4
5
6
7
   mov      r8d,     [rcx]   ; r8d := a0 
   mov      r9d,     [rdx]   ; r9d := a1 
   cmp      r8d,     r9d     ; i < j ? 
   jle      @Order_End       ; si oui, c'est fini sinon... 
   mov      [rcx],   r9d 
   mov      [rdx],   r8d 
@Order_End:

J'ai essayé de représenter les traitements effectifs. Même si c'est un peu approximatif, le but n'est pas une estimation ultra précise mais comparative.

Instructions en parallèle ( // )
Code : Sélectionner tout
1
2
3
4
5
   mov      r8d,     [rcx]   //   mov      r9d,     [rdx]  => 1                     + latences 
   cmp      r9d,     r8d     //   mov      eax,     r8d    => 1 
   cmovl    eax,     r9d     //   cmovg    r8d,     r9d    => 1 
   mov      [rcx],   eax     //   mov      [rdx],   r8d    => 1 
                                        Total approximatif => 4
Instructions en parallèle ( // )
Code : Sélectionner tout
1
2
3
4
5
6
   mov      r8d,     [rcx]   //   mov      r9d,     [rdx]  => 1         1           + latences 
   cmp      r8d,     r9d     //                            => 1         1 
   jle      @Order_End       //                            => 1         2  si saut 
   mov      [rcx],   r9d     //   mov      [rdx],   r8d    => 1 
@Order_End:     
                                        Total approximatif => 4         4
A solutions équivalentes en terme de performances, j'aurais tendance à opter pour la moins énergivore.

Salutations
0  0