Un point sur Open CL et Grand Central
Nous avons demandé à Christophe Ducommun qui développe le logiciel MovieGate et qui est toujours à la recherche des moyens de le rendre plus véloce son opinion sur les deux technologies phares de Snow Leopard, Open CL et Grand Central.
Actuellement je travaille sur les optimisations possible du décodeur vidéo de MovieGate. Le décodeur de MovieGate se charge de fournir des images au format YCbCr 4:2:2 aux deux encodeurs MPEG-2 possible (mpeg2enc et ffmpeg). Au niveau performances, le but est de fournir un maximum d'images/seconde à l'encodeur vidéo avec un minimum de temps processeur utilisé. La solution est d'utiliser le processeur de la carte graphique (GPU) pour décharger le processeur central, cela à aussi comme impact de laisser plus de CPU libre à l'encodeur.
Grand Central Dispatch
Cette technologie permet de faire du multi-threading "sans synchronisation". Il faut savoir que lorsqu'on développe une application multi-thread, il faut protéger l'accès aux variables communes entre les différents thread (lock, semaphores etc...). Ces opérations demandent au kernel l'accès aux variables, et si un autre thread y accède, le thread en question est mis en attente. Ces accès sont couteux et empêchent les threads de pouvoir dans tous les cas travailler en parallèle. C'est une des raisons pour laquelle la gain en vitesse par exemple sur une machine à 8 coeurs n'est pas deux fois plus rapide que sur une machine à 4 coeurs. Quand un traitement sur n données doit être effectué, les coeurs vont se partager le travail, plus il y a de coeurs, moins important sera le temps de traitement par coeur. Mais les temps de latence induit par la synchronisation reste identique. Ce qui fait que les threads passent leur temps (façon de parler) à attendre l'accès aux variables. Plus il y a de coeurs plus ce problème s'intensifie.
Grand Central Dispatch propose des threads déjà prêt à exécuter le travail au niveau du kernel. Ce qui signifie que les applications n'ont plus besoin de créer des threads et n'ont plus besoins de synchroniser l'accès aux variables. C'est Grand Central qui s'en charge et comme il travaille à un niveau plus bas les temps de latence sont nettement moins importants.
De plus Grand Central Dispatch gère lui-même le nombre de threads actifs suivant la charge de la machine, de cette manière le traitement est bien plus efficace qu'avec une programmation traditionnelle via des threads et de la synchronisation.
Il y a beaucoup de choses à dire sur cette technologie, mais en voici le principe.
Concernant le décodeur vidéo de MovieGate, une version BETA exploite déjà Grand Central, le gain en vitesse n'est pas important, mais la charge processeur est diminuée ce qui est un bon point.
OpenCL
Cette technologie est très prometteuse mais pas forcément facile à prendre en main. Le principe est d'exécuter des opérations sur le GPU à la place du CPU.
Pour commencer, un GPU possède un nombre important d'unité de calculs (112 sur une 8800GT), par comparaison un Xeon Quad Core en possède... quatre. Alors il est aisément compréhensible que si on peut paralléliser des calculs, un GPU exécutera ce traitement de manière bien plus rapide qu'un processeur.
Voilà pour la théorie, mais dans la pratique il y a certains facteurs dont il faut faire très attention.
Voici le principe de fonctionnement.
(Host) < BUS PCI-Express > (Device)
Host, c'est l'application qui travaille sur le CPU avec la RAM qui lui est allouée. Device, c'est la carte graphique avec sa propre mémoire (GPU et VRAM).
Lorsqu'une application veut exécuter un certains nombre de calculs sur le GPU, il doit tout d'abord transférer les données de la RAM vers la VRAM de la carte graphique. Cette opération est couteuse en temps et doit être réduite au maximum. Le temps de traitement des données par le GPU, dépend de sa puissance. Lorsque le GPU a terminé ses calculs, il faut transférer à nouveau les résultats de la VRAM vers la RAM via le bus PCI-Express ce qui est à nouveau couteux en temps. On comprend donc, que pour limiter l'impact du transfert mémoire, il faut que le temps de traitement sur le GPU soit important. Donc si il faut faire quelques calculs simples, OpenCL sera plus lent qu'un traitement sur le CPU de manière traditionnelle. Evidemment on peut travailler de manière asynchrone, c'est-à-dire faire quelque chose d'autre pendant que les données sont transférées, mais cela ne supprime pas le fait que le transfert mémoire est couteux.
Le principe d'OpenCL est d'écrire des kernel qui exécutent le traitement spécifique à l'application. Ces kernels sont compilé à la volée par l'application pour le GPU détecté, le compilateur va fournir un code compilé spécifique au GPU détecté et peut donc faire certaines optimisations.
Cependant on ne peut pas écrire un kernel de n'importe quelle manière, car suivant le code écrit les performances suivant le GPU peuvent chuter drastiquement. nVidia fournit un guide pour les développeurs expliquant comment optimiser le code d'un kernel afin que le GPU l'exécute de la manière la plus efficace. Il faut donc bien connaître l'architecture d'un GPU pour en tirer tout son potentiel, ce qui n'est pas chose aisée.
Concernant OpenCL, le but est d'offrir une API indépendante des constructeurs de cartes graphique. Mais il faut savoir qu'OpenCL est en fait bâtit comme CUDA. En effet nVidia à développé une passerelle OpenCL -> CUDA, d'ailleurs OpenCL ressemble très fortement à CUDA et utilise les mêmes principes. NVidia à donc eu peu de travail car ils avaient déjà fournit un SDK CUDA pour Mac OS X bien avant Snow Leopard.
On comprend aussi facilement qu'OpenCL fonctionne mieux sur cartes nVidia que des cartes ATI pour ces raisons.
Concernant ATI (ceci n'engage que moi), ils ont eu un travail bien plus important et c'est sans doute la raison pour laquelle peu de cartes ATI sont finalement supportées par OpenCL.
OpenCL est très prometteur, cependant ce n'est pas une technologie que l'on prend en main facilement contrairement à ce que disait Steve Jobs. N'importe quelle application ne tirera pas forcément profit d'OpenCL, et la qualité du code des kernels écrits impactera fortement sur les performances. Ce qui veut dire que les développeurs utilisant cette technologie devront vraiment savoir l'exploiter de manière correct pour en tirer tous les avantages.
Pour terminer OpenCL offre une passerelle vers OpenGL, c'est-à-dire que l'on peut travailler directement avec des données provenant d'OpenGL donc de la VRAM mais aussi fournir des résultats calculé par OpenCL vers OpenGL sans avoir besoin de transfert via le bus PCI-Express.
Ce sont à mon avis les applications utilisant OpenGL qui tireront le mieux profit d'OpenCL car les transfert mémoire sont réduits.
Si nous devions résumer ses propos, nous dirions que le potentiel est indubitablement énorme, mais que contrairement à ce qu'Apple laissait penser, il ne suffira pas de modifications légères pour accélérer des logiciels. Il faudra non seulement avoir les bonnes données, celles que l'on peut paralléliser, mais aussi optimiser au mieux le code fourni pour que tout soit optimal. C'est certainement ce qui explique que personne n'ait été prêt à lancer un logiciel ultra optimisé à la sortie de Snow Leopard.