I. Introduction▲
Intel est un grand constructeur de processeurs qui ne cesse d'inventer des produits dont les performances croissent à une vitesse exponentielle. L'un de ses derniers bébé est l'Intel Core 2 Duo, qui montre une grande avancée dans le domaine du multi-core. La demande en matière de simulations 3D complexes, fichiers multimédias en continu, niveaux supplémentaires de sécurité, interfaces utilisateur plus sophistiquées, bases de données plus volumineuses et nombre plus important d'utilisateurs en ligne commence à dépasser les capacités des processeurs à cœur unique.
Mais à quoi cela sert d'avoir des processeurs tels processeurs le Core 2 Duo, Intel 64 bits, Intel Quad-Core, la technologie 65 nm, etc. si les programmes ne sont pas optimisés pour pouvoir exploiter pleinement les capacités de ces processeurs. En effet jusqu'à maintenant, on a pu voir très peu de logiciels gérer les processeurs multi-coeurs. Globalement les logiciels ne sont pas conçus pour tirer le maximum de cette technologie.
Le compilateur C++ d'Intel version 10 n'est pas seulement destiné aux processeurs multi-coeurs mais aussi aux processeurs Pentium 4 de dernière génération. Ce compilateur gère très bien le fonctionnement multitâche pour que les applications jouissent au maximum de la puissance du processeur.
Le département Intel Software du constructeur Intel propose divers produits pour optimiser les applications fonctionnant sous un ordinateur utilisant un processeur Intel.
II. Présentation▲
Le compilateur C++ d'Intel permet de compiler des sources C et C++ sous les systèmes d'exploitation existants à savoir Windows, Mac OS et Linux. La version 10 du compilateur supporte les plateformes IA-32 (IA pour Intel Architecture), Intel 64 (anciennement EMT64) et les architectures IA-64 (série Itanium II).
On peut lancer le compilateur C++ d'Intel par ligne de commande mais ce compilateur s'intègre également à de nombreux environnements de développement intégré EDI connus comme Microsoft Visual Studio.
Montrez la puissance cachée de vos programmes en utilisant ce compilateur adéquat pour les processeurs Intel.
La nouvelle édition professionnelle combine un compilateur performant avec les autres outils produits d'Intel Software : Intel Threading Building Blocks (TBB), Intel Integrated Performance Primitives (Intel IPP) et Intel Math Kernel Library (Intel MKL) afin de construire une fondation puissante de code aux meilleurs prix.
Vue d'ensemble▲
L'édition professionnelle du compilateur C++ d'Intel offre le meilleur support pour la création d'applications multitâches. Seule cette édition professionnelle offre la largeur d'optimisation avancée, de multitâche qui inclut une gestion automatique du processeur, la vectorisation, l'auto-parallélisation, de l'OpenMP, du " data prefetching " et du " loop unrolling " en utilisant des templates C++ optimisés pour le parallélisme, les calculs mathématiques et les bibliothèques multimédia.
L'édition standard de ce compilateur a les mêmes performances et caractéristiques que l'édition professionnelle sauf qu'elle ne fournit pas des bibliothèques pour le multi-threading.
III. Mode d'utilisation du compilateur▲
III-A. Utiliser la ligne de commande▲
On peut lancer le compilateur en ligne de commande. Sous le système d'exploitation Windows, il suffit de lancer C++ Build Environment for applications running on IA-32/64 (etc.) à travers le menu. Par exemple pour compiler un fichier source C++.
icl mon_source.cpp
ou sous Linux et Mac OS:
icc mon_source.cpp
III-B. Utiliser le compilateur avec Visual Studio▲
L'intégration du compilateur sous Visual Studio est possible sur les versions suivantes : Microsoft Visual Studio 6.0, Microsoft Visual Studio .NET 2003 et Microsoft Visual Studio 2005.
Enfin, pour utiliser le compilateur dans Visual Studio : dans le menu Project, cliquer sur Convert to Use Intel C++ Project System.
Un fichier projet Intel (.icproj) sera créé à la compilation d'un programme C/C++ sous Visual Studio. Ce fichier englobe tous les paramètres d'un projet comme le fait le fichier .dsw (espace de travail) sous Visual Studio 6 et comme le fait le fichier projet .vcproj des Visual Studio 2003 et 2005. Pour s'assurer que le projet sera compilé avec Intel C++ Compiler la prochaine fois, il suffit de lancer le fichier projet .icproj du programme.
Voici un aperçu de la page des propriétés indiquant le compilateur choisi (ici Intel):
Le projet apparaîtra ainsi lorsqu'on choisit comme compilateur le compilateur d'Intel ou lorsqu'on lance le projet Intel (.icproj): |
Remarque pour Visual Studio 6▲
Le support pour Microsoft Visual C++ 6.0 et Microsoft Visual Studio 98 ne sera plus fourni dans les futures versions du compilateur C++ d'Intel pour Windows. Il est donc conseillé de migrer vers Microsoft Visual Studio 2005 pour assurer la compatibilité avec les futures parutions du compilateur C++ d'Intel. Pour cet article, j'ai testé la version 10.0.25, le compilateur marche encore sous Visual C++ 6.0 mais il bogue pour certaines applications spécifiques (ex: jeux, etc.)
Le compilateur C++ de Intel fournit un support macro pour outrepasser le compilateur sélectionné dans l'outil de sélection de compilateur. Ces macros et leurs significations sont les suivant :
_USE_INTEL_COMPILER - Utiliser le compilateur Intel pour compiler les fichiers sélectionnés.
_USE_NON_INTEL_COMPILER - Utiliser le compilateur Microsoft Visual C++ pour compiler les fichiers sélectionnés.
Pour utiliser ces macros dans Microsoft Visual C++, faire ce qui suit :
- ouvrir ou créer un projet C++
- ouvrir le menu Project > Settings
- choisir une configuration à activer dans la liste de la boîte combo (combobox) Settings For.
- Sélectionner le fichier à modifier (.exe)
- Aller dans l'onglet C/C++
- Dans le champ d'édition des définitions des préprocesseurs, ajouter le macro _USE_INTEL_COMPILER pour forcer l'utilisation du compilateur Intel pour les fichiers sélectionnés et _USE_NON_INTEL_COMPILER dans le cas contraire.
III-C. Compatibilité sous Mac▲
III-D. Compatibilité sous le système d'exploitation Linux▲
IV. Technologies exigées▲
Le compilateur C++ d'Intel fonctionne pour les 3 types de plateforme:
- Architecture Intel 32-bit (IA-32): à partir de Pentium II (450 MHz)
- Architecture Intel 64 (formellement Intel EM64T) : fait référence aux systèmes basés sur des processeurs IA-32 qui ont des extensions architecturales 64-bit. (par exemple les processeurs Intel Core 2 et Intel Xeon)
- Architecture IA-64: Intel Itanium II
Développement cross-platform d'une application▲
Le tableau suivant résume l'intercompatibilité entre plateformes, en montrant la compatibilité d'une application, créée sur une architecture A1, avec une architecture A2 :
Hôte / Cible | Architecture IA-32 | Intel 64 | Architecture IA-64 |
Architecture IA-32 | Oui | Oui | Oui |
Intel 64 | Oui | Oui | Oui |
Architecture IA-64 | Non | Non | Oui |
Résumons par le tableau ci-dessous les exigences matérielles du compilateur C++ d'Intel:
Composant | Minimum | Recommandé |
Processeur |
Intel Pentium II 450 MHz - système basé sur les processeurs AMD Athlon et AMD Opteron Intel Itanium 2 Tout processeur utilisant l'architecture Intel 64 |
Intel Core Duo - Intel Pentium 4 - Intel Pentium D - Intel Xeon N/A N/A |
RAM | Architecture IA-32 : 256 Mo et les autres : 512 Mo | Architecture IA-32 : 512 Mo et les autres : 1 Go |
Espace disque | 700 Mo | 1 Go |
V. Caractéristique générale et optimisations▲
En résumant, Intel C++ Compiler permet de créer un code compilé hautement optimisé avec une performance de thread et une sécurité nettement améliorées. Ce compilateur permet de créer un code moins susceptible aux vulnérabilités comme un débordement de buffer. Ainsi, les exploits au niveau du code source sont réduits tels que la provocation d'une erreur système exploitée par les virus et hackers la plupart du temps, sont ainsi réduits. |
Les logiciels qui sont compilés en utilisant l'Intel C++ Compiler bénéficient des différentes optimisations avancées de ce dernier, les voici:
V-A. Utilisation de IPO et PGO▲
IPO et PGO sont respectivement les acronymes de "InterProcedural Optimization" et "Profile-guided Optimization".
IPO améliore grandement les performances des fonctions qui sont fréquemment utilisées, surtout dans les programmes qui contiennent des appels de fonctions à l'intérieur de boucles. Les capacités d'analyse de cet optimiseur peuvent aussi aider à réduire les vulnérabilités et les erreurs de code, telles que les variables non initialisées ou l'utilisation de fonctions de l'API OpenMP qui ne sont pas détectés par d'autres compilateurs.
PGO améliore la performance d'une application en réorganisant le code pour réduire les problèmes de cache-instruction, en réduisant la taille du code et en améliorant la branche de parallélisation (pipelining). PGO fournit des messages au compilateur sur les sections du code qui sont fréquemment exécutées.
PGO travaille selon trois phases:
IPO et PGO peuvent être appliqués ensemble à un programme. La combinaison des deux est plus sollicitée que l'utilisation de IPO seule. Lorsque les deux sont combinées, c'est PGO qui sera utilisée en premier.
V-B. L'auto-parallélisation▲
La fonction d'auto-parallélisation du compilateur traduit automatiquement des morceaux du code d'un programme en son équivalent en code multitâche. L'auto paralléliseur analyse les excès dans les boucles du code source de l'application et génère le code multitâche pour les boucles qui peuvent être exécutées efficacement et sans risque en parallèle.
REM : L'auto-vectorisation (aussi appelé "autovectorizer" en anglais) est un composant du compilateur C++ Intel qui utilise automatiquement les instructions SIMD dans le MMX, SSE, SSE2, et SSE3, et SSE3 jeux d'instructions (et bientôt SSE4).
Avant Vectorisation :
i=
0
;
while
(i<
n)
{
a[i]=
b[i]+
c[i];
++
i;
}
Le compilateur peut manier le "strip-mining" et le traitement de la boucle en restructurant la boucle de la manière suivante:
Après Vectorisation
// The vectorizer generates the following two loops
i=
0
;
while
(i<
(n-
n%
4
))
{
// Vector strip-mined loop
// Subscript [i:i+3] denotes SIMD execution
a[i:i+
3
]=
b[i:i+
3
]+
c[i:i+
3
];
i=
i+
4
;
}
while
(i<
n)
{
a[i]=
b[i]+
c[i];
++
i;
}
V-C. OpenMP▲
Les principales bases de la programmation parallèle du compilateur Intel sont l'auto-vectorisation, OpenMP et l'auto-parallélisation.
OpenMP (Open Multi-Processing) est une interface de programmation pour le calcul parallèle sur architecture à mémoire partagée. Cette API est supportée par de nombreuses plateformes pour les languages de programmation C++ et Fortran. Elle se présente sous la forme d'un ensemble de directives, d'une bibliothèque logicielle et de variables d'environnement.
Pour compiler avec OpenMP, vous avez besoin de préparer votre programme en annotant le code avec les directives OpenMP. Le compilateur Intel traite en premier l'application et produit une version multitâche (multithreaded est le plus approprié) du code qui est alors compilé. Le résultat est un exécutable avec un parallélisme avancé.
Voici comment lancer le compilateur en mode OpenMP.
Sous Linux et Mac OS:
icc -openmp input_file
Sous Windows
icl /Qopenmp input_file
Les pragmas en OpenMP emploient un format et une syntaxe spécifiques.
#pragma omp nom-directive [propositon, ...] nouvligne
Voici un petit exemple l'illustrant:
int
i;
void
simple_omp(int
*
a){
#pragma omp parallel for
for
(i=
0
; i<
1024
; i++
)
a[i] =
i*
2
;
}
V-D. Quelques exemples (OpenMP)▲
Les exemples suivants tirés de la documentation Intel C++ nous montrent comment utiliser OpenMP.
Cet exemple montre une boucle parallèle simple où le montant de travail dans chaque itération est différent. La planification dynamique est utilisée pour obtenir le bon balancement de la charge. For est en nowait parce qu'il y a une barrière implicite à la fin de la région parallèle.
void
for1(float
a[], float
b[], int
n)
{
int
i, j;
#pragma omp parallel shared(a,b,n) private(i,j)
{
#pragma omp for schedule(dynamic,1) nowait
for
(i =
1
; i <
n; i++
)
for
(j =
0
; j <=
i; j++
)
b[j +
n*
i] =
(a[j +
n*
i] +
a[j +
n*
(i-
1
)]) /
2.0
;
}
}
Pour le deuxième exemple, le premier for a un nowait parce que toutes les données utilisées dans la deuxième boucle sont différentes de toutes les données utilisées dans la première boucle.
void
for2(float
a[], float
b[], float
c[], float
d[],
int
n, int
m)
{
int
i, j;
#pragma omp parallel shared(a,b,c,d,n,m) private(i,j)
{
#pragma omp for schedule(dynamic,1) nowait
for
(i =
1
; i <
n; i++
)
for
(j =
0
; j <=
i; j++
)
b[j +
n*
i] =
( a[j +
n*
i] +
a[j +
n*
(i-
1
)] )/
2.0
;
#pragma omp for schedule(dynamic,1) nowait
for
(i =
1
; i <
m; i++
)
for
(j =
0
; j <=
i; j++
)
d[j +
m*
i] =
( c[j +
m*
i] +
c[j +
m*
(i-
1
)] )/
2.0
;
}
}
VI. Liens utiles▲
Télécharger le compilateur C++ de Intel : cliquez ici pour en savoir plus