web-dev-qa-db-fra.com

Est-il possible d'utiliser l'accélération GPU lors de la compilation de plusieurs programmes sur un compilateur gcc?

Existe-t-il un moyen ou un outil pour appliquer l'accélération GPU sur les programmes de compilation avec le compilateur GCC? En ce moment, j'ai créé un programme pour compiler la liste donnée de programmes de manière itérative. Cela prend quelques minutes. Je connais quelques programmes comme Pyrit qui aident à appliquer l'accélération GPU pour les hachages de pré-calcul.

S'il n'y a pas de tels outils disponibles, veuillez nous conseiller d'utiliser OpenCL ou toute autre chose pour reprogrammer mon code.

48
clu3Less

A. Dans un langage de programmation impératif, les instructions sont exécutées en séquence, et chaque instruction peut changer l'état du programme. L'analyse des unités de traduction est donc intrinsèquement séquentielle.

Un exemple: Découvrez comment la propagation constante pourrait fonctionner -

a = 5;
b = a + 7;
c = a + b + 9;

Vous devez parcourir ces instructions séquentiellement avant de comprendre que les valeurs affectées à b et c sont des constantes au moment de la compilation.

(Cependant, des blocs de base séparés peuvent éventuellement être compilés et optimisés en parallèle les uns avec les autres.)

B. En plus de cela, différentes passes doivent également s'exécuter séquentiellement et s'influencer mutuellement.

Un exemple: sur la base d'un calendrier d'instructions, vous allouez des registres, puis vous constatez que vous devez renverser un registre en mémoire, vous devez donc générer de nouvelles instructions. Cela modifie à nouveau le calendrier.

Vous ne pouvez donc pas exécuter de "passes" comme "allocation de registre" et "ordonnancement" en parallèle non plus (en fait, je pense qu'il y a des articles où les informaticiens/Les mathématiciens ont essayé de résoudre ces deux problèmes ensemble, mais ne rentrons pas dans les détails).

(Encore une fois, on peut obtenir un certain parallélisme en passant par pipelining.)

De plus, les GPU ne conviennent surtout pas car:

  1. Les GPU sont bons en mathématiques à virgule flottante. Quelque chose que les compilateurs n'ont pas besoin ou utilisent beaucoup (sauf lors de l'optimisation de l'arithmétique à virgule flottante dans le programme)

  2. Les GPU sont bons pour SIMD. c'est-à-dire effectuer la même opération sur plusieurs entrées. C'est encore une fois, pas quelque chose qu'un compilateur doit faire. Il peut y avoir un avantage si le compilateur doit, par exemple, optimiser plusieurs centaines d'opérations en virgule flottante (Un exemple génial serait: le programmeur a défini plusieurs grandes FP tableaux, leur a assigné des constantes, puis a écrit du code pour les utiliser. Un programme très mal écrit en effet.)

Donc, mis à part la parallélisation de la compilation des blocs de base et des passes de pipelining, il n'y a pas beaucoup de parallélisme à au niveau de `` dans la compilation d'un fichier C '' . Mais le parallélisme est possible, facile à implémenter et constamment utilisé à un niveau supérieur. GNU Make, par exemple, a le -j=N argument. Ce qui signifie essentiellement: tant qu'il trouve N des travaux indépendants (généralement, la compilation d'un tas de fichiers _ GNU Make est utilisé de toute façon), il génère N processus (ou N instances de gcc compilation de fichiers différents en parallèle).

30
ArjunShankar

SI vous demandez: "Pouvez-vous écrire automatiquement du code accéléré par GPU pour une utilisation avec GCC et LLVM?" la réponse est oui. NVIDIA et Google créent des projets de compilateur LLVM open source:

NVIDIA CUDA LLVM:

GOOGLE GPUCC:

Si votre question est, "puis-je utiliser le GPU pour accélérer la compilation de code générique non-CUDA?" la réponse est actuellement non. Le GPU est bon pour certaines choses comme les tâches parallèles, mauvais pour d'autres comme les branches qui sont les compilateurs. La bonne nouvelle est que vous pouvez utiliser un réseau de PC avec des processeurs pour obtenir des accélérations de compilation de 2 à 10 fois, selon l'optimisation de votre code, et vous pouvez obtenir le processeur multicœur le plus rapide et le SSD haute vitesse disponibles pour votre bureau pour obtenir des gains pour moins de tracas avant de recourir à des constructions de réseau.

Il existe des outils pour distribuer les tâches du compilateur C/C++/ObjC à un réseau d'ordinateurs comme Distcc. Il était inclus dans les anciennes versions de XCode mais a été supprimé, et il n'y a pas de support pour l'utiliser avec Swift.

Il existe un outil commercial similaire à Distcc appelé Incredibuild qui prend en charge les environnements de développement Visual Studio C/C++ et Linux:

Il existe de bons articles sur l'utilisation du monde réel d'Incredibuild vs Distcc et des compromis par rapport à la prise en charge incrémentielle de la construction dans le compilateur natif pour effectuer de petites modifications comme une seule ligne dans un seul fichier sans recompiler tout le reste. Points à considérer:

  • Vous pouvez accélérer considérablement une base de code en précompilant les en-têtes, en utilisant plusieurs DLL et en utilisant des versions incrémentielles sur une seule machine.
  • Incredibuild est une solution plus complète pour distribuer automatiquement le travail et garantir le même résultat qu'une compilation en série par rapport à le faire gratuitement avec distcc où vous devez faire beaucoup plus de travail pour les mêmes résultats et la compatibilité avec autre chose que gcc.
  • Pour un examen détaillé, voir http://gamesfromwithin.com/how-incredible-is-incredibuild
13
Alex Peake