Pour février un défi de vitesse de calcul et d’optimisation. Il m’a en effet été demandé plusieurs fois de faire un défi sur les optimisations LabVIEW.
Syracuse et Collatz ont travaillés sur des choses simples qui comme d’habitude se compliquent. Elles sont devenues des conjectures (ou suite et arbres de Syracuse) à tel point que « les mathématiques ne sont pas encore prêtes pour de tels problèmes ». Mais LabVIEW si !
Par exemple on choisit au départ un entier naturel strictement positif. Si celui-ci est pair alors on le divise par deux. S’il est impair alors, pour le rendre pair, on le multiplie par 3 et on ajoute 1. Si on répète l’opération, nous obtenons une suite d’entiers qui « à priori » tendent toujours vers 1 à la fin (pas encore définitivement prouvé). Avec plus ou moins de rapidité que l’on appelle le temps de vol et passant par des valeurs qui atteignent un pic que l’on appelle altitude maximale.
Exemple de suite pour la valeur de 6 :
6 - 3 - 10 - 5 - 16 - 8 - 4 - 2 – 1 soit une durée de vol de 8 et une altitude maximale de 16
Le défi sera de calculer toutes les altitudes maximales et durées de vol sur les 3 millions premières valeurs de 1 à 3E6 et de les retourner dans un tableau 2D avec une exécution la plus rapide possible.
La face avant du programme LabVIEW sera donc composée d’une entrée « n » U32 pour saisir la taille du tableau à calculer (par exemple 3E6) et d’un tableau à indicateur à deux dimensions U64 qui sera connecté en sortie pour en faire un Sous-VI (Vous pouvez utiliser l’exemple fourni en pièce jointe). Ainsi je pourrais utiliser un programme de test qui charge le Sous-VI proprement pour mesurer le temps de calcul.
Le gagnant sera celui qui a le temps moyen de calcul le plus court. Les méthodes doivent exécuter des opérations mathématiques et ne pas fournir de valeurs à partir de tableaux déjà précalculés.
Le but est d’explorer les astuces, simplifications et optimisations présentes dans LabVIEW.
Pour unifier les règles sur les valeurs de départ du tableau à retourner, voici les valeurs :
Pour 1 la durée de vol est 0 et l’altitude maximale est de 1
Pour 2 on a [2 – 1] soit une durée de vol de 1 et altitude maximale de 2 (on compte la valeur de départ comme la plus grande dans ce cas)
Pour 3 on a [3 - 10 - 5 - 16 - 8 - 4 - 2 – 1] soit une durée de vol de 7 et une altitude maximale de 16
Etc…
Pour participer envoyez votre code LabVIEW (peu importe la version) avec l’extension Ch48_Vol_syracuse_votre pseudo.vi avant le 1er mars 2018 à emmanuel.roset@ni.com
Vous pouvez envoyer plusieurs versions de vos codes si vous constatez une amélioration.
Ce qu’il y a à gagner ? des goodies qui sont utiles.
Les codes seront publiés et partagés à la fin du mois.
Que la guerre des chiffres et optimisations commence ! et pas de triche je surveille les codes !
Pour information :
Le VI de test est un simple chargement et passage de valeurs avec soustraction de temps puis moyenne.
C'est pour cela qu'il faut relier les E/S de l’icône du VI avec les bon noms sur les étiquettes ("n" et "s").
Mon PC de test, sans perturbation pendant les calculs :
Le programme utilisé recharge complètement le VI à chaque passe pour éviter la bufférisation: (moy sur 100)
Voici le tableau du classement en cours de mois (mis a jour régulièrement):
Moy sur 100 | Toutes versions testées (la meilleure retenue) | Moy | Min | Utilisation de : | ||||||||
1 | Ch48_Vol_Syracuse_Didje007 | 226,85 | 192,23 | Opérateur logique rotation vers la droite avec retenue, registre valeurs connues, structure élément en place | ||||||||
2 | Ch48_Vol_syracuse_Ben64 | 243,73 | 204,98 | Opérateur arithmétique plus et de l'opération décalage logique et le ET, registre des valeurs connues (meilleure=V4) | ||||||||
3 | Ch48_Vol_syracuse_JulienV | 383,75 | 353,06 | Opérateur logique rotation vers la droite avec retenue et structure élément en place (mémoire registre) | ||||||||
4 | Ch48_Vol_syracuse_Bleses.vi | 476,56 | 438,45 | Opérateur logique, structure élément en place, registre valeur connues | ||||||||
5 | Ch48_Vol_syracuse_Damien21 | 746,67 | 688,25 | Opérateur logique et décalage logique avec boucle de paralélisation | ||||||||
6 | Ch48_Vol_syracuse_PHILB58 | 2548,9 | 2469,7 | Opérateur logique rotation vers la droite et parallélisation massive par boucles en parallèle | ||||||||
7 | Ch48_Vol_Syracuse_OlivierL | 2489,54 | 1735,47 | Opérateur logique rotation vers la droite, Opérateur arithmétique par puissance de 2 et parallélisation native à la boucle For | ||||||||
8 | Ch48_Vol_syracuse_lulu44 | 38891,3 | 38154,6 | Gestion directe par boucle while et augmentation tableau dynamiquement |
Il reste de la place pour d'autres ! et renvoyez vos ajustements si vous le souhaitez (v1,v2...) on stoppe à 10 par personne
Pour ceux que ça intéresse, ce qui sympa avec cette conjecture est de la représenter graphiquement pour voir apparaitre des tendances. Il suffit de tracer par exemple:
- durée du vol = f(valeur de départ)
- altitude maximale = f(valeur de départ)
Premier test
2402ms pour n = 1000000.
Intel i5 - 6500 CPU @ 3.2GHz
RAM 8GB
Win 7PRO SP1 64 bits (LabVIEW 2017 32 bits)
En recherche d'optimisations 🙂
Et comme les goodies sont toujours de mise, je ne participe pas au tirage au sort
intel i7-4790 @3.6GHz / 16Go ram / W7
Premier test pour n=3 000 000 (codé en 5 minutes, méthode bourrin): 6.65 s
Première optimisation (parallélisation) : 1.3 s
Nouvel algorithme : 1.2 s
Optimisation : 0.86 s
En recherche de pistes pour optimiser plus.
Hum, j'avais posté un message ici, il a disparu
Et je ne reçois plus de notifications
Et je viens de passer MEMBER ça fait déjà un moment que je le suis, alors je suis content de changer de status MEMBER pour MEMBER
Bon bah je vois que j'ai encore du boulot!!
Avec n = 3 000 000
Première version : 165 secondes.
Améliorations des données utilisées : 4,6 secs.
Va peut-être falloir que j'aille faire un tour vers la parallélisation pour optimiser encore ^^
Parralelisation : 1.6 sec
Olivier L. | Certified LabVIEW Developer
Code envoyé.
Merci pour ce challenge très instructif, j'ai vraiment été surpris à quel point de petites modifications pouvaient avoir un impact sur les performances. Je crois finalement être venu à bout de toutes les améliorations possibles de mon code, en voici les résultats et le vi que j'ai utilisé pour en mesurer les performances (statistiques de 1000 itérations avec n = 3E6).
Code envoyé.
Ben64
Bonjour, j'ai ajouté un tableau des valeurs en cours. Les temps sont un peu plus long que ce que vous avez mais cela dépend surtout de la méthode de chargement qui en natif "voit" que c'est le même VI. Et il optimise sur les variables.
En tout cas il y a une nette différence. Nous affinerons si les temps se rapprochent.
il reste pas mal d'optimisations possibles (si seulement vous voyiez les codes des uns et des autres tous mis ensemble) ce sera à la fin du mois
Tous ceux qui veulent se lancer, n'hésitez pas le but est aussi de partager ses méthodes. A la fin tout le monde récupère les optimisations et astuces des autres.
J'ai reçu une mise a jour de Ben64 qui améliore la vitesse. Tableau rafraichi.
Bizarrement, je ne reçois pas d'e-mail pour les nouveaux commentaires.
En tout cas, je vois que j'ai encore du boulot pour trouver l'optimisation qui va bien... je suis loin derrière 😄
Olivier L. | Certified LabVIEW Developer
pareil, plus de notification
Par contre, j'ai du mal à interpréter "244,329446m" dans le tableau!!!!
C'est des ms???
Nouveau classement publié avec les nouveaux arrivants.
Julien_V a effectué de grosses optimisations pour arriver à un excellent temps et se rapproche de Ben64 !
lulu64 n'a pas cherché particulièrement d'optimisations ce qui nous fait un temps de référence d'origine
Optimisation du code de JulienV qui descend à 408ms
Pfff, un mois difficile s'il en est, je n'ai pas trouvé de temps pour optimiser mon code 😞
J'ai maintenant un code qui tient la route (et une certaine vitesse 🙂 ) par contre, j'ai une question:
La valeur entrée (n) peut-elle être du style 3215713 ou simplement 1, c'est à dire n'étant pas multiple de 10???
Auquel cas, je devrai faire une petite modif pour en tenir compte, mais bon, je n'en voit pas l'utilité si c'est pour mesurer l'efficacité du code, la vitesse de traitement!
Merci de me donner votre avis!
Code envoyé 😉
code envoyé
Tableau du classement remis a jour avec les nouveaux codes arrivés. Je donnerai les astuces clé de chaque codes en commentaire au dépouillement. Chacun a misé sur une méthode différente ingénieuse et valable. Il reste jusqu'à demain !
Moyenne n=100 | Moy | Min | |
1 | Ch48_Vol_syracuse_Ben64 | 244,33 | 201,56 |
2 | Ch48_Vol_Syracuse_Didje007 | 404,54 | 358,95 |
3 | Ch48_Vol_syracuse_JulienV | 408,40 | 392,98 |
4 | Ch48_Vol_syracuse_Bleses.vi | 855,55 | 848,50 |
5 | Ch48_Vol_syracuse_PHILB58 | 2576,62 | 2440,07 |
6 | Ch48_Vol_Syracuse_OlivierL | 2593,58 | 1757,45 |
7 | Ch48_Vol_syracuse_lulu44 | 37000,00 | 36000,00 |
En effet amélioration du temps d'exécution, bravo encore des ms de gagnés
Ch48_Vol_syracuse_JulienV | 387,08 | 357,71 |
Bonjour,
Code envoyé 🙂
V2 envoyée
J'améliore un peu mon temps
Update de dernière minute qui change le classement de tête. J'ai fait de très nombreuses passes avec mon Laptop. (Qui m'a permis de me réchauffer les mains ce matin).
Didje007 passe devant Ben64 de très peu mais incontestable. Voici donc les 5 premiers avec l'entrée de Damien21 :
Moyenne n=100 | Moy | Min | |
1 | Ch48_Vol_Syracuse_Didje007 | 232,56 | 203,62 |
2 | Ch48_Vol_syracuse_Ben64 | 244,33 | 201,56 |
3 | Ch48_Vol_syracuse_JulienV | 387,08 | 357,71 |
4 | Ch48_Vol_syracuse_Damien21 | 746,35 | 698,81 |
5 | Ch48_Vol_syracuse_Bleses.vi | 855,55 | 848,50 |
Je confirme, mon cerveau est proche de l'explosion aussi.
Par contre je suis complètement largué. J'ai réussi à descendre à 4s ce matin mais je ne vois vraiment pas comment faire mieux. Vivement que je puisse me pencher sur vos codes à tous
Mise a jour de mon code envoyé.
J'ai hâte de voir la stratégie des codes rapides.
Merci pour tous les codes, la bataille est acharnée, je suis en train de tout tester. J'attends encore les dernières versions d'ici demain matin pour partir d'un PC redémarré et tout re-tester en prenant le minimum de chaque code toujours dans les mêmes conditions. Le suspense se joue a quelques ms...
A la fin vous pourrez voir dans les codes les astuces de chacun qui pourrons resservir plus tard et je ferai un petit résumé.
A vrai dire je ne pensais pas passer devant Ben64. Sur mon pc la différence de temps de mon amélioration n'était pas aussi significative.
J'ai toute de même envoyé une dernière version qui améliore un peu mes performances, l'effet est négligeable sur mon PC, mais si ça me permet de rester en tête...
Et merci encore Emmanuel pour ces challenges mensuel même si je n'envoie pas ma participation tous les mois je me creuse au moins la tête dessus
Code envoyé
Bon voilà, les résultats sont publiés, mon PC va pouvoir refroidir...
Le gagnant est Didje007 qui a cumulé presque toutes les astuces ! BRAVO
Je tiens a féliciter la belle bagarre entre les deux finalistes avec Ben64 qui ont envoyés leurs codes tour a tour a faire fumer ma boite mail
Du coup je pense lui donner un lot de compensation aussi
Pour les optimisations :
En effet il faut se concentrer sur les déclarations mémoire, si possible utiliser les fonctions natives voir de type booléennes même pour des opérations mathématiques, désactiver tout débogage, mettre en priorité haute, ne pas recalculer toutes les valeurs, retirer tout ce qu'il est possible de la boucle qui est la plus sollicitée (ne pas utiliser de boucle while pour augmenter la taille d'un tableau).
La parallélisation fonctionne mais parfois si le calcul est trop court alors cela prend plus de temps au processeurs de gérer les basculements et le multitache que de le faire nativement par windows/LabVIEW et les thread déjà déclarés par le compilateur.
En tout cas on passe de 38 secondes à 226 ms ce qui est énorme ! J'espère que vous appliquerez ces astuces pour vos prochains programmes et épater votre entourage
sympa les solutions, je n'imaginais pas du tout aller dans le sens des plus rapides!!!!
Comme quoi, se remettre en question et ce partage de solutions peut être bénéfique pour tout le monde 😉
Merci à tous!
Bravo à tous pour ce challenge, et bravo pour les codes optimisés!!
Très instructif de voir les solutions!! même si certains manquent un peu de lisibilité
Et comme le dit Emmanuel, passer de 38sec à 226 ms .... On voit qu'il est important de se poser un peu sur son code pour l'optimiser ^^
Olivier L. | Certified LabVIEW Developer