Je souhaite développer un logiciel de calcul scientifique parallèle à partir de zéro. Je veux quelques réflexions sur quelle langue commencer. Le programme consiste à lire / écrire des données dans des fichiers txt et à effectuer des calculs lourds en parallèle, avec de nombreuses factorisations LU et l'utilisation de solveurs linéaires clairsemés. Les solutions candidates auxquelles je pensais sont Fortran 2003/2008 avec OpenMP ou co-array, C ++ avec openmp cilk + ou TBB, python. Toute autre suggestion documentée est la bienvenue! Je connais très bien C, Fortran et Java (dans cet ordre). J'ai fait quelques scripts en python mais des trucs basiques.
Je sais que fortran est très rapide, mais difficile à maintenir et à paralléliser. On dit que le C ++ est lent à moins que vous n'utilisiez des bibliothèques externes, etc. Python que j'aime, mais est-il réaliste d'écrire un logiciel complet à l'échelle industrielle?
Le logiciel doit être capable de gérer de grandes quantités de données et être efficace avec les calculs scientifiques. La performance est essentielle.
Pour le fond, j'ai déjà un logiciel de travail écrit en Fortran. Beaucoup de gens ont été impliqués dans le développement pendant de nombreuses années et le code est vraiment sale. Maintenir et paralléliser le code s'est avéré être un cauchemar et je pense à des alternatives.
Petros
Réponses:
Laissez-moi essayer de décomposer vos besoins:
À partir de cette liste, je considérerais les langues suivantes:
C, C ++, Fortran, Python, MATLAB, Java
Julia est une nouvelle langue prometteuse, mais la communauté se forme toujours autour d'elle et elle n'a été déployée dans aucun nouveau code majeur.
Lecture / écriture de données textuelles
C'est facile à obtenir dans n'importe quel langage de programmation. Assurez-vous que vous mettez correctement en mémoire tampon et fusionnez votre accès d'E / S, et vous obtiendrez de bonnes performances dans toutes les langues que vous devriez considérer. Évitez les objets de flux en C ++ à moins de savoir comment les utiliser de manière performante.
Interfaces / capacités solides pour les factorisations LU
Si vous effectuez des factorisations LU denses, vous souhaiterez utiliser LAPACK ou ScaLAPACK / Elemental pour une fonctionnalité parallèle. LAPACK et ScaLAPACK sont écrits en Fortran, Elemental est écrit en C ++. Les trois bibliothèques sont performantes et bien prises en charge et documentées. Vous pouvez vous y connecter à partir de n'importe quelle langue que vous devriez considérer.
Solveurs linéaires clairsemés
Les premiers solveurs linéaires clairsemés disponibles gratuitement sont presque tous disponibles via PETSc , écrit en C, qui est bien documenté et pris en charge. Vous pouvez vous connecter à PETSc à partir de n'importe quelle langue que vous devriez considérer.
Performances et évolutivité aux données volumineuses
Les seuls paradigmes de programmation parallèle que vous mentionnez sont basés sur la mémoire partagée, ce qui signifie que vous n'envisagez pas une approche informatique basée sur MPI (passage de messages) et à mémoire distribuée. D'après mon expérience, il est beaucoup plus facile d'écrire du code qui évolue bien au-delà d'une douzaine de cœurs à l'aide d'une solution de mémoire distribuée. Presque tous les «clusters» universitaires sont basés sur MPI de nos jours, les grandes machines à mémoire partagée sont chères et, par conséquent, rares. Vous devriez considérer MPI pour votre approche, mais mes conseils s'appliqueront quel que soit le paradigme de programmation que vous choisissez.
En ce qui concerne les performances sur le nœud, si vous écrivez vous-même des routines numériques, il est plus facile d'obtenir de bonnes performances en série dans Fortran. Si vous avez un peu d'expérience en C, C ++ ou Python, vous pouvez obtenir des performances très comparables (C et C ++ sont morts-même avec Fortran, Python et MATLAB arrivent dans un délai d'environ 25% sans trop d'effort). MATLAB le fait grâce à un compilateur JIT et une très bonne expressivité d'algèbre linéaire. Vous devrez probablement utiliser les noyaux numériques Cython, numpy, numexpr ou incorporés pour obtenir les performances revendiquées de Python. Je ne peux pas commenter les performances de Java, car je ne connais pas très bien le langage, mais je soupçonne qu'il n'est pas loin de Python s'il est écrit par un expert.
Une note sur les interfaces
J'espère que je vous ai convaincu que vous allez pouvoir faire tout ce que vous voulez dans n'importe quel langage de programmation que vous envisagez. Si vous utilisez Java, les interfaces C seront un peu difficiles. Python a une excellente prise en charge des interfaces C et Fortran via ctypes, Cython et f2py. LAPACK est déjà emballé et disponible via scipy. MATLAB possède toutes les fonctionnalités dont vous avez besoin dans ses bibliothèques natives, mais n'est pas facilement évolutif ou particulièrement facile à exécuter sur des clusters. Java peut prendre en charge les interfaces C et Fortran avec le JNI , mais n'est pas communément trouvé sur les clusters et dans les logiciels parallèles pour le calcul scientifique.
Maintenabilité
Une grande partie de cela va se résumer à une saveur personnelle, mais le consensus général sur la maintenabilité est que vous voulez minimiser le nombre de lignes de code dans votre logiciel, écrire du code modulaire avec des interfaces bien définies, et pour les logiciels de calcul, fournir des tests qui vérifient l'exactitude et la fonctionnalité de l'implémentation.
Recommandation
J'ai personnellement eu beaucoup de chance avec Python et je le recommande pour de nombreux projets de calcul. Je pense que vous devriez le considérer sérieusement pour votre projet. Python et MATLAB sont probablement les langages les plus expressifs disponibles pour le calcul scientifique. Vous pouvez facilement interfacer Python avec n'importe quel autre langage de programmation, vous pouvez utiliser f2py pour encapsuler votre implémentation Fortran actuelle et réécrire morceau par morceau les parties que vous souhaitez en Python tout en vérifiant que vous maintenez la fonctionnalité. Pour le moment, je recommanderais une combinaison de l'implémentation officielle de Python 2.7 avec scipy . Vous pouvez commencer très facilement avec cette pile à partir de la distribution Enthought Python disponible gratuitement .
Vous pouvez également effectuer la plupart de ces opérations en C, C ++ ou Fortran. Le C et le C ++ sont des langages très attrayants pour les développeurs professionnels avec beaucoup d'expérience, mais ils tripotent fréquemment les nouveaux développeurs et ne sont probablement pas en ce sens une bonne idée pour un code plus académique. Fortran et MATLAB sont populaires en calcul académique, mais sont faibles au niveau des structures de données avancées et de l'expressivité qu'offre Python (pensez à un objet dict Python, par exemple).
Questions connexes:
la source
En plus de la réponse très complète d'Aron, j'examinerais les différents fils de discussion sur scicomp.stackexchange qui traitaient de la question de savoir quel langage de programmation prendre - à la fois en ce qui concerne la vitesse des programmes ainsi que la question de la facilité ou de la difficulté il s'agit d'écrire et de maintenir des logiciels dans ces langues.
Cela dit, en plus de ce qui y est écrit, permettez-moi de faire quelques observations:
(i) Vous incluez le co-réseau Fortran dans votre liste. À ma connaissance, le nombre de compilateurs qui le prennent en charge est très faible - et le mien, en fait, est nul. Le compilateur Fortran le plus largement disponible est GNU gfortran, et bien que les sources de développement actuelles analysent un sous-ensemble de co-tableaux, je pense qu'il n'en prend en charge aucun (c'est-à-dire qu'il accepte la syntaxe mais n'implémente aucune sémantique) . Il s'agit bien sûr d'une observation générale sur les nouvelles normes Fortran: que le décalage avec lequel les compilateurs prennent réellement en charge les nouvelles normes est mesuré sur plusieurs années - les compilateurs n'ont implémenté Fortran 2003 que dans les deux dernières années et ne prennent en charge que Fortran 2008 partiellement. Cela ne devrait pas vous empêcher d'utiliser tout cela si vous avez un compilateur qui prend en charge ce que vous utilisez,
(ii) La même chose est certainement vraie avec C ++ / Cilk +: Oui, Intel développe cela sur une branche de GCC mais il n'est disponible dans aucune des versions de GCC et ne le sera probablement pas pendant un certain temps. Vous pouvez vous attendre à ce qu'il prenne encore 2-3 ans au moins jusqu'à ce que vous trouviez Cilk + avec les versions GCC installées sur des machines Linux typiques.
(iii) C ++ / TBB est une autre histoire: le TBB existe depuis un certain temps, a une interface très stable et est compilable avec la plupart des compilateurs C ++ qui existent depuis plusieurs années (sur Linux ainsi que sur Windows) . Nous l'utilisons en deal.II depuis plusieurs années déjà avec de bons résultats. Il y a aussi un très bon livre là-dessus.
(iv) J'ai ma propre opinion sur OpenMP, à savoir que c'est une solution à la recherche d'un problème. Cela fonctionne bien pour paralléliser les boucles internes, ce qui pourrait être intéressant si vous avez des structures de données très régulières. Mais c'est rarement ce que vous voulez faire si vous avez besoin de paralléliser quelque chose - parce que ce que vous voulez vraiment faire est de paralléliser les boucles externes . Et pour cela, des solutions telles que le TBB sont de bien meilleures solutions car elles utilisent les mécanismes du langage de programmation plutôt que d'essayer de décrire ce qui se passe en dehors du langage (via #pragmas) et de telle manière que vous n'avez pas accès aux poignées de threads , indicateurs d'état des résultats, etc., à partir de votre programme.
(v) Si vous êtes expérimental, vous pouvez également jeter un œil aux nouveaux langages de programmation conçus pour la programmation parallèle et, en particulier, pour des tâches comme celles que vous décrivez. Il y en a essentiellement deux que j'examinerais: X10 et Chapel . J'ai vu de bons tutoriels sur Chapel, et cela semble bien conçu, bien que les deux soient bien sûr aujourd'hui des solutions insulaires.
la source
En général, si vous êtes vraiment sérieux au sujet de ce projet de logiciel, je suggérerais une réécriture complète dans la langue avec laquelle vous vous sentez le plus à l'aise. Il semble que vous fassiez le travail seul et que vous obtiendrez donc les meilleurs résultats dans la langue avec laquelle vous vous sentez le plus à l'aise.
Plus précisément, cependant, en ce qui concerne le parallélisme, je vous encourage à essayer de penser un peu en dehors de la boîte. OpenMP a ses points forts, mais est coincé dans un état d'esprit de prendre un code séquentiel et un parallélisme claquant ici et là. Il en va de même, en substance, pour Intels TBB.
Cilk est définitivement un pas dans la bonne direction, c'est-à-dire qu'il vous oblige à repenser votre problème / solution dans une configuration intrinsèquement parallèle. Ce que je n'aime pas, cependant, c'est que c'est encore une autre langue . De plus, comme il ne peut que déduire grossièrement les relations entre les tâches parallèles, le planificateur peut être assez conservateur et peut ne pas bien évoluer pour certains problèmes.
La bonne nouvelle est, cependant, que, encore une fois, si vous êtes sérieux au sujet de votre implémentation, vous pouvez faire ce que fait Cilk, par exemple réécrire votre problème sous la forme d'un ensemble de tâches interdépendantes et les répartir sur un certain nombre de processeurs / cœurs, vous-même en utilisant pthreads ou en utilisant abusivement OpenMP pour générer des processus. Un bon exemple de la façon dont cela peut être fait est le planificateur QUARK utilisé dans la bibliothèque PLASMA . Une belle comparaison de ses performances par rapport à Cilk est donnée ici .
la source
pthreads-win32
ou dans lecygwin
projet.Il y a eu peu de discussions sur le coarray fortran dans les commentaires ci-dessus. À l'heure actuelle, et à ma connaissance limitée, le support de coarray dans les compilateurs est à peu près comme suit:
En général, je serais prudent si vous démarrez un code basé sur Coarray. La syntaxe est simple et beaucoup plus pratique que Fortran / C / C ++ avec MPI, mais elle n'est tout simplement pas aussi complète. Par exemple, MPI prend en charge de nombreuses opérations de réduction, etc., ce qui pourrait être très pratique pour vous. Cela dépendrait vraiment de votre besoin de beaucoup de communication. Si vous voulez un exemple, faites-le moi savoir et je peux vous en fournir quelques-uns, si je peux déterrer les fichiers.
la source
Jetez un œil à Spark, c'est un framework distribué pour les calculs en mémoire qui tire parti de la programmation fonctionnelle. La structure d'un programme dans Spark est très différente par rapport à MPI, fondamentalement, vous écrivez un code comme pour un seul ordinateur, qui est automatiquement distribué en tant que fonctions aux données situées en mémoire. Il prend en charge Scala, Java et Python.
Régression logistique (scala):
Il existe une extension appelée MLib (bibliothèque d'apprentissage automatique) qui utilise une bibliothèque Fortran pour certains calculs de bas niveau (pour Python, je suppose que numpy est utilisé). Donc, l'idée est simple, concentrez-vous sur votre algorithme et laissez les optimisations à des niveaux inférieurs (ordre de traitement, distribution des données, etc.).
la source