Ahaha je me disais bien aussi, j'avais un peu tiqué sur l'avx-512 "qu'il y en aura dans les deux familles mais ça sera pas le même avx-512"
Bon faut dire j'ai vu que la fin de la présentation technique. Ils sont idiots aussi de commencer un séminaire avant 9h du mat'
- - - Mise à jour - - -
Ca serait drôle tiens, devoir attendre l'arrivée de 4 lignes de cache pour lancer une instructions avx
Ya un topic où on peut poser des questions sur git ?
On a un problème avec un projet de groupe là :
On a 2 branches, A et B.
On a fait des modifs sur A, et en attendant qu'elles soit utilisables (il fallait modifier la partie serveur sur laquelle on a pas la main), on a créé à partir de A une branche B.
Ensuite, on a revert les commit sur A (créant donc environ 25 commit de revert) et on a recommencé à travailler dessus.
Maintenant, le serveur a été modifié et on voudrait donc récupérer les modifs de B.
On fait donc :
Sauf que le seul commit qui est merge c'est le dernier (le seul qui n'a jamais été présent sur A, il a été spécialement fait sur la branche B.Code:git checkout A git merge B
Je pense donc que c'est les commit de revert qui font que les commit de B sont jamais appliqués.
Mais je sais pas quoi faire, c'est la première fois que j'ai un cas comme ça...
On pensais réécrire rapidement l'history des commit sur A pour virer les revert et les commit d'avant les revert.
Vous en pensez quoi ?
Merci d'avance
Oui, c'est bien l'endroit pour parler de git
Perso j'en suis resté à svn, et je développe seul donc pas de merge pour moi
Bah ouais, mais à 3 plombes du mat, ça met le stress.
Dire que le type a signé son "papier"
Y bosse pas chez Intel, c'est genre un consultant. J'ai trouvé sa fiche sur Ziff Davis, c'est dire si ça part bien
Je lui ai envoyé un mèl sur sa boîte perso, on verra bien.
Dernière modification par vectra ; 20/04/2016 à 16h02.
Facile.
J'ai qu'une branche: dev et prod.
Sinon, question importante: mais comment que ça marche, OpenMP, les pragmas, la compilation, l'édition de liens??
J'ai constaté qu'une boucle avec les pragmas autour, et la compilation et l'édition de liens avec OpenMP, ben ça marchait plus vite que si on compile sans OpenMP.
Et ce pour un seul thread, donc.
Bref, j'aimerais voir ce que fait OpenMP pour accélérer le code mono-thread. J'arrive à faire mieux que lui en vectorisant (etc), mais j'aimerais qu'on soit potes et que mes optis se raccordent aux siennes.
Ma question: OpenMP injecte-t-il du code à lui à une étape donnée de la compilation? Puis-je voir quoi?
Visiblement, cpp ne suffit pas, et me renvoie en clair les pragmas.
La question suivante, c'est comment OpenMP fonctionne... Est-ce une bibliothèque séparée qui va exécuter mes boucles? Bref, je comprends queud' à comment fonctionne le système.
Dernière modification par vectra ; 20/04/2016 à 22h13.
Je suis en train de me taper la seconde vague de bad trip.
OpenMP peut auto-simd on dirait, c'est clairement pas déconnant et on peut l'en remercier.
Par contre, comment qu'on auto-simd plus parallélise? Moi, y'm'faut les deux...
re:
https://software.intel.com/en-us/art...using-openmp40
En fait, j'ai tendance à voir OpenMP comme une bibliothèque externe au compilateur, mais en fait j'ai l'impression que c'est une fonctionnalité normalisée que chaque compilateur moderne propose.
Tu as quand même une réécriture assez importante des boucles quand tu compile avec openmp. (très amusant à débugguer quand tu te tapes une segfault sur un ligne qui n'existe pas dans ton code source d'ailleurs )
T'es bien sûr d'avoir un seul thread qui tourne ? Les mêmes conditions de compilation en-dehors des ajouts openmp ?
De mon côté, j'ai plutôt observé qu'une boucle avec directives openmp en mono thread sera sensiblement moins rapide que le code sans aucune directive.
Oui, j'ai bien veillé à cela.
Donc OpenMP, c'est le compilateur qui l'implémente?
En gros, c'est le code x86 qui est ré-écrit, y'a pas de transformation vers du code C optimisé avant la compilation?
Je viens de voir sur mon gestionnaire de paquets: c'est marqué que ce sont des bibliothèques, mais y'en a visiblement une par compilateur.
J'ai la 4.9 pour gcc, la 5 est sortie on dirait.
Mais je ne peux pas cumuler le parallel for et le simd avec gcc.
Quelque part ça m'arrange pour ma thèse, mais c'est un peu triste dans l'absolu.
J'aurais pu m'en servir pour torcher l'optimisation de filtres additionnels par exemple...
C'est vraiment pas clair, mais ils ne parlent pas de la largeur d'une ligne de cache, ils parlent de la largeur du cache lui-même. Tu peux avoir un bus de largeur 64-bit entre le L2 et le L3 et transférer tes lignes de cache en 8 cycles voire moins si tu bypasses le cache. Ça permet déjà un débit de 30 Go/s par core, et un bus 512 bit serait overkill à ce niveau.
D'ailleurs tu as une optimisation classique pour gratter quelques cycles de latence mémoire lors d'un cache miss, qui est de rapatrier la ligne de cache en commençant par le mot dont tu as besoin, suivi du reste de la ligne de cache. Comme ça tu peux forwarder la donnée aux unités d'exécution dès que le premier mot arrive plutôt que d'attendre toute la ligne de cache. Les DRAM ont un mode spécial pour ça, où en mode burst les bits de poids faibles de l'adresse indiquent l'ordre des transferts dans le burst.
- - - Updated - - -
Oui c'est le compilateur qui le gère (il faut bien parser le #pragma à un moment), mais les transformations sont faites au niveau représentation intermédiaire, bien après le parsing du C et bien avant la génération de code x86. D'ailleurs ça peut aussi bien être pour du Fortran sur PowerPC.
Et tu as aussi une bibliothèque, pour les fonctions omp_* et le support runtime.
La réécriture n'est pas un processus indépendant en fait, tu n'as pas "1 étape de tranformation openmp + 1 étape de compilation" tout se passe en même temps.
La lib sert comme support d'exécution, elle apporte certaines fonctions genre omp_get_thread_num() mais n'est pas directement liée à la transformation du code avec les directives.
Dans le standard 4.0 tu est censé pouvoir faire des #pragma omp parallel for simd si le code s'y prête bien, mais j'ai jamais testé.
Vu comment c'est formulé, je trouve surtout que ça n'a pas de sens. D'un côté ça parle de "Data transfers between the processor and memory are always 64 bits wide", donc en effet ça a l'air d'être la largeur du bus. Cela étant, quelle que soit la largeur dudit bus, on va transférer une ligne de cache depuis la DRAM vers le L3 (à part dans des cas chelous, lire 1/8 de ligne de cache je vois moyennement l’intérêt). Donc quand ensuite on lit "If only a byte of data is requested, the full 64 bits are retrieved but the processor may use only 8 of those", là je ne comprend plus. Je ne parle même pas du fait qu'il y a un L3 mais que ça parle de la largeur du L2.C'est vraiment pas clair, mais ils ne parlent pas de la largeur d'une ligne de cache, ils parlent de la largeur du cache lui-même. Tu peux avoir un bus de largeur 64-bit entre le L2 et le L3 et transférer tes lignes de cache en 8 cycles voire moins si tu bypasses le cache. Ça permet déjà un débit de 30 Go/s par core, et un bus 512 bit serait overkill à ce niveau.
Après il y a des chances que ça soit un mix des deux: bus 64-bit entre DRAM et L3(L2?/L1?) d'un côté et transferts de 8 bytes (64-bit) minimum entre le L1 et les unités fonctionnelles de l'autre. Mais clairement pour la clarté on repassera.
Critical word first (c'est si quelqu'un veut chercher sur gogole ).D'ailleurs tu as une optimisation classique pour gratter quelques cycles de latence mémoire lors d'un cache miss, qui est de rapatrier la ligne de cache en commençant par le mot dont tu as besoin, suivi du reste de la ligne de cache. Comme ça tu peux forwarder la donnée aux unités d'exécution dès que le premier mot arrive plutôt que d'attendre toute la ligne de cache. Les DRAM ont un mode spécial pour ça, où en mode burst les bits de poids faibles de l'adresse indiquent l'ordre des transferts dans le burst.
Dernière modification par Thamior ; 20/04/2016 à 17h10.
Envoyé par François
Ah, oui, on avait déjà parlé du frontend et du backend du compilateur.
Ca me fait un peu penser aux intrinsics alors: y'a un standard pour les faire, mais c'est aux compilateurs qui veulent le supporter de l'implémenter chacun à leur manière...
Merci pour la réponse sur le cache, je comprends ta version en tous cas. Le but des caches, c'est aussi de faire chambre de compression entre la mémoire lente et le cache L1 qui doit débiter en 1 cycle CPU.
Si je ne dis pas de conneries, avec 25 go/s de débit mémoire total pour un CPU à 4 Ghz (oui soyons fous), ça nous fait 6.25 octets en moyenne lisibles par cycle CPU, soit 50 bits.
Ah oui, comme ça, ça marche :P
Et là, les perfs redescendent à 330ms avec un thread + parallel-for simd.
Sans simd, ça va à 240 ms pour un thread, ce qui est une belle opti pour quelque chose de complètement gratuit.
Sinon, en résumé, simd n'améliore pas grand-chose parce que le compilateur a déjà pas mal vectorisé le code des boucles, sans qu'OpenMP ne soit invoqué, et sans que je lui demande d'ailleurs (movaps partout, mulps, etc...)
En codant en SSE, en mettant des lectures/écritures non-terminales, en dépliant un peu les boucles, puis en parallélisant après avec OpenMP, j'arrive à descendre à 150 ms, parfois 135 sur certains codes tordus. Donc, en gros, tout se tient.
Sous gcc, c'est l'option -ftree-vectorize qui contrôle l'auto-vectorisation (activé par défaut en O3 il me semble), mais tu peux aussi ajouter -ffast-math ou -fassociative-math (moins violent) pour lui permettre de faire de la vecto plus agressive.
Tu peux avoir des retours sur ces transformations avec -ftree-vectorizer-verbose=2 par exemple.
J'avais testé ça dans le temps, -ffast-math gagne un peu, mais relativement peu par rapport à de l'opti à la main.
Et il fait des trucs sales je crois, c'est un raccourci pour toute une série d'optimisations pas très safe, dont les divisions d'office par reciprocal moins précise, il me semble.
Faudrait décomposer chaque option pour voir ce qui est safe ou pas.
Si c'était safe, ça serait activé par défaut en -O3.
Globalement, le compilateur a le droit de transformer ton programme en return 42 en respectant les contraintes de -ffast-math, parce qu'il n'y en a essentiellement pas.
Même -fassociative-math est un concept foireux à la base. Si tu te permets de jouer à la fois sur l'associativité et sur les vraies propriétés des flottants, tu peux aussi exprimer tout et n'importe quoi en combinant ces transformations (ex falso quodlibet : une fois que tu as prouvé que 0 == 1, tout devient possible).
Du coup tu dépends du bon vouloir de ton compilateur faute de spec, comme si tu faisais du Python.
Sleeping all day, sitting up all night
Poncing fags that's all right
We're on the dole and we're proud of it
We're ready for 5 More Years
Sans voir ton historique exact c'est quand même dur de faire une bonne recommandation, c'est un peu vague.
Y a plein d'approches possibles.
Sleeping all day, sitting up all night
Poncing fags that's all right
We're on the dole and we're proud of it
We're ready for 5 More Years
Bon, bah je fais un joli dessin alors
Voilà la gueule de l'historique :
Désolé pour le schéma un peu sale...Code:Branche comportant désormais les modifs de la feature X ()------[1 mini commit]---------------------------------------------------------------------------- B | | Création de la nouvelle branche B A---------[Commit de la feature X] -----------()----------[Commits de revert de la feature X]-------[Commits qui touche à d'autre choses]-- A
Ce que j'ai essayé de faire :
Code:git checkout A git rebase -i B ET git checkout A git merge B
Il faut que tu fabriques une nouvelle branche qui est B + [Commits qui touchent à d'autre choses], c'est bien ça ?
Si oui...
a) les deux branches sont vraiment des travaux indépendants, il faut que tu rebases le range de commits [Commits qui touchent à d'autre choses] sur A.
b) si les deux travaux vont rentrer en conflit, il faut que tu rebases [commits qui touchent à d'autre chose] sur l'ancêtre commun de A et B pour créer C.Tu peux ensuite merger A et C.
Les deux possibilités sont là pour minimiser le nombre de merges (a) ou le nombre de résolution de conflits (b)
Tu sais te servir de rebase --onto ou de rebase --interactive ?
Dernière modification par Tramb ; 21/04/2016 à 09h24.
Sleeping all day, sitting up all night
Poncing fags that's all right
We're on the dole and we're proud of it
We're ready for 5 More Years
Oui, désolé, je ne peux pas m'empêcher de faire des blagues dégueulasses. Plein. Mais ne débattons pas du nombre.
Sleeping all day, sitting up all night
Poncing fags that's all right
We're on the dole and we're proud of it
We're ready for 5 More Years
Bonjour bonjour, petite question.
On est en train de faire un projet pour retaper un logiciel. Celui-ci affiche une interface un peu à la simulink ou Labview. Un ensemble de boite (qui doivent être sensible au clic, déplaçable et tunable graphiquement etc...) lié entre elles par des liens.
Problèmes, avant on avais fait ça avec GTK + cairo. Et on aimerais bien savoir quelles sont les alternatives à ce combo ?
Quelqu'un à proposé le Javascript avec, notamment, node.js, mais je me méfie ... j'aimerais un truc simple et bas niveau et surtout ne pas multiplier les langage (on est en C à la base).
Voila voila, je prends tout les conseils...