• Aucun résultat trouvé

Parallélisation pour les architectures SIMD

8.2 Approche employant les algorithmes à réutilisation des valeurs

8.2.2 Parallélisation pour les architectures SIMD

Une fois expliqué l’algorithme HGW pour les éléments de base, nous nous demandons de quelle manière nous pouvons explorer les capacités SIMD de notre architecture multimédia pour accélérer le calcul de cet algorithme. Puisque cet algorithme utilise les principes de traitement qui sont compatibles avec le traitement des données paquetées, nous pouvons facilement dériver un algorithme SIMD à par- tir de la description de l’algorithme travaillant avec les éléments de base, comme présenté par l’algo- rithme 8.2. Nous allons travailler, comme à l’échelle des colonnes, tant à l’échelle des macro blocs, avec les structures composées des vecteurs paquetés PVec I α plutôt que d’utiliser les structures composées des éléments de base du type α.

Formellement, nous pouvons décrire ce procédé par la spécialisation de l’algorithme 8.2 pour les données paquetées et l’algorithme qui décrira ce procédé devra assurer le paquetage de l’array d’entrée, appel de l’algorithme algoHGWFst et, à la sortie, également le dépaquetage des résultats afin d’obtenir l’array composé des données du type de base.

Cependant, nous ne pouvons pas choisir n’importe quelle direction pour la propagation des valeurs SIMD car nous sommes contraints par le sens de stockage des données vectorielles dans la mémoire. Ainsi, il est simple de construire l’algorithme pour les segments qui sont perpendiculaires au sens de stockage. En revanche, il est impossible d’utiliser l’algorithme SIMD de van Herk-Gil-Werman pour un segment parallèle au sens du stockage et nous sommes obligés d’effectuer une opération de changement du sens de stockage des données vectorielles, comme décrit dans le chapitre 6 dédié à cette problé-

matique. Dans ce cas, nous allons faire appel à la transposition des images entières. Remarquons que nous pourrions construire également des algorithmes qui exploiteraient l’approche des macro blocs et la transposition directe, mais nous soulignons que leur construction, même possible, n’est pas triviale.

C’est à cette place que nous allons expliquer pourquoi nous avons choisi l’axe "Fst" pour la construc- tion de l’algorithme 8.2, défini par la fonction algoHGWFst. Supposant que les données sont stockées dans la direction de la deuxième coordonnée, ce sont les segments suivant la direction "Fst" pour lesquels nous pouvons construire l’algorithme SIMD d’une manière simple, comme présenté par l’algorithme 8.3 (défini par la fonction algoHGWFstSIMD).

Algorithme 8.3 : algoHGWFstSIMD, Algorithme SIMD de van Herk-Gil-Werman pour les seg- ments suivant la direction de la première coordonnée (Fst) et en supposant que l’axe de stockage des données dans la mémoire est "Snd"

1 algoHGWFstSIMD :: I → I → BroderFnc → (α → α → α) → Ar ( I , I ) α → Ar ( I , I ) α 2 algoHGWFstSIMD n k brdfnc f ar = 3 mkAr2DFromAr2DPVecBySnd 4 ◦ (algoHGWFst k brdfnc f ) 5 ◦ (mkAr2DPVecBySnd n) 6 $ ar

La construction de l’algorithme 8.4 (défini par la fonction algoHGWSndSIMD) exploitant les capa- cités SIMD pour les segments suivant la direction parallèle à l’axe de stockage de données est enrichie par la transposition par diagonale, exécutée par la fonction trRot2DMBSIMD, qui assure le change- ment du sens de stockage des données. Cela à deux reprises, avant et après l’exécution de l’algorithme algoHGWFstSIMD.

Algorithme 8.4 : algoHGWSndSIMD, Algorithme SIMD de van Herk-Gil-Werman pour les seg- ments suivant la direction de la deuxième coordonnée (Snd) et en supposant que l’axe de stockage des données dans la mémoire est "Snd"

1 algoHGWSndSIMD :: I → I → I → BroderFnc → (α → α → α) → Ar ( I , I ) α → Ar ( I , I ) α 2 algoHGWSndSIMD mbsize n k brdfnc f ar = 3 (trRot2DMBSIMD "TD" "Snd" mbsize ) 4 ◦ (algoHGWFstSIMD n k brdfnc f ) 5 ◦ (trRot2DMBSIMD "TD" "Snd" mbsize ) 6 $ ar 8.3 Résultats expérimentaux

Nous avons implémenté la version SIMD de l’algorithme de van Herk-Gil-Werman à l’aide des templates du langage C++, fournis avec le compilateur Intel ICL que nous avons utilisé pour cette im- plémentation. Pour pouvoir illustrer ses performances sur une architecture grand public, nous avons effectué d’autres tests qui ont une valeur informative car leurs temps d’exécution sont de loin moindres. La table 8.1 mentionne les résultats en chiffres. L’implémentation SIMD y est mentionnée en tant que C++ template SSE2.

Nous avons testé l’implémentation itérative, cf. la section 8.1, page 166, qui utilise à l’interne, comme l’algorithme de base pour les itérations, une implémentation optimisée manuellement au niveau d’ins- tructions d’assembleur pour l’architecture Intel IA-32 qui exploitait l’exécution SIMD à l’échelle des registres 32 bits.

Nous mentionnons également deux autres implémentations qui ont été écrites dans le langage C, sans avoir exploré les capacités SIMD. La première (mentionnée comme C non-SIMD* dans la tab. 8.1) a suivi directement la définition, utilisait abondamment les structures if-else dans les tests de dépassement des bords, et correspond à une implémentation intuitive qu’un programmeur effectue si la performance de l’algorithme n’est pas sa priorité. Nous avons restructuré le code de cette implémentation dans une forme plus propre qui ne fait plus appel aux instructions spécifiques à l’architecture (mentionnée comme C non- SIMD**). Nous avons espéré que le compilateur pourrait, dans un tel code, procéder à la vectorisation de la même manière que nous l’avons exposée dans l’algorithme 8.3, mais malgré le gain que nous avons obtenus et qui est dû à la restructuration de cette implémentation, le temps d’exéctution est plutôt décevant, surtout si on le compare avec les temps obtenu pour les implémentations C++ template SSE2 qui intègrent le travail SIMD dans la structure de l’algorithme.

Temps d’exécution en ms des algorithmes de la dilatation par segments

algorithme méthode type 1Taille du segment symétrique (1 ∼ 3 pixels)3 5 15 30 60 Itératif assembleur 32 bits HOR 1.486 3.893 5.791 13.00 21.96 36.85 Itératif assembleur 32 bits VER 3.256 8.596 10.31 31.18 52.35 91.84

HGW C non-SIMD* HOR — — 31 — — —

HGW C non-SIMD** HOR — — 6.1 — — —

HGW C++ template SSE2 HOR 0.626 0.625 0.622 0.602 0.602 0.592 HGW C++ template SSE2 VER 0.334 0.331 0.313 0.276 0.261 0.260

Légende : HOR = segment horizontal, VER = segment vertical ; L’implémentation assembleur 32 bits est program- mée en assembleur et utilise directement les instructions 32 bits de l’architecture Intel IA-32 ; l’implémentation C non-SIMD*selon la définition mathématique, utilise abondamment les constructions if-else ; l’implémentation C non-SIMD**est la plus optimisée possible en C et à la main sans utiliser les types vectoriels. L’implémentation C++ template SSE2utilise les classes fournies avec le compilateur Intel ICL pour le calcul vectoriel. L’image d’entrée/sortie : 768 × 576 × 8 bits = 432 ko ; processeur Intel Pentium 4 à 2.4 GHz, mémoire cache L2 = 512 ko ; système d’exploitation Microsoft Windows XP ; compilateur Intel ICL 7.1 pour Windows.

TAB. 8.1 : Résultats expérimentaux de diverses implémentations de la dilatation par segments

Le graphe présentant les temps d’exécution dépendant de la taille du segment pour l’implémentation itérative, cf. la fig. 8.7(a), a tout-à-fait la forme attendue sachant que la complexité de cet algorithme pour une image donnée est de O(K), où K est le nombre de voisins traités par pixel. Les temps d’exécution grandissent avec la taille de l’élément structurant linéairement.

Nous présentons cette courbe comme contre-exemple pour démontrer qu’il est possible de calculer les dilatations / érosions beaucoup plus rapidement et surtout, avec un algorithme ayant la complexité O(1), où le temps du calcul ne dépend pas du nombre des voisins traités par pixel, q.v. la fig. 8.7(b). Il s’agit de l’implémentation SIMD de l’algorithme de van Herk-Gil-Werman, cf. les définitions de la fonction algoHGWFstSIMD (l’algorithme 8.4) et de la fonction algoHGWSndSIMD (l’algorithme 8.4). L’écart entre les deux courbes dans la fig. 8.7(b) qui est d’une valeur constante n’est pas surpre- nant car nous savons comment nous avons construit ces deux implémentations. Cet écart correspond, en effet, à 2 exécutions de la transposition par diagonale de l’image entière. Un phénomène plus intéres- sant présenté par les mêmes données est celui de la baisse du temps du calcul avec la taille du segment grandissant qui est, au premier regard, paradoxal.

Au début, nous avons jugé que cette baisse était due aux optimisations que le compilateur peut effectuer dans le code de boucles lors de l’exécution de la phase p1et p2à l’échelle des macro blocs. Mais

l’explication est, en fait, plus simple. Il s’agirait d’un phénomène dû à la gestion des boucles car pour les tailles grandissantes des segments, nous obtenons moins de macro blocs et par conséquent, moins de boucles. Ce phénomène est présent également dans les implémentations non-SIMD de l’algorithme de van Herk et même dans d’autres, nous renvoyons le lecteur aux articlesDB05et aux publicationsDD06qui

0 10 20 30 40 50 60 70 80 90 100 0 10 20 30 40 50 60 temps / ms

taille de l’élémént structurant (1 = 3 pixels)

itératif, asm32, horizontal itératif, asm32, vertical

(a)Algorithme itératif

0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0 10 20 30 40 50 60 temps / ms

taille de l’élémént structurant (1 = 3 pixels)

VanHerk, SSE2, horizontal vanHerk, SSE2, vertical

(b)Algorithme SIMD de van Herk-Gil-Werman pour Intel SSE2

FIG. 8.7 : Les temps du calcul des implémentations de la dilatation / érosion par un segment pour une image

8.4 Récapitulation

Ce chapitre a été consacré à l’explication des principes de la construction des algorithmes SIMD de la dilatation / érosion par les segments. Nous avons présenté le cas spécifique de l’implémentation de l’algorithme de van Herk-Gil-Werman pour les éléments structurants de la forme des segments ho- rizontaux et verticaux. Cet algorithme nous a également servi dans cette thèse comme exemple d’un algorithme complexe qui réutilise toutes les techniques de travail avec les vecteurs paquetés présentées dans les chapitre précédents, notamment la gestion de la dépendance de l’exécution sur le parcours lors de la propagation des valeurs, l’exploitation de la non-dépendance de l’exécution sur le sens du par- cours à l’échelle des macro blocs et, enfin, l’utilisation de la transposition par diagonale afin d’assurer le changement de l’axe de stockage des données.

Ces principes peuvent être réutilisés dans d’autres implémentations des algorithmes de ce type. Nous pensons, en particulier, aux implémentations sur la grille hexagonale, à l’implémentation de l’algorithme de van Herk-Gil-Werman avec la transposition directe par macro blocs et à l’implémentation SIMD des dilatations / érosions pour les segments inclinés qui n’est pas triviale car elle devrait gérer l’appartenance des données utilisées dans l’algorithme HGW à plusieurs macro blocs dédiés à la transposition. L’emploi de ces techniques dans les algorithmes pour les ouvertures et fermetures rapides par les segments est également à envisager.

Algorithmes et complexité

9.1 Définition d’un algorithme

Dans le contexte moderne, les algorithmes sont les méthodes pour la résolution des problèmes sur les ordinateurs. Dans le contexte plus large que celui restreint à l’informatique, nous comprenons sous le terme algorithme une prescription qui peut avoir différentes formes (textuelle, d’une formule mathéma- tique, d’un diagramme de séquence, d’un langage de programmation, etc.). Cette prescription décrit une méthode de résolution d’un problème qui, après être effectuée, nous fournit la solution du problème.

L’utilisation des algorithmes n’est pas un phénomène de l’époque des ordinateurs et du calcul auto- matique. Les algorithmes ont été connus et employés depuis bien longtemps et cette utilisation remonte, d’aprèsWik06aDonald Knuth, à travers l’Antiquité jusqu’au Babyloniens (1800 avant J.C). En revanche,

l’origine du mot algorithme est plus récent (9ème siècle) ; il a ses racines dans la traduction latine da- tant du Moyen Âge du nom de Abou Jafar Muhammad Ibn Musa al-KhuwarizmiWik06a où son nom

al-Khuwarizmi1était traduit en Algoritmi.

Par curiosité, nous pouvons découvrirWik06bégalement que le titre Al-jabr wa’l-muqabalah d’un des

ouvrages d’al-Khuwarizmi (publié en 825) qui signifie La transposition et la réduction est à l’origine d’un autre mot que l’on utilise fréquemment de nos jours – algèbre. Plus précisément, c’est sa partie Al-jabr qui après la traduction latine puis la traduction française devint algèbre et désigne aujourd’hui une discipline de la mathématique moderne dont certaines techniques sont déjà décrites dans l’ouvrage concerné d’al-Khuwarizmi.