Université d’Oran
Faculté des Sciences
Département D’Informatique
Diplôme de Magister
par
Examinateurs :
Mr Y. Lebbah (Professeur, Université d’Oran)
Mr A. Benyamina (MCA, Université d’Oran
i
Remerciements
Je tiens à remercier Dieu tout puissant qui m’a donné le courage et le soutien
pendant toutes mes années d’études.
Enfin, j’adresse mes plus sincères remerciements à tous mes proches et amis, qui
m’ont toujours soutenue et encouragée au cours de la réalisation de ce mémoire.
Résumé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1 Introduction générale 3
iii
SOMMAIRE iv
6 Expérimentation 68
6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.2 Environnement d’exécution . . . . . . . . . . . . . . . . . . . . . 69
6.3 Résultats sur les différentes architectures . . . . . . . . . . . . 70
6.3.1 Résultats d’exécution de la version MPI -OpenMP-
CUDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
SOMMAIRE v
7 Conclusion 75
Bibliographie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Table des figures
vi
Liste des tableaux
vii
Liste d’algorithmes
viii
Listings
ix
LISTINGS 1
Résumé
Nous avons réalisé dans ce mémoire maintes versions d’implémentation d’un al-
gorithme de recherche tabou itérative en utilisant une panoplie d’architectures d’exé-
cution pour mettre en évidence l’avantage des GPU par rapport aux architectures
classiques.
Abstract
To resolve this problem, we refer to COP resolving methods divided into two big
categories : Exact and approximate methods. We will focus our works on the second
class and exactly in metaheuristics which aim to find good solutions in reasonable
time. We can cite tabu search and genetic algorithms.
Introduction générale
«
’est la démarche intellectuelle qui est au cœur de la science du
C xxie siècle. La combinatoire consiste à combiner des éléments
simples en séquences, en architecture, et à construire ainsi des systèmes
complexes. (. . . ) Les sciences de la combinatoire font appel à des for-
malismes particuliers, à des logiques spécifiques, particulières, adaptés.
Voilà la vie de la nouvelle science, par laquelle le développement semble
infini. »
C Allègle Dictionnaire amoureux de la science,2005.
3
CHAPITRE 1. INTRODUCTION GÉNÉRALE 4
Les méthodes exactes ont permis de trouver des solutions optimales pour des
problèmes de taille raisonnable. Malgré les progrès réalisés, comme le temps de calcul
nécessaire pour trouver une solution risque d’augmenter exponentiellement avec la
taille du problème, les méthodes exactes rencontrent généralement des difficultés
face aux applications de taille importante.
Les méthodes approchées constituent une alternative très intéressante pour trai-
ter les problèmes d’optimisation de grande taille si l’optimalité n’est pas primordiale.
En effet, ces méthodes sont utilisées depuis longtemps. On peut les classifier en deux :
les heuristiques (méthodes dédiées à un problème spécifique) et les méta-heuristiques
(plus générales).
Malgré leurs robustesses, ces méthodes sont soit puissantes en termes d’exploi-
tation du voisinage au détriment de l’intensification, soit le contraire et c’est qui a
poussé les scientifiques a penser à l’hybridation entre ces méthodes pour parer à ce
genre de problème.
Le Q3AP a été présenté par P. Hahn et al. [14]. La motivation principale a été
l’optimisation d’un schéma de retransmission sur réseau sans fil, en affectant des
symboles de modulation à des séquences binaires de taille fixe. Des erreurs de trans-
mission pouvant avoir lieu, les paquets erronés sont susceptibles d’être retransmis.
La diversité est une mesure de l’indépendance statistique entre une transmission et
les éventuelles retransmissions successives. Maximiser la diversité revient à réduire
4
CHAPITRE 1. INTRODUCTION GÉNÉRALE 5
la probabilité d’erreurs lors des retransmissions. Comme présenté par P. Hahn et al.
, lorsque l’on considère qu’une seule retransmission, ce problème revient à un QAP.
Le Q3AP correspond au cas de deux retransmissions.
Pour résoudre le Q3AP nous avons opté pour une exécution parallèle sur les
cartes graphiques NVidia 1 , celles-ci offrent un environnement adéquat pour ce genre
de situation. Et pour pousser le parallélisme au plus profond, on a opter pour une
implémentation sur architectures multi-cœurs et GPU en même temps.
Le problème d’affectation
quadratique à 3 dimension
(Q3AP)
Sommaire
2.1 Les problèmes d’optimisation combinatoire . . . . . . . . 7
2.2 Quelques exemples de problèmes d’optimisation com-
binatoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 Le problème d’affectation quadratique à 3 dimensions
Q3AP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.3.1 Définition du problème QAP . . . . . . . . . . . . . 10
2.3.2 Définition du problème Q3AP . . . . . . . . . . . . 11
6
2.1 Les problèmes d’optimisation combinatoire 7
Dans ce chapitre nous allons définir certains problèmes d’optimisation parmi les
plus connus de la littérature avec quelques concepts de base. Puis on passera a une
définition plus en moins détaillé du problème Q3AP.
7
2.2 Quelques exemples de problèmes d’optimisation combinatoire 8
9
2.3 Le problème d’affectation quadratique à 3 dimensions Q3AP 10
n−1
X n−1
X
min fij dπ(i)π(j) , (2.1)
π∈Πn
i=0 j=0
n−1
X n−1
X n−1
X
min fij dπ(i)π(j) + ciπ(i) , (2.2)
π∈Πn
i=0 j=0 i=0
n−1
X
xij = 1, j = 0, 1, .., n − 1; (2.4)
j=0
10
2.3 Le problème d’affectation quadratique à 3 dimensions Q3AP 11
t.q. :
n−1
X
xij = 1, i = 0, 1, .., n − 1; (2.7)
j=0
n−1
X
xij = 1, j = 0, 1, .., n − 1; (2.8)
j=0
Où
n−1
X n−1
X
u, w ∈ x≥0: xij = 1 pour j = 0, .., n − 1; xij = 1 pour i = 0, .., n − 1; .
i=0 j=0
(2.11)
11
2.3 Le problème d’affectation quadratique à 3 dimensions Q3AP 12
Si l’on pose uij wip = xijp et ukm wkq = xkmq , on obtiendrait la formulation équivalente
à 2.10 suivante :
n−1
X n−1
X n−1 n−1
X n−1
X n−1
X n−1
X n−1
X n−1
X X
min bijp xijp + cijpkmq xijp xkmq , (2.12)
i=0 j=0 p=0
i=0 j=0 p=0 k=0 m=0 q=0
k6=i m6=j q6=p
Où :
X = (xijl ) ∈ I ∩ J ∩ L, (2.13)
n−1
X n−1
X
I = {X = (xijl ) : xijl = 1, i = 0, 1, .., n − 1}; (2.15)
j=0 l=0
n−1
X n−1
X
J = {X = (xijl ) : xijl = 1, j = 0, 1, .., n − 1}; (2.16)
i=0 l=0
X n−1
n−1 X
L = {X = (xijl ) : xijl = 1, l = 0, 1, .., n − 1}; (2.17)
i=0 j=0
12
Chapitre 3
Sommaire
3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.2 Méthodes de résolution . . . . . . . . . . . . . . . . . . . . . 14
3.3 Méthodes exactes . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3.1 Méthode "Branch and Bound" (B & B) . . . . . . 15
3.3.2 Programmation dynamique . . . . . . . . . . . . . . 16
3.4 Les métaheuristiques . . . . . . . . . . . . . . . . . . . . . . . 16
3.4.1 Définitions . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.4.2 Métaheuristique à population de solution . . . . . 18
3.4.2.1 Les algorithmes évolutionnistes . . . . . . . . 18
3.4.2.2 Algorithmes génétiques . . . . . . . . . . . . . 18
3.4.2.3 Les colonies de fourmis . . . . . . . . . . . . . 20
3.4.2.4 Programmation évolutive . . . . . . . . . . . . 21
3.4.2.5 Stratégies d’évolution "SE" . . . . . . . . . . . 22
3.4.3 Métaheuristique à solution unique . . . . . . . . . 22
3.4.3.1 Recherche aléatoire (RS) . . . . . . . . . . . . 22
3.4.3.2 Recherche Locale (LS) . . . . . . . . . . . . . 22
3.4.3.3 Recuit Simulé (SA) . . . . . . . . . . . . . . . 23
3.4.3.4 Recherche Tabou TS . . . . . . . . . . . . . . 24
3.4.3.5 Recherche Locale Itérée (Iterated Local Search) 25
3.5 Métaheuristiques hybrides . . . . . . . . . . . . . . . . . . . 27
3.6 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
13
3.1 Introduction 14
3.1 Introduction
Ce chapitre est organisé comme suit : La section 3.3 cite quelques méthodes
exactes les plus connus dans la littérature.
On parlera d’une hybridation de ces méthodes dans la section 3.5 puis on clôtu-
rera le chapitre par une conclusion.
Les métaheuristiques constituent une autre partie importante des méthodes ap-
prochées et ouvrent des voies très intéressantes en matière de conception de méthodes
heuristiques pour l’optimisation combinatoire.
14
3.3 Méthodes exactes 15
Méthodes de
résolution
Méthodes Méthodes
Exactes Approchées
B& Programmation
A∗
X dynamique
Métaheuristiques Heuristiques
Solution Population
unique de solution
Les méthodes exactes reposent sur l’utilisation d’algorithmes qui mènent de façon
sûre vers la solution optimale. Le principe essentiel de ces méthodes est d’énumé-
rer de manière implicite l’ensemble des solutions de l’espace de recherche. Malgré
l’important temps de calcul que nécessitent, généralement, ces approches, plusieurs
méthodes ont été développées.
15
3.4 Les métaheuristiques 16
Elle a été désignée par ce terme pour la première fois dans les années 1940 par
Richard Bellman. Elle s’applique à des problèmes d’optimisation dont la fonction
objectif se décrit comme « la somme de fonctions monotones croissantes des res-
sources ».
Elle a d’emblée connu un grand succès, car la plupart des fonctions économiques
de l’industrie étaient de ce type : maximisation du tonnage de charbon (ou de barils
de pétrole) produit à partir de plusieurs puits à budget donné, par exemple.
Les méthodes d’optimisation sont des algorithmes évaluant des solutions asso-
ciées à des problèmes bien déterminés soit de manière complète ou partielle.
Parmi les différentes méthodes d’optimisation, nous allons uniquement nous in-
téresser aux métaheuristiques.
1. Inférieure dans le cas d’une minimisation, Supérieure dans le cas d’une maximisation.
16
3.4 Les métaheuristiques 17
Le but des métaheuristiques est similaire à celui des heuristiques : obtenir des
solutions de bonne qualité en un temps raisonnable. Cependant, contrairement à
une heuristique, l’algorithme et l’emploi d’une métaheuristique est totalement indé-
pendants du problème à traiter.
3.4.1 Définitions
Les métaheuristiques sont apparues au début des années 1980 avec une ambition
commune : résoudre au mieux les problèmes dits d’optimisation difficile. En effet,
celles-ci s’appliquent à toutes sortes de problèmes discrets, et elles peuvent s’adapter
aussi aux problèmes continus.
N (x) = y ∈ S : dist(x, y) ≤
17
3.4 Les métaheuristiques 18
produisent une nouvelle solution, à travers les opérateurs génétiques, tels que le croi-
sement et la mutation. La nouvelle population, obtenue par le choix de N individus
parmi les populations parent et enfant, est appelée génération suivante [13].
Initialement proposé par Marco Dorigo] et al [6]. dans les années 1990, pour
la recherche de chemins optimaux dans un graphe, le premier algorithme s’inspire du
comportement des fourmis recherchant un chemin entre leur colonie et une source de
nourriture. L’idée originale s’est depuis diversifiée pour résoudre une classe plus large
de problèmes et plusieurs algorithmes ont vu le jour, s’inspirant de divers aspects
du comportement des fourmis.
Des biologistes ont ainsi observé, dans une série d’expériences menées à partir de
1989, qu’une colonie de fourmis ayant le choix entre deux chemins d’inégale longueur
menant à une source de nourriture, avait tendance à utiliser le chemin le plus court.
Un modèle expliquant ce comportement est le suivant :
1. Une fourmi (appelée « éclaireuse ») parcourt plus ou moins au hasard l’envi-
ronnement autour de la colonie ;
2. si celle-ci découvre une source de nourriture, elle rentre plus ou moins direc-
tement au nid, en laissant sur son chemin une piste de phéromones ;
3. ces phéromones étant attractives, les fourmis passant à proximité vont avoir
tendance à suivre, de façon plus ou moins directe, cette piste ;
4. en revenant au nid, ces mêmes fourmis vont renforcer la piste ;
20
3.4 Les métaheuristiques 21
5. si deux pistes sont possibles pour atteindre la même source de nourriture, celle
étant la plus courte sera, dans le même temps, parcourue par plus de fourmis
que la longue piste ;
6. la piste courte sera donc de plus en plus renforcée, et donc de plus en plus
attractive ;
7. la longue piste, elle, finira par disparaître, les phéromones étant volatiles ;
8. à terme, l’ensemble des fourmis a donc déterminé et " choisi " la piste la plus
courte.
sortie de l’automate est mesurée par rapport au résultat déjà connu. Cette mesure
constitue l’adaptation de l’individu. L’étape suivante consiste à créer, pour chaque
individu, un individu enfant par une mutation aléatoire de l’individu parent. La
mutation est assurée par une des 5 opérations suivantes : changer le symbole d’une
sortie, changer un état de transition, ajouter ou supprimer un état et changer l’état
initial.
Les stratégies d’évolution inventés par Rechenberg 1973, sont conçues dès le dé-
part pour résoudre des problèmes d’optimisation continus. Dans un algorithme SE,
les individus sont des points (vecteurs de réels). Comme la programmation évolutive,
les SE n’utilisent que la mutation et la sélection.
C’est la plus simple des méthodes stochastiques. Cette méthode consiste à tirer
à chaque itération une solution au hasard [39]. La fonction objectif f est évaluée en
ce point. La nouvelle valeur est comparée à la précédente. Si elle est meilleure que
la précédente, cette valeur est enregistrée, ainsi que la solution correspondante, et le
processus continu. Sinon on repart du point précédent et on recommence le procédé,
jusqu’à ce que les conditions d’arrêt soient atteintes. L’algorithme 1 est présenté
ci-dessous dans le cas d’un problème de minimisation.
La recherche locale "Local Search" est la plus ancienne des méthodes de réso-
lution. Elle démarre avec une solution initiale, et à chaque itération elle remplace
22
3.4 Les métaheuristiques 23
Cette méthode est issue d’une analogie entre le phénomène physique de refroi-
dissement lent d’un corps en fusion, qui le conduit à un état solide, de basse énergie.
Il faut abaisser lentement la température, en marquant des paliers suffisamment
longs pour que le corps atteigne l’équilibre thermodynamique à chaque palier de
température [24]. Pour les matériaux, cette basse énergie se manifeste par l’obtention
d’une structure régulière, comme dans les cristaux et l’acier.
L’analogie exploitée par le recuit simulé consiste à considérer une fonction f à
minimiser comme fonction d’énergie, et une solution s peut être considérée comme
23
3.4 Les métaheuristiques 24
un état donné de la matière dont f (s) est l’énergie. Le recuit simulé se démarre
par une solution initiale s qui peut être prise d’une manière aléatoire dans l’espace
de recherche. A cette solution correspond une énergie initiale f (s). Une tempéra-
ture initiale T élevée est également choisis. A chaque itération de l’algorithme une
modification de la solution est effectuée. Cette modification entraîne une variation
∆ de l’énergie du système. Si cette variation est négative (c’est-à-dire qu’elle fait
baisser l’énergie du système), elle est appliquée à la solution courante. Sinon, elle est
acceptée avec une probabilité e∆/T . Ce choix de l’exponentielle pour la probabilité
s’appelle règle de Metropolis. On itère ensuite selon ce procédé en gardant la tempé-
rature constante. L’algorithme Recuit Simulé est présenté ci-dessous (algorithme 3).
L’algorithme de la recherche tabou a été proposé par Glover [12] en 1986. Dans
les années 1990, elle est devenu très populaire dans la résolution de problèmes d’op-
timisation d’une manière approximative.
Aujourd’hui, elle est l’une des plus répandus métaheuristiques à solution unique.
L’utilisation de la mémoire, qui stocke les informations relatives au processus de
recherche, représente la caractéristique la plus particulière de cette recherche.
"TS" agit comme un algorithme de recherche locale mais accepte des solutions non
améliorantes pour échapper des optimums locaux quand tous les solutions voisines
ne sont pas améliorantes.
24
3.4 Les métaheuristiques 25
TS gère une mémoire de solutions récemment visitées appelées Liste tabou. Cette
liste constitue la mémoire à court terme de la méthode, elle est mise à jour à chaque
itération. Sauvegardant tous les mouvements est couteux en temps et en espace
mémoire. En effet, on vérifie à chaque itération si une solution appartient ou non
à l’ensemble des solutions visitées. La liste tabou contient un nombre constant de
mouvements tabous, au fait c’est les attributs de ces mouvements qui sont sauve-
gardés.
La qualité d’un optimum local obtenu par une recherche locale dépend de la
solution initiale choisie.
Dans une recherche locale multistart, la solution initiale est choisie aléatoirement
et est donc sans rapport avec l’optimum local. ILS améliore les recherches locales
25
3.4 Les métaheuristiques 26
recherche.
– Critère d’acceptation : des conditions sur lesquels on accepte ou non la
solution générée.
L’hybridation est une tendance observée dans de nombreux travaux réalisés sur
les métaheuristiques ces dernières années. Elle permet de tirer profit des avantages
cumulés des différentes métaheuristiques, à tel point que les métaheuristiques que
nous avons vues jusqu’à présent ne sont plus que des canevas, des points de départ,
pour commencer à résoudre un problème d’optimisation.
27
3.6 Conclusion 28
recherche sur les architectures parallèles. Toutes les métaheuristiques classiques ont
fait l’objet d’une implémentation parallèle, y compris l’algorithme du recuit simulé
qui, bien que de nature séquentielle, a pu être parallélisé en le divisant en processus
élémentaires.
Enfin une troisième forme d’hybridation combine les métaheuristiques avec des
méthodes exactes. Une méthode exacte peut ainsi donner lieu à une technique effi-
cace pour la détermination du meilleur voisin d’une solution (ce qui peut s’avérer
plus judicieux que de choisir la meilleure solution parmi un petit échantillon de voi-
sins). Dans le domaine de la programmation par contraintes, certaines techniques
de retour-arrière non déterministes (backtracking) ont été associées à des métaheu-
ristiques.
3.6 Conclusion
Les méthodes exactes donnent les meilleurs résultats qui soit en terme de qualité
de solution pour les problèmes d’optimisation combinatoire au détriment des temps
d’exécution.
Face à un problème de taille importante, on est obligé de passé par les heuris-
tiques (pour un problème spécifique) ou les métaheurostiques (plus généralement)
pour gagner du temps d’exécution et parfois de combiner les deux approches (exactes
et heuristiques) ou deux métaheuristiques pour tirer profit des avantages des deux.
Cette hybridation devient une tendance dans la résolution des problèmes d’op-
timisation combinatoire ces dernières années.
28
Chapitre 4
Sommaire
4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.2 Les architectures parallèles et multi-cœurs . . . . . . . . . 30
4.2.1 Classification des architectures . . . . . . . . . . . . 30
4.2.2 Architectures multi-cœurs . . . . . . . . . . . . . . . 33
4.3 Modèle de programmation parallèle . . . . . . . . . . . . . 33
4.3.1 OpenMP . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.3.2 Message Passing Interface (MPI ) . . . . . . . . . . 36
4.4 Les accélérateurs Graphiques GPU s . . . . . . . . . . . . . 38
4.4.1 Le GPGPU . . . . . . . . . . . . . . . . . . . . . . . . 39
4.5 BrookGPU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.6 OpenCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.7 CUDA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.7.1 Contexte . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.7.2 Modèle de programmation CUDA . . . . . . . . . . 43
4.7.3 Parallélisme de donnée . . . . . . . . . . . . . . . . . 43
4.7.4 Structure d’un programme CUDA . . . . . . . . . 44
4.7.5 Mémoires périphériques et transfert de données 45
4.7.6 Les kernels et les threads . . . . . . . . . . . . . . . 46
4.7.7 Exemple d’un programme CUDA . . . . . . . . . . 48
4.8 conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
29
4.1 Introduction 30
4.1 Introduction
Le monde de l’informatique est un monde très dynamique dans le sens où, nous
rencontrons tous les jours un nombre de technologies récentes. Face a cette avancée
technologique, les concepteurs de logiciels sont obligés à fournir un effort pour s’ali-
gner avec les outils disponibles. De ce fait les architectures parallèles deviennent de
plus en plus accessible au grand public.
Les ordinateurs parallèles sont des machines qui comportent une architecture
parallèle, constituée de plusieurs processeurs identiques, ou non, qui concourent au
traitement d’une application. La performance d’une architecture parallèle est la
combinaison des performances de ses ressources et de leur agencement. (latence,
débit).
La classification la plus connue est celle de [9] flynn 1966, qui classifie les
architectures selon les flux de données (Single ou Multiple) et de contrôle (Single ou
Multiple).
• Machines SISD :
Une machine SISD (Single Instruction /Single Data) correspond concrètement à
30
4.2 Les architectures parallèles et multi-cœurs 31
• Machines SIMD :
Dans le modèle SIMD (Single Instruction stream, Multiple Data stream), on ré-
plique les unités de traitement pour effectuer exactement la même opération au
même moment sur des données différentes. Toutes les opérations parallèles d’une
PU
Instruction Pool
PU
PU
PU
• Machines MIMD :
Le cas des machines MIMD (Multiple Instruction /Multiple Data) est la classe la
plus générale et la plus intuitive. Il y a N processeurs, N flots d’instructions et
N flots de données. Ces machines ont un nombre de processeurs qui fonctionnent
de manière asynchrone et indépendante. A tout moment, différents processeurs
peuvent exécuter différentes instructions sur différentes données. Les machines
MIMD ainsi que SIMD sont appropriées aux techniques de parallélisme de don-
nées. Elles sont utilisées dans différents domaines d’applications tels que la concep-
tion assistée, la simulation et la modélisation.
32
4.3 Modèle de programmation parallèle 33
33
4.3 Modèle de programmation parallèle 34
4.3.1 OpenMP
34
4.3 Modèle de programmation parallèle 35
OpenMP est basé sur l’existence de plusieurs threads dans le paradigme de pro-
grammation à mémoire partagée. Un processus de mémoire partagée se compose de
plusieurs threads, c’est un modèle de programmation explicite (non automatique),
offrant au programmeur un contrôle total sur la parallélisation [28].
Les directives OpenMP sont sensibles à la casse. Ils respectent les formats suivant
4.2.
35
4.3 Modèle de programmation parallèle 36
MPI pour Message Passing Interface [30], conçue en 1993-94, est une norme
définissant une bibliothèque de fonctions, utilisable avec les langages C et Fortran.
Elle permet d’exploiter des ordinateurs distants ou multiprocesseurs par passage
de messages. MPI a été écrite pour obtenir de bonnes performances aussi bien
sur des machines massivement parallèles à mémoire partagée que sur des clusters
d’ordinateurs hétérogènes à mémoire distribuée [32]. Elle est disponible sur de très
nombreux matériels et systèmes d’exploitation. Ainsi, MPI possède l’avantage par
rapport aux plus vieilles bibliothèques de passage de messages d’être grandement
portable (car MPI a été implantée sur presque toutes les architectures de mémoires)
et rapide (car chaque implantation a été optimisée pour le matériel sur lequel il
s’exécute).
Son but est de spécifier une bibliothèque de fonctions de passage de messages
portable. Il se base sur un environnement d’exécution qui lance les processus et les
connecte entre eux. MPI supporte des modes de communication synchrones et asyn-
chrones et des communications collectives et offre des domaines de communication
séparés.
MPI est une librairie, pas un langage, c’est une spécification de librairie proposée
comme une norme pour une large population de vendeurs, développeurs et utilisa-
teurs. Il spécifie les noms, séquencement d’un appel et les résultats des fonctions
sous C, C++ et Fortran, et décrit ce qu’il faut faire mais pas comment faire.
Ce mode de programmation est connu sous le nom de : SPMD i.e. « Single Pro-
gramm Multiple Data » il consiste à lancer plusieurs processus sur une ou plusieurs
machines où chaque processus à ses propres variables locales. le partage de données
se fait par passage de message qui peut être :
i- Point à point (un à un) ;
ii- Collection de données (plusieurs à un) ;
iii- Broadcast (un à plusieurs).
36
4.3 Modèle de programmation parallèle 37
37
4.4 Les accélérateurs Graphiques GPU s 38
#i n c l u d e <s t d i o . h>
#i n c l u d e <mpi . h>
38
4.4 Les accélérateurs Graphiques GPU s 39
entre en concurrence directe avec son comparse et s’immisce dans l’industrie des
super-ordinateurs.
Généralement, le GPU est embarqué sur une carte dite graphique, mais il se
trouve de plus en plus intégré au chipset des cartes mères.
4.4.1 Le GPGPU
Alors que les CPU s sont performants dans l’exécution de tâches diverses et
variées les unes à la suite des autres (faible parallélisme) les GPU sont quant à
eux performants dans l’exécution de nombreuses tâches simples simultanées (fort
parallélisme).
39
4.4 Les accélérateurs Graphiques GPU s 40
graphiques des GPU augmentent plus rapidement que celles des CPU. Ceci n’est
bien évidemment pas dû à la capacité de semi-conducteurs, qui augmente au même
rythme pour les deux plates-formes (et qui est étroitement liée aux progrès de la
technologie de fabrication). La différence est par contre dûe aux architectures de
ces deux types de processeurs, qu’on a brièvement décrites plus haut. Pour être plus
précis en ce qui concerne les processeurs graphiques, les GPU modernes adoptent un
40
4.5 BrookGPU 41
4.5 BrookGPU
4.6 OpenCL
OpenCL [23] est une combinaison d’une API et d’une extension du langage C.
Initialement conçu par Apple, puis affiné en partenariat avec AMD, Intel, et NVIDIA
- tous membres du Khronos Group - , OpenCL se présente aussi comme un standard
ouvert. Il s’agit d’un outil relativement récent. Le principe diffère un peu de Brook.
Tout d’abord, on pourra remarquer une ressemblance frappante, dans l’architecture
du code, avec l’utilisation d’un driver en C (création du device, puis création d’un
contexte . . . ). Cela s’explique du fait qu’OpenCL n’est pas destiné uniquement à
l’utilisation de la carte graphique, mais plutôt comme un outil généraliste permet-
tant de choisir son unité de calcul (le GPU , mais aussi le CPU ). On pourra aussi
remarquer que c’est dans l’instance du programme que l’on transmet le code à exé-
cuter sur le matériel choisi, le GPU dans notre cas. Le code n’est pas directement
intégré dans le programme.
4.7 CUDA
CUDA [25] est une architecture de traitement parallèle développée par NVI-
DIA permettant de décupler les performances de calcul du système en exploitant la
41
4.7 CUDA 42
Alors que plus de 128 millions de GPU compatibles avec CUDA ont déjà été
vendus, des milliers de développeurs de logiciels, de scientifiques et de chercheurs
utilisent CUDA dans une grande gamme de domaines [18], incluant notamment la
production vidéo, l’astrophysique, la chimie et la biologie par modélisation numé-
rique, la mécanique des fluides numérique, les interférences électromagnétiques, la
reconstruction tomodensitométrique, l’analyse sismique, le ray tracing et bien plus
encore.
4.7.1 Contexte
42
4.7 CUDA 43
banquier) et figurant dans la liste des « 500 entreprises les plus importantes au
monde » publiée par Fortune, ont adopté CUDA.
Par exemple, pour des multiplications de matrices de taille 1000 × 1000, il s’agit
de 1000000 de multiplications, sans rapport les unes avec les autres, qui peuvent donc
être parallélisées sans problème. Un GPU peut fortement améliorer les performances
en exécutant toutes ces opérations simultanément.
43
4.7 CUDA 44
Dans CUDA, l’hôte et les périphériques ont des espaces mémoires séparés. Cela
reflète le fait que les dispositifs sont généralement des cartes matérielles qui viennent
avec leur propre Mémoire à accès aléatoire dynamique (DRAM). Afin d’exécuter
un kernel sur un périphérique, le programmeur doit allouer de la mémoire sur le
périphérique et transférer les données pertinentes de la mémoire hôte vers celle du
périphérique. De même, après l’exécution au niveau du périphérique, le programmeur
doit transférer les données résultat à partir de celui-ci à l’hôte et de libérer la mémoire
du périphérique qui n’est plus nécessaire. Le CUDA runtime fournit des appels
de fonctions dites "Application Programming Interface" (API) pour effectuer ces
transferts. La figure 4.7.5 présente une vue d’ensemble du modèle de mémoire du
grâce aux fonctions API CUDA pour le transfert des données entre les mémoires. La
fonction cudaMemcpy() nécessite quatre paramètres. Le premier est un pointeur vers
l’objet source de données à copier. Le second pointe l’emplacement de destination
pour l’opération de copie. Le troisième indique le nombre d’octets à copier. Tandis
que le quatrième paramètre indique les types de mémoire impliqués dans la copie :
de la mémoire de hôte vers la mémoire hôte, de la mémoire hôte vers la mémoire
périphérique, de la mémoire périphérique vers la mémoire hôte, et finalement de la
mémoire périphérique vers la mémoire périphérique.
cudaMemcpy (Md, M, s i z e , cudaMemcpyHostToDevice ) ;
Quand un kernel est invoquée, ou lancé, il est exécuté en tant que grille de
threads parallèles. Dans la figure 4.7.6, le lancement du Kernel 1 crée la grille 1.
Chaque grille CUDA comprend typiquement des milliers ou des millions de légers
threads GPU par appel kernel. Créer suffisamment de threads pour utiliser pleine-
ment le matériel nécessite souvent une grande quantité de parallélisme de données,
par exemple chaque élément d’un tableau de grande taille peut être calculé dans un
thread séparé.
Les threads dans une grille sont organisés en une hiérarchie à deux niveaux,
comme illustré à la figure 4.7.6. En réalité, une grille contient de nombreux threads
. Au niveau haut, chaque grille est constitué d’un ou de plusieurs blocs de threads.
Tous les blocs dans une grille ont le même nombre de threads. Dans la figure 4.7.6,
la grille 1 se compose de 6 blocs de thread qui sont organisés dans un tableau 2 × 3 à
deux dimensions. Chaque bloc a un thread de deux coordonnées tridimensionnelles
donnés par le blockIdx.x et le blockIdx.y qui sont des mots-clés spécifiques CUDA.
Tous les blocs doivent posséder le même nombre de threads organisées de la même
manière. Chaque bloc est à son tour organisé comme un tableau en trois dimensions
46
4.7 CUDA 47
de threads avec une taille totale d’un maximum de 512 threads. Les coordonnées
de threads dans un bloc sont uniquement définie par : threadIdx.x, threadIdx.y, et
threadIdx.z.
Très simplement, un kernel est une fonction exécutée sur le GPU . Il en existe diffé-
rent types, qualifiés de :
1. __global __
2. __device__
3. __host__
Le premier correspond à un kernel exécuté sur le GPU mais appelé par le CPU ;
le deuxième, à un kernel exécuté et appelé par le GPU ; le troisième, à une fonction
exécutée et appelée par le CPU. Ce dernier n’est pas obligatoire :
c’est le mode de fonctionnement par défaut.
Un appel de kernel se fait en spécifiant 2 paramètres entre triples chevrons pré-
cédant les paramètres passés au kernel.
k e r n e l <<< nBlocs , t h r e a d s P a r B l o c >>> ( arguments ) ;
Voici un code source d’un programme typique CUDA. Il s’agit d’une addition
de deux vecteurs A et B de taille n dans un troisième vecteur C résultats. La grille
est sous-divisée en N blocs (tous de 1 dimension), l’index pourrait être trouvé de la
manière suivante4.5.
/∗ ∗ A d d i t i o n des v e c t e u r s A+B = C CUDA ∗ ∗/
#i n c l u d e <cuda . h>
#i n c l u d e <s t d i o . h>
#i n c l u d e <cuda_runtime . h>
const int N = 16;
const int blocksize = 16;
i n t main ( ) {
48
4.7 CUDA 49
f l o a t ∗a = new f l o a t [N ] ;
f l o a t ∗b = new f l o a t [N ] ;
f l o a t ∗ c = new f l o a t [N ] ;
f o r ( i n t i = 0 ; i < N; ++i ) {
a [ i ] = 1.0 f ; b [ i ] = 3.5 f ;
}
f l o a t ∗ad , ∗bd , ∗ cd ;
c o n s t i n t s i z e = N∗ s i z e o f ( f l o a t ) ;
cudaMalloc ( ( v o i d ∗∗)&ad , s i z e ) ; // A l l o c a t i o n de l a mémoire
d e v i c e pour l e v e c t e u r A
cudaMalloc ( ( v o i d ∗∗)&bd , s i z e ) ; // A l l o c a t i o n de l a mémoire
d e v i c e pour l e v e c t e u r B
cudaMalloc ( ( v o i d ∗∗)&cd , s i z e ) ; // A l l o c a t i o n de l a mémoire
d e v i c e pour l e v e c t e u r C
cudaMemcpy ( ad , a , s i z e , cudaMemcpyHostToDevice ) ; // c o p i e
du v e c t e u r A v e r s l e d e v i c e
cudaMemcpy ( bd , b , s i z e , cudaMemcpyHostToDevice ) ; // c o p i e
du v e c t e u r B v e r s l e d e v i c e
dim3 dimBlock ( b l o c k s i z e , 1 ) ; // nbr de t h r e a d s par b l o c k
dim3 dimGrid ( N/ dimBlock . x , 1 ) ; // nbr de b l o c k
add_vec<<<dimGrid , dimBlock>>>( ad , bd , cd , N ) ; // a d d i t i o n
au n i v e a u d e v i c e
cudaMemcpy ( c , cd , s i z e , cudaMemcpyDeviceToHost ) ; // c o p i e
du r é s u l t a t ( v e c t e u r C) du d e v i c e v e r s l e h o s t
/∗ A f f i c h a g e ∗/
f o r ( i n t i =0; i <N; i ++)
{
p r i n t f ( "%f \n " , c [ i ] ) ;
}
/∗ L i b e r a t i o n de l ’ e s p a c e mémoire s u r l e h o s t e t l e d e v i c e
∗/
49
4.8 conclusion 50
cudaFree ( ad ) ;
cudaFree ( bd ) ;
cudaFree ( cd ) ;
delete [ ] a ;
delete [ ] b;
delete [ ] c ;
r e t u r n EXIT_SUCCESS ;
}
4.8 conclusion
Tandis que MPI est désigné pour les architectures distribuées. C’est une norme
qui fait coordonner des processeurs distants par le passage de messages.
Une nouvelle voie vient de se tracer dans le domaine du parallélisme par l’avè-
nement de la technologie Nvidia et son architecture de traitement CUDA.
CUDA est une architecture de traitement parallèle définie pour l’exploitation des
cartes graphiques Nvidia pour des calculs autre que le traitement d’images.
50
Chapitre 5
Conception de la solution du
problème Q3AP
Sommaire
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.2 Méthode de résolution du Q3AP adoptée . . . . . . . . . 52
5.3 Solution du Q3AP et fonction d’évaluations . . . . . . . . 53
5.3.1 Solution du Q3AP . . . . . . . . . . . . . . . . . . . . 53
5.3.2 Fonction d’évaluation du Q3AP . . . . . . . . . . . 54
5.3.3 Fonction de voisinage . . . . . . . . . . . . . . . . . . 55
5.4 La nécessité du parallélisme . . . . . . . . . . . . . . . . . . 57
5.4.1 ILS-TS OpenMP . . . . . . . . . . . . . . . . . . . . . 57
5.4.2 ILS-TS-CUDA . . . . . . . . . . . . . . . . . . . . . . 59
5.4.3 ILS-TS-Multikernels . . . . . . . . . . . . . . . . . . 63
5.4.4 ILS-TS-multi GPU . . . . . . . . . . . . . . . . . . . 64
5.4.5 ILS-TS-MPI-cuda . . . . . . . . . . . . . . . . . . . . 64
5.4.6 ILS-TS-MPI-OpenMP-cuda . . . . . . . . . . . . . . 66
5.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
51
5.1 Introduction 52
5.1 Introduction
Dans ce chapitre nous allons parler des éléments qui constituent la solution au
problèmes d’optimisation traité (Q3AP), et de toutes les implémentations faites.
consiste à créer une solution aléatoire puis l’évaluer. Il applique sur elle une recherche
tabou (trouver le meilleur voisin et marquer le mouvement comme tabou) et donc
trouve un optimum local. Il perturbe celui-ci et il l’évalue. Ce processus est répétée
jusqu’à épuisement du nombre d’itération fixé au départ.
52
5.3 Solution du Q3AP et fonction d’évaluations 53
Nous optons pour une représentation directe des solutions du problème Q3AP
c - à - d une double permutation d’entiers de 0 à n − 1, n étant la taille du problème
à résoudre. Ces doubles permutations sont représentées par deux vecteurs de taille
variable comme montré au listing 5.1 suivant.
typedef struct {
i n t ∗ permut1 ;
i n t ∗ permut2 ;
} Solution ;
6 7 0 3 5 2 4 1
0 4 1 6 2 7 5 3
La création d’une solution initiale est simple, elle consiste à créer une solution aléa-
toire.
void c r e a t e ( Solution s o l u t i o n ) {
f o r ( i n t i = 0 ; i < Nd ; i ++){
s o l u t i o n . permut1 [ i ]= i ;
s o l u t i o n . permut2 [ i ]= i ;
}
f o r ( i n t i = 0 ; i < Nd ; i ++){
random = rand ( ) %(Nd−i ) + i ;
temp = s o l u t i o n . permut1 [ i ] ;
s o l u t i o n . permut1 [ i ] = s o l u t i o n . permut1 [ random ] ;
s o l u t i o n . permut1 [ random ] = temp ;
}
..
.
}
53
5.3 Solution du Q3AP et fonction d’évaluations 54
i n t f u l l E v a l ( c o n s t i n t ∗ P , c o n s t i n t ∗ W, c o n s t S o l u t i o n
solution ){
i n t j j , l l ,mm, nn ;
int fitnessValue = 0;
f o r ( i n t i i = 0 ; i i < Nd ; i i++ ) {
j j = s o l u t i o n . permut1 [ i i ] ;
l l = s o l u t i o n . permut2 [ i i ] ;
f i t n e s s V a l u e = f i t n e s s V a l u e + Cost (P , W , i i , jj , ll
, ii , jj , ll ) ;
f o r ( i n t kk = 0 ; kk < Nd ; kk++ ) {
i f ( kk != i i ) {
nn = s o l u t i o n . permut1 [ kk ] ;
mm = s o l u t i o n . permut2 [ kk ] ;
f i t n e s s V a l u e = f i t n e s s V a l u e + Cost (P , W , i i , jj , ll ,
kk , nn , mm) ;
}
}
}
return fitnessValue ;
}
i n t Cost ( c o n s t i n t ∗ P , c o n s t i n t ∗ W , i n t i , i n t j ,
i n t l , i n t k , i n t n , i n t m) ;
i n t MoveIncrEval ( c o n s t i n t ∗ A, c o n s t i n t ∗ B, c o n s t i n t ∗ S ,
int i , int j , int n , const int f i t n e s s ) ;
Les conditions d’arrêts des deux métaheuristiques sont les nombres d’itération
ILSmaxIter fixé à 100 et TSMAXITERS fixé à 3000 respectivement pour la recherche
itérée ILS et la recherche tabou TS.
55
5.3 Solution du Q3AP et fonction d’évaluations 56
Lire ins-
tance Q3AP
Générer
une solution
initiale S0
Evaluer f (s0 )
Bst sol
oui
Fin trouvée
/approché
Générer
oui et évaluer les
s0 ← si
(n×((n−1))/2)2
voisins de S0
Existe-t-il
Perturber
un voisin
l’optimum local
Si de S0
56
5.4 La nécessité du parallélisme 57
Par la suite, et pour mieux interpréter les résultats expérimentaux, nous avons
implémenter plusieurs versions de l’algorithme qui se ressemble algorithmiquement
parlant, et qui diffèrent au niveau de l’implémentation.
57
5.4 La nécessité du parallélisme 58
S0 S1 Sn
...
TS TS TS
...
Meilleure Solution
Perturbation
.
.
.
58
5.4 La nécessité du parallélisme 59
les critères d’arrêt à la fin de chaque ILS-TS et on choisie la meilleure solution parmi
les solution des processus. l’algorithme 5.6.
{
#pragma omp p a r a l l e l s h a r e d ( f i t _ t h r e a d s , P ,W) p r i v a t e (
new_fitness , solution , best_solution , f i n a l _ s o l u t i o n )
num_threads ( n b t h r e a d s )
{
..
.
create ( solution ) ;
/∗ e v a l u a t e th e s o l u t i o n ∗/
i n t b e s t _ f i t n e s s = f u l l E v a l (P ,W, s o l u t i o n ) ;
..
.
/∗ ILS s i m p l e p e r t u r b a t i o n
randomly s h u f f l e a c e r t a i n number o f p o s i t i o n s
i n t h e f i r s t permutation o r th e second permutation
∗/
..
.
#pragma omp c r i t i c a l
{
i f ( omp_get_thread_num ( ) ==0)
b e s t _ f i t n e s s=Minimum( f i t _ t h r e a d s ) ;
}
..
.
} // end o f p a r a l l e l r e g i o n pragma
5.4.2 ILS-TS-CUDA
Générer
une solution
initiale S0
Evaluer f (s0 )
Bst sol
oui
Fin trouvée
/approché
Générer
oui et évaluer les
s0 ← si Partie exécutée par GPU
(n×((n−1))/2)2
voisins de S0
Existe-t-il
Perturber
un voisin
l’optimum local
Si de S0
60
5.4 La nécessité du parallélisme 61
La difficulté réside dans la distribution des taches entre les différents threads du
GPU ,
{
__global__ v o i d MoveIncrEval ( c o n s t i n t ∗ P , c o n s t i n t ∗ W,
const Solution solution , int ∗ new_fitness )
{
v o l a t i l e i n t i d = b l o c k I d x . x ∗ blockDim . x + t h r e a d I d x . x ;
i f ( i d < Nd∗(Nd−1)∗Nd∗(Nd−1) /4 ) {
i n t move_first ;
i n t move_second ;
i n t move_third ;
i n t move_fourth ;
i n t temp , temp2 ;
temp = i d / (Nd∗(Nd−1) /2 ) ;
temp2 = i d % (Nd∗(Nd−1) /2 ) ;
m o v e _ f i r s t = (Nd−1) − f l o o r f ( ( ( s q r t f ( 8 ∗ ( ( Nd∗(Nd−1)
/ 2) − temp − 1 ) + 1 +0.1 f ) ) −1 ) / 2 ) − 1;
move_second = temp − m o v e _ f i r s t ∗ (Nd−1)+ m o v e _ f i r s t ∗ (
m o v e _ f i r s t + 1 ) /2 + 1 ;
move_third = (Nd−1) − f l o o r f ( ( ( s q r t f ( 8 ∗ ( ( Nd∗(Nd−1)
/ 2) − temp2 − 1 ) + 1 +0.1 f ) ) −1 ) / 2 ) − 1;
move_fourth = temp2 − move_third ∗ (Nd−1)+ move_third ∗
( move_third + 1 ) /2 + 1 ;
n e w _ f i t n e s s [ i d ] = compute_delta (P ,W, s o l u t i o n , move_second
, move_first , move_fourth , move_third ) ;
}
}
61
5.4 La nécessité du parallélisme 62
/∗ copy th e f i t n e s s e s s t r u c t u r e i . e . t he e v a l u a t e d
solutions
from GPU t o CPU ∗/
cudaMemcpy ( n e w _ f i t n e s s , new_fitness_d , s i z e o f ( i n t ) ∗Nd
∗(Nd−1)∗Nd∗(Nd−1) / 4 ,
cudaMemcpyDeviceToHost ) ;
MoveIncrEval<<<ceil(((Nd*(Nd-1)*Nd*(Nd-1)/4)*1.0)
/BLOCK_SIZE),BLOCK_SIZE>>>(new_fitness_d);
}
62
5.4 La nécessité du parallélisme 63
Ce qui signifie donc que chaque processus atteignant cette section critique bloquera
les autres processus d’où l’utilisation des versions multi-kernels et multi-GPU s sui-
vantes.
5.4.3 ILS-TS-Multikernels
Dans cette version, nous visons à combiner CUDA et OpenMP pour en profiter de
leurs avantages sans se faire pénalisé par le temps d’attente engendré par l’utilisation
de la section critique.
Pour ce faire, CUDA propose la notion de « stream » ou flux qui va contenir les
kernels à exécuter :
cudaStream_t ∗ stream ;
// a l l o c a t i o n c r e a t i o n de stream
stream = ( cudaStream_t ∗) m a l l o c ( n k e r n e l s ∗ s i z e o f (
cudaStream_t ) ) ;
f o r ( i n t i =0; i <n k e r n e l s ; i ++)
{
c u t i l S a f e C a l l ( cudaStreamCreate(& stream [ i ] ) ) ;
}
MoveIncrEval<<<ceil(((Nd*(Nd-1)*Nd*(Nd-1)/4)*1.0)
/BLOCK_SIZE),BLOCK_SIZE,0,stream[omp_get_thread_num()]>>>
(new_fitness_d+cp*nkernels);
Donc on passe au GPU les streams a exécuter comme paramètre pendant l’appel
du kernel.
63
5.4 La nécessité du parallélisme 64
Cette version vise à utiliser les différents GPU s disponibles présents dans une
machine en créant autant de processus OpenMP que de GPU . On commence par
trouver le nombre de GPU présent sur une machine et créer ensuite un nombre de
processus OpenMP correspondant :
i n t devID ; // i d d ’ un gpu
i n t deviceCount =0; // compteur de GPU;
cudaGetDeviceCount(& deviceCount ) ;
p r i n t f ( " l e nombre de GPUs e s t :%d\n " , deviceCount ) ;
cudaDeviceProp d e v i c e P r o p s ; // p r o p r i e t é d ’ un GPU
Et ensuite on spécifie le devID dans l’appel du kernel ppour l’affecter au GPU correspondant :
MoveIncrEval<<<ceil(((Nd*(Nd-1)*Nd*(Nd-1)/4)*1.0)
/BLOCK_SIZE),BLOCK_SIZE,omp_get_thread_num()>>>(new_fitness_d);
5.4.5 ILS-TS-MPI-cuda
65
5.4 La nécessité du parallélisme 66
/∗ copy th e f i t n e s s e s s t r u c t u r e i . e . t he e v a l u a t e d
solutions
from GPU t o CPU ∗/
cudaMemcpy ( n e w _ f i t n e s s , new_fitness_d , s i z e o f ( i n t ) ∗Nd
∗(Nd−1)∗Nd∗(Nd−1) / 4 ,
cudaMemcpyDeviceToHost ) ;
cudaThreadSynchronize ( ) ;
cutStopTimer ( timerILSTabuSearchGPU ) ;
cudaUnbindTexture ( texRefPd ) ;
cudaUnbindTexture ( texRefWd ) ;
cudaUnbindTexture ( t e x R e f S o l u t i o n d 1 ) ;
cudaUnbindTexture ( t e x R e f S o l u t i o n d 2 ) ;
cudaFree (Pd) ;
cudaFree (Wd) ;
cudaFree ( s o l u t i o n _ d . permut1 ) ;
cudaFree ( s o l u t i o n _ d . permut2 ) ;
cudaFree ( new_fitness_d ) ;
r e t u r n cutGetTimerValue ( timerILSTabuSearchGPU ) / 1 0 0 0 ;
}
gputime=run_kernel(P,W,solution,new_fitness);
5.4.6 ILS-TS-MPI-OpenMP-cuda
Pour exploiter tous les types de parallèlisme possible, on a visé à concevoir une
méthode qui exploite le parallélisme à mémoire distribué (MPI ), le parallélisme à
mémoire partagée (OpenMP) et le parallélisme de donnée sur GPU .
66
5.5 Conclusion 67
5.5 Conclusion
Le chapitre suivant intitulé " Expérimentation et résultats " sera consacré à cette
comparaison.
67
Chapitre 6
Expérimentation
Sommaire
6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.2 Environnement d’exécution . . . . . . . . . . . . . . . . . . 69
6.3 Résultats sur les différentes architectures . . . . . . . . . 70
6.3.1 Résultats d’exécution de la version MPI -OpenMP-
CUDA . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
6.4 Interprétation des résultats . . . . . . . . . . . . . . . . . . 71
6.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
68
6.1 Introduction 69
6.1 Introduction
Les expérimentations que nous avons menées par la suite avaient pour objectif
de prouver que les unités graphiques peuvent être un moyen efficace pour accélérer
la recherche itérative de solutions du Q3AP. La méthode de recherche locale implé-
mentée sur GPU , rappelons le, est une recherche tabu itérative. La recherche tabu
est réitérée plusieurs fois pour améliorer la qualité des optimas locaux. Le principe
de l’approche est de perturber l’optimum local trouvé par la recherche tabu et de
l’utiliser comme solution initiale pour la recherche tabu suivante. La perturbation
implémentée est une suite de µ, de permutations opérées dans la première ou dans
la seconde permutation, µ étant un nombre entier aléatoire dans l’intervalle [2, n]
(n est la taille de l’instance). La méthode a été déployée sur deux configurations
matérielles différentes. La prmière configuration est un ordinateur portable AMD
Turion 64 X2 Mobile TL-60 @ 2000MHz doté d’une carte graphique Nvidia GeForce
8400M GS et la seconde est un PC de bureau Intel Core 2 Duo E7200 @ 2.53GHZ
X2 doté d’une carte graphique Nvidia Quadro NVS 290. Le nombre d’itérations de
Config. 1 Config. 2
VGA Nvidia GeForce 8400M GS Nvidia Quadro NVS 290
GPU clock 0.80 Ghz 0.92 Ghz
Taille Mém. 256 MB 256 MB
Major/Minor 1.1 1.1
Cuda Cores 2 MP × 8 cuda cores/MP 2 MP × 8 cuda cores/MP
la recherche locale et celui de la recherche tabou ont été fixés respectivement à 100
m
et 3000. La taille de la liste tabou a été fixé à 4
. La méthode a été testé sur les
benchmarks nug8, nug12, nug13, nug15, nug18 et nug22 de la librairie QAPLIB [3]
Chaque instance e été exécuté 10 fois, les tableaux suivants servent comme com-
paraison entre les différentes versions implémentées et leurs impact sur le temps
d’exécution.
69
6.3 Résultats sur les différentes architectures 70
ILS-TS-CUDA
instance nug8 nug12 nug13 nug15 nug18 nug22
Opt/meill. val. 134 580 1912 2230 17836 42476
val. moyenne 134 688.4 2048.3 2488.33 18074 42745
Val. max. 134 776 2112 2544 18218 44116
Temps GPU (s) 1.48 11.27 19.15 46.07 68.28 234.21
Le tableau 6.3.1 suivant montre les résultats sur la version MPI -CUDA. Et la
version MPI -OpenMP-CUDAavec un nombre de thread variable (6.3.1).
70
6.4 Interprétation des résultats 71
ILS-TS-MPI -CUDA
instance nug8 nug12 nug13 nug15 nug18 nug22
val. moyenne 134 692.6 2033 2590.3 18210 46858
Val. max. 134 782 2112 2756 19147 48426
Temps GPU (s) 2.39 9.58 12.93 26.28 74.01 252.27
71
6.4 Interprétation des résultats 72
Voici quelques graphes illustrant la performance des différentes versions pour les
instances testés. On remarque que l’augmentation du nombre de threads (multi-
START avec OpenMP) produit une baisse de performance en terme de temps d’exé-
cution (due à la charge sur le bus PCI qui relie la vRam avec la RAM). Tandis que les
versions MPI et MPI-OpenMP sont plus meilleures. Pour l’instance nug8, la version
CUDA reste la plus performante. Mêmes remarques que le nug8 mais on note bien
qu’à partir de cette instance (nug12), la faveur reviens aux versions MPI-CUDA et
MPI-OpenMP-CUDA, cela revient à la minimisation significatif des transferts, dans
ces versions par rapport aux autres. L’instance nug15 montre une légère amélio-
ration dans la version OpenMP-CUDA 4 threads par rapport aux autres. Tandis
que l’instance nug12 suit le même schéma précédant. Ces graphes (nug18, nug22)
montrent bien, le rôle très important, que joue le multi-START dans les instances
de grandes tailles, et aussi l’amélioration très importante du temps d’exécution sur
le GPU.
72
6.5 Conclusion 73
6.5 Conclusion
73
6.5 Conclusion 74
74
Chapitre 7
Conclusion
Résoudre ce problème fait donc appel aux métaheuristiques. Nous avons penchés
vers les recherches locales et plus exactement à la recherche locale itérative.
D’après les résultats d’exécution que nous avons obtenus, nous avons constaté
que ces architectures sont un moyen de parallélisme fort en terme de parallélisme de
données.
Rien qu’avec une carte graphique Nvidia grand public, on a pu avoir de bon
résultats en terme de temps d’exécution par rapport aux exécution séquentielle.
En fin, le GPGPU est une solution de faible cout, à exploiter dans différents
domaines, scientifiques, mathématiques, et même médicale (étude de possibilité
d ?apparition des maladies héréditaires).
75
CHAPITRE 7. CONCLUSION 76
76
Bibliographie
77
BIBLIOGRAPHIE 78
79
Résumé
Mots clés :
Q3AP; QA; GPGPU; CUDA; GPU; Accélérateurs graphiques; Recherche tabou; Recherche
itérative; MPI; Open MP.