L'École Gray Scott

Jour 6 — SIMD avec EVE + architecture GPU

29 juin, deux sessions : Joël Falcou ouvre la semaine avec EVE et Kiwaku (SIMD C++20 explicite et portable), Pierre Aubert enchaîne avec l'architecture GPU qui portera les trois derniers jours.

29 juin 2026 — la semaine 2 s'ouvre · Matin : Joël Falcou (LISN, CodeReckons) — C++ 20 Computing with EVE + Kiwaku · Après-midi (14 h) : Pierre Aubert (LAPP) — GPU Architecture, massively parallel computing · Auditorium Marcel Vivargent + satellites (dont la CINERI). Le TP du jour vit dans GrayScott2026/day-6/ — les fichiers d'exercice de Falcou + la bibliothèque EVE clonée.

Session du matin — EVE + Kiwaku, le SIMD assumé

1. Le problème : un parallélisme fragile

Un seul cœur traite déjà plusieurs flottants par instruction (8 en AVX2, 16 en AVX-512) — c'est orthogonal au multithreading. Mais ce parallélisme est fragile : l'auto-vectorisation du compilateur n'est pas garantie (le Jour 3 a montré des boucles refusées), et les intrinsics écrits à la main ne survivent pas au changement de jeu d'instructions. La réponse de Falcou : en faire un type.

2. eve::wide — le registre devient un type C++

Premier exercice du TP, basic.cpp — sept lignes qui contiennent toute la thèse :

eve::wide<float, eve::fixed<8>> x( [](auto i, auto) { return 1.f + i; } );

std::cout << "EVE is optimizing for: " << eve::current_api << "\n";
std::cout << eve::sqrt(eve::abs(1 - x)) << "\n";   // les 8 voies d'un coup

eve::current_api imprime l'ISA détectée à la compilation — le même source émet de l'AVX2 ici, de l'AVX-512 ou du NEON ailleurs.

eve::wide<float, fixed<8>> x1.02.03.04.05.06.07.08.0eve::sqrt(eve::abs(1 - x))une écriture — les 8 voies calculent ensembleeve::current_api décide à la compilation :SSE2AVX2AVX-512NEONSVE
Le type wide EST le registre : on écrit le calcul une fois, EVE émet les bonnes instructions pour la machine cible

3. La progression du TP

FichierCe qu'il enseigne
basic.cppwide, les fonctions mathématiques vectorielles, current_api
math.cpples familles de fonctions EVE sur un vrai tableau
hypot.cppprécision et performance : l'hypoténuse naïve vs robuste, vectorisées
bilateral.cppun filtre bilatéral d'image — SIMD sur un algorithme réel
gray_scott.cpple stencil du cours, vectorisé à la main

4. Le Gray-Scott EVE — la vectorisation garantie

Le noyau final charge les neuf voisins en wide et enchaîne les FMA explicites :

auto u = eve::load(&su[i]);
auto full_u1 = w00 * (eve::load(&su[i - W - 1]) - u);   // 8 cellules à la fois
full_u1 = eve::fma(w12, (eve::load(&su[i + 1]) - u), full_u1);
// … les 9 termes du stencil, fusionnés en chaînes de FMA

Ce que le Jour 3 obtenait en négociant avec -fopt-info-vec, EVE l'obtient par construction — la vectorisation n'est plus un espoir, c'est le type qui l'impose.

5. Kiwaku — les conteneurs qui vont avec

Même auteur, étage au-dessus : Kiwaku fournit les conteneurs et vues multidimensionnels (shape, strides, adaptation au matériel) pensés pour brancher EVE dessus — le duo annoncé « containers » de la session. Encore jeune, mais la direction est claire : un code d'algorithme, des cibles.

Session de l'après-midi — l'architecture GPU (14 h)

6. Changer de philosophie

À 14 h, Pierre Aubert retourne la perspective : le CPU cache la latence (gros caches, peu de cœurs puissants) ; le GPU la noie sous le nombre — des dizaines de Streaming Multiprocessors, des centaines de cœurs simples chacun, et des threads qui avancent par warps de 32.

CPU — optimisé latencepeu de cœurs puissants, gros cachescœur 1cœur 2cœur 3cœur 4gros cache (L3)GPU — optimisé débitdes dizaines de SM × des centaines de cœurs simplesSM 1mém. partagéeSM 2mém. partagéeSM 3mém. partagéeSM 4mém. partagéeSM 5mém. partagéeSM 6mém. partagéeSM 7mém. partagéeSM 8mém. partagéemémoire globale (HBM) — accès coalescés obligatoiresles threads avancent par warps de 32 — la latence se cache par le nombre
Deux philosophies : le CPU cache la latence avec du cache, le GPU la noie sous des milliers de threads — à condition de nourrir la mémoire globale par accès coalescés

7. La hiérarchie mémoire du GPU

La session détaille les trois étages qui commanderont tout le reste de la semaine : registres (par thread), mémoire partagée (par SM — le « cache géré à la main »), et mémoire globale (HBM) dont les accès doivent être coalescés : les 32 threads d'un warp lisent des adresses voisines, ou le débit s'effondre. C'est la leçon de layout des Jours 2-4, transposée à 32 voies.

8. nvc++ en éclaireur, puis les Jours 7-9

La journée se clôt (15 h, Pierre Aubert encore) par un éclaireur : nvc++ compile du C++17 standard directement pour le GPU depuis 2020 — std::transform + politiques d'exécution parallèles, sans bibliothèque externe. C'est l'esprit stdpar qu'on retrouvera en Fortran au Jour 8 (do concurrent).

Tout est en place : Python sur GPU demain (Jour 7), Fortran sur GPU (Jour 8), Kokkos sur GPU (Jour 9) — trois langages, une seule architecture cible, celle de cet après-midi.

Le TP — GrayScott2026/day-6/

EVE est header-only : cloner et compiler suffit.

cd GrayScott2026/day-6
g++ -std=c++20 -O3 -march=native -I eve/include basic.cpp -o basic
./basic          # → "EVE is optimizing for: X86 AVX2" (selon ta machine)

Puis dérouler math.cpp, hypot.cpp, bilateral.cpp et gray_scott.cpp dans le même moule. Sur la machine du TP local : AVX2 détecté, 8 floats par instruction.

En vidéo — les replays officiels

Replay — EVE, a C++20 computing library on CPU (Gray Scott Thursdays)
Replay — GPU Architecture (Gray Scott Thursdays)
Replay — Modern C++ GPU computing avec std::algorithm et CUDA (Gray Scott Thursdays)

Sources & matériel officiel

Copyright © 2026