Nvidia, CUDA ou comment accélérer vos backtests

 

De Simon Depiets pour Trading Automatique.

Lors de vos backtests vous pouvez vous retrouver face à un problème de puissance disponible sur votre machine, faites variez 5 paramètres entre 1 et 1000 et vous devrez en fait effectuer 1000^5 backtests soit un million de milliards ! La puissance de votre processeur est alors trop petite pour réaliser vos calculs dans un temps raisonnable, il est alors possible dans un premier temps d’utiliser un algorithme génétique pour obtenir une bonne approximation, mais augmentez encore le nombre de variables et vous vous retrouverez face au même problème.

Pour celà vous pouvez utiliser les spécificités d’un GPU et la technologie GPGPU pour General Purpose GPU. Il est impossible aujourd’hui d’augmenter la fréquence des CPU, on augmente donc le nombre de coeurs dont ils disposent. Les GPU disposent par contre d’une parallélisation poussée à l’extrême avec plusieurs dizaines de cœurs et la possibilités d’exécuter en parallèle plusieurs centaines de threads.

Pour résumer les GPU ont un jeu d’instruction SIMD (Simple Instruction Multiple Data) qui vient à l’origine du marché du jeu (CG de PC). Depuis quelque années une transformation s’opère vers une utilisation professionnelle pour le calcul scientifique. Il est ainsi possible d’utiliser les unités de calcul très présentes sur un GPU (au détriment du cache ou des Entrées/Sorties d’un CPU) et de fait avoir un très gros potentiel de calcul.

L’histoire

La roadmap des GPU est très agressive puisque les performances sont multipliées par 2 à chaque itération depuis le milieu des années 2000. Tout a commencé dans les années 80/90 avec les premières stations SUN graphiques, cela restait une sorte d’outil à plugger avec une carte externe. Dans les années 90, on voit arriver les premières cartes 3D, avec la Voodoo par exemple : 16 bits au départ, pas de flottants, purement graphique. Puis Nvidia arrive à la fin des années 90 sur le marché avec les GeForce, pour les programmer Microsoft lance Direct X et face à eux on trouve l’implémentation libre OpenGL.

Au début 2003 arrivent les premiers calculs sur Cartes Graphiques, les gens se sont rendus compte qu’il y avait du potentiel, les Cartes Graphiques avaient déjà plus de puissance de calcul que les processeurs. On voit apparaitre des méthodes de programmation orientées graphiques : les shaders. On peut en utilisant quelques astuces considérer que le graphique n’est que du calcul et les utiliser pour faire du calcul scientifique, il faut pour celà néanmoins passer par toutes les contraintes d’OpenGL.

A l’époque Nvidia/ATI sont au même niveau en termes de mégaflops, on est aujourd’hui au dessus du TéraFlop. La programmation GPU utilise néanmoins toujours quelques aspects graphiques, le marché de Nvidia est constitué de joueurs, pas de scientifiques…

En 2004/2005 les constructeurs s’intéressent au GPGPU, ils créent des langages dédiés pour faire des calculs sur GPU au lieu de l’OpenGL bidouillé et le rendent ainsi accessible. La première implémentation intéressante est celle d’ATI avec Brook, basé sur le Stream Computing, mais n’est tout de même pas très utilisable par la communauté scientifique traditionnelle.

En 2007, Nvidia lance CUDA, qui permet vraiment de faire du calcul scientifique sur les GPU NVidia, la même année ATI fournit son propre SDK. L’interet est qu’on a plus besoin de passer par OpenGL, les GPGPU sont maintenant exploitables par l’industrie et sortent du cadre confidentiel de quelques informaticiens farfelus.

Nvidia a ainsi séparé ses cartes pro et gamer au début de la décennie, la Quadro est orientée vers le graphisme, les Tesla vers le GPGPU et le calcul scientifique. La ligne Quadro a été dérivée en une première ligne Tesla en 2002. 

La nouvelle génération est attendue en 2010, basée sur une architecture Fermi qui a de bien meilleures performances en double précision (la moitié des performances simple précision pour les Tesla, un huitième pour la gamme gamers).  L’adressage est en 64 bits, on peut donc dépasser les 4GB de mémoire vive, mais aussi faire du mapping de mémoire entre poste et GPU sur des tailles de plus de 4GB.

De plus des opérations atomiques de lecture mémoire/calcul/écriture mémoire sont disponibles, très importantes pour certaines opérations qui ne peuvent être interrompues. La mémoire partagée passe de 16 à 32ko, les cartes sont disponibles en cartes simples, en racks avec des versions disponsant de 3 ou 6 GB de mémoire. Ces cartes dépassent le téraflop de puissance de calcul.

Du côté d’AMD on trouve le Firestream, comme chez Nvidia c’est une gamme proche de celles des cartes gamers, les premières cartes sortent en 2004, aujourd’hui la plus récente est une 5870. En 2006, le concept de stream computing est lancé, ainsi qu’une première plateforme de développement qui ressemble toujours fortement à un Proof of Concept et est destinée à la recherche. En 2007 il y a la première release officielle du SDK avec Brook  et des aspects assembleur de haut-niveau, depuis ATI sort une version par an du SDK. Fin 2009 ils abandonnent Brook pour se focaliser sur OpenCL ils atteignent 2.7 Téraflops avec néanmoins une forte perte de puissance lors du passage de simple à double précision.

L’avantage des GPU est qu’on y trouve beaucoup de Stream Processing Units, chaque processeur peut gérer actuellement mille threads, lancés par une partie hardware dédiée. On retrouve toujours sur ces cartes des blocs matériels dédiés au graphique et à la gestion des textures et du rendu.

La mémoire n’est pas en général de très bonne qualité, le principal problème est d’être certain qu’il n’y a pas d’erreur lors de l’accès mémoire, le moindre bit inversé va bouleverser les résultats. Une étude a été faite sur Folding@Home pour voir quelle était la fiabilité des GPU, sur les cartes pro et gaming, quand on passe sur un nombre de cartes assez grand (50000) deux-tiers d’entre elles ont des mémoires assez chaotiques. Il fallait ajouter le support des mémoires ECC, Fermi va supporter ECC, comme ce sont des bits correcteurs d’erreur on va perdre 1/8 de la mémoire.

ATI et Nvidia savent ou ils vont, mais ils ont pas sûrs d’y arriver, ils ne donnent pas beaucoup d’informations sur leurs roadmap. Comme le Fermi vient juste de sortir, on dispose d’informations sur les releases de cette gamme mais de peu d’indications à long terme.  On devrait voir apparaître cette année plusieurs versions dont CMA50, CMA70 avec un peu plus de mémoire et un peu plus de capacités en double précision.

Premier processeur non-CPU ayant participé au grid computing avec des résultats prometteurs (10 fois la performance d’un CPU), le Cell d’IBM semble abandonné, l’entreprise américaine envisage en 2011 d’ajouter un accélérateur dans leur nouveau Power, ils ont dit de manière vague qu’ils réutilisaient les choses qu’ils maitrisaient donc la porte n’est pas totalement fermée. Le Cell dans sa version actuelle est définitivement mort, il n’est de toute façon pas évident à utiliser puisqu’il faut déporter certains calculs sur les différents niveaux de l’architecture.

Comment utiliser votre GPU

En pratique les standard ne sont pas encore présents, on mélange en fait plusieurs interfaces de programmation. On va avoir plusieurs technos qui permettent d’accéder à plusieurs niveau de programmation dans l’architecture. Le but est de mélanger des CPU et des GPU, un CPU c’est une grosse RAM, du gros cache, partagé par 4 à 8 coeurs, plusieurs Unités de Calcul, et un tout petit peu de vectorisé caché au niveau de la programmation.

Au contraire le GPU c’est une architecture dont le design est spécifique à certaines applications, basé sur des concepts de vectoriel SIMD. La façon de programmer va cacher de façon plus ou moins efficace l’aspect vectoriel ou l’aspect SIMD, il y a peu de cache mais des mémoires et des bus et des requêtes mémoires très larges. Avec souvent plusieurs dizaines de cœurs on va pouvoir lancer plusieurs centaines de threads en parallèle, si ceux-ci ont le même code.

On va créer des GPU Thread, c’est un Thread léger, qui n’est là que pour faire du calcul et des accès mémoires. Il y a des statements (instructions) et un identifiant, qui va varier selon les architectures et qui le rendent unique. Tous les threads ont le même code sur le même kernel, il n’y a pas de pile donc pas de récursif par exemple, Les threads sont organisés en warp et exécutes de façon SIMD, regroupés pour former des blocs. Ils sont reppartis sur les multi-processeurs, chacun va être capable d’executer un bloc (ou plus si il a assez de capacités pour en executer plus). Quand on atteint un test conditionnel par exemple, les threads avec la condition fausse vont devenir inactifs, ceux avec la bonne continuent et vice versa quand on atteint le else.

L’API la plus efficace et la plus utilisée à l’heure actuelle est le CUDA (Compute Unified Device Architecture) de Nvidia, disponible à partir des cartes graphiques GeForce 8XXX. C’est un modèle de programmation générique, l’objectif est d’exécuter des millions de Light Threads sur le GPU. Au niveau de la programmation c’est du C++ avec quelque extensions : des qualifiers pour spécifier que c’est un thread GPU : __global__ et quelques qualifiiers de données: __constant__ __shared__. On peut lancer un kernel de manière très simple avec kernel<<<config…>>>. Tout le C++ n’est pas nécessairement implémenté dans CUDA, mais il y a par exemple la possibilité quand même de templater les kernels, une API C pour remplacer les appels système sclassiques, des possibilités de copier de la mémoire entre CPU et GPU ou a l’intérieur du GPU, de manière synchrone ou asynchrone mais aussi un Driver API en C qui permet de contrôler de façon beaucoup plus fine le driver CUDA.

On peut dès lors imaginer paralléliser des backtests sur 10 ans avec un jeu de paramètres par thread, sachant qu’un code dont 99% est parallélisable est exécuté 100 fois plus rapidement sur un GPU. Les gains de performance ne sont pas négligeables, pour l’instant aucune application de trading grand public ne s’est intéressée à celà, pourtant nombreux sont les traders découragés par la lenteur de leurs backtests…

Sites :

http://gpgpu.org/

http://www.nvidia.com/object/cuda_home.html

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>