Quiero desarrollar un software paralelo de computación científica desde cero. Quiero algunas ideas sobre qué idioma comenzar. El programa implica leer / escribir datos en archivos txt y hacer cálculos pesados en paralelo, con muchas factorizaciones LU y el uso de solucionadores lineales dispersos. Las soluciones candidatas que estaba pensando son Fortran 2003/2008 con OpenMP o co-array, C ++ con openmp cilk + o TBB, python. ¡Cualquier otra sugerencia documentada es bienvenida! Sé muy bien C, Fortran y Java (en ese orden). He hecho algunos scripts en Python pero cosas básicas.
Sé que fortran es muy rápido, pero difícil de mantener y paralelizar. Se dice que C ++ es lento a menos que use bibliotecas externas, etc. Me gusta Python, pero ¿es realista escribir un software a nivel industrial a escala completa?
El software debe ser capaz de manejar grandes cantidades de datos y ser efectivo con los cálculos científicos. El rendimiento es de la esencia.
Para el fondo, ya tengo un software de trabajo escrito en Fortran. Muchas personas estuvieron involucradas en el desarrollo durante muchos años y el código está muy sucio. Mantener y paralelizar el código ha resultado ser una pesadilla y estoy pensando en alternativas.
Pedro
Respuestas:
Déjame intentar y desglosar tus requisitos:
De esta lista, consideraría los siguientes idiomas:
C, C ++, Fortran, Python, MATLAB, Java
Julia es un nuevo lenguaje prometedor, pero la comunidad todavía se está formando a su alrededor y no se ha implementado en ningún código nuevo importante.
Leer / escribir datos de texto
Esto es fácil de entender en cualquier lenguaje de programación. Asegúrese de almacenar y fusionar adecuadamente su acceso de E / S, y obtendrá un buen rendimiento de cualquiera de los idiomas que debe considerar. Evite los objetos de flujo en C ++ a menos que sepa cómo usarlos de manera eficaz.
Interfaces fuertes / capacidad para factorizaciones LU
Si está realizando factorizaciones LU densas, querrá usar LAPACK o ScaLAPACK / Elemental para la funcionalidad paralela. LAPACK y ScaLAPACK están escritos en Fortran, Elemental está escrito en C ++. Las tres bibliotecas son eficaces y están bien respaldadas y documentadas. Puede interactuar con ellos desde cualquiera de los idiomas que debe considerar.
Solucionadores lineales dispersos
Los principales solucionadores lineales dispersos disponibles gratuitamente están casi todos disponibles a través de PETSc , escrito en C, que está bien documentado y respaldado. Puede interactuar con PETSc desde cualquiera de los idiomas que debe considerar.
Rendimiento y escalabilidad a datos grandes
Los únicos paradigmas de programación paralelos que menciona son basados en memoria compartida, lo que significa que no está considerando un enfoque de computación de memoria distribuida basada en MPI (transmisión de mensajes). En mi experiencia, es mucho más fácil escribir código que se escala mucho más allá de una docena de núcleos utilizando una solución de memoria distribuida. Casi todos los "clústeres" universitarios están basados en MPI en estos días, las grandes máquinas de memoria compartida son caras y, en consecuencia, raras. Debería considerar MPI para su enfoque, pero mi consejo se aplicará independientemente del paradigma de programación que elija.
Con respecto al rendimiento en el nodo, si está escribiendo rutinas numéricas usted mismo, es más fácil obtener un buen rendimiento en serie en Fortran. Si tiene un poco de experiencia en C, C ++ o Python, puede obtener un rendimiento muy comparable (C y C ++ están muertos, incluso con Fortran, Python y MATLAB tienen una sobrecarga de tiempo del 25% sin mucho esfuerzo). MATLAB hace esto a través de un compilador JIT y muy buena expresividad de álgebra lineal. Es probable que necesite usar núcleos numéricos Cython, numpy, numexpr o incrustar para obtener el rendimiento reclamado de Python. No puedo comentar sobre el rendimiento de Java, porque no conozco muy bien el lenguaje, pero sospecho que no está lejos de Python si está escrito por un experto.
Una nota sobre interfaces
Espero haberte convencido de que podrás hacer todo lo que quieras en cualquiera de los lenguajes de programación que estás considerando. Si está utilizando Java, las interfaces C serán un poco desafiantes. Python tiene una excelente compatibilidad con la interfaz C y Fortran a través de ctypes, Cython y f2py. LAPACK ya está envuelto y disponible a través de scipy. MATLAB tiene toda la funcionalidad que necesita en sus bibliotecas nativas, pero no es fácilmente escalable o particularmente fácil de ejecutar en clústeres. Java puede soportar interfaces C y Fortran con el JNI , pero no se encuentra comúnmente en clústeres y en software paralelo para computación científica.
Mantenibilidad
Mucho de esto se reducirá al gusto personal, pero el consenso general sobre la capacidad de mantenimiento es que desea minimizar la cantidad de líneas de código en su software, escribir código modular con interfaces bien definidas y, para el software computacional, proporcionar pruebas que verifican la corrección y la funcionalidad de la implementación.
Recomendación
Yo personalmente he tenido mucha suerte con Python y lo recomiendo para muchos proyectos computacionales. Creo que deberías considerarlo fuertemente para tu proyecto. Python y MATLAB son probablemente los lenguajes más expresivos disponibles para la computación científica. Puede conectar fácilmente Python con cualquier otro lenguaje de programación, puede usar f2py para ajustar su implementación actual de Fortran y reescribir pieza por pieza las partes que desee en Python mientras verifica que mantiene la funcionalidad. En este momento, recomendaría una combinación de la implementación oficial de Python 2.7 con scipy . Puede comenzar fácilmente con esta pila desde la distribución de Enthought Python disponible gratuitamente .
También podría hacer la mayor parte de esto en C, C ++ o Fortran. C y C ++ son lenguajes muy atractivos para desarrolladores profesionales con mucha experiencia, pero con frecuencia tropiezan con nuevos desarrolladores y, en este sentido, probablemente no sean una gran idea para un código más académico. Fortran y MATLAB son populares en computación académica, pero son débiles en las estructuras de datos avanzadas y la expresividad que ofrece Python (piense en un objeto dict Python, por ejemplo).
Preguntas relacionadas:
fuente
Además de la respuesta muy completa de Aron, echaría un vistazo a los diversos hilos en scicomp.stackexchange que trataban la pregunta sobre qué lenguaje de programación tomar, tanto con respecto a la velocidad de los programas como a la cuestión de cuán fácil o difícil es para escribir y mantener software en estos idiomas.
Dicho esto, además de lo que se ha escrito allí, permítanme hacer algunas observaciones:
(i) Usted incluye Fortran co-array en su lista. Que yo sepa, el número de compiladores que realmente lo admiten es muy pequeño y, de hecho, mi cero. El compilador Fortran más ampliamente disponible es GNU gfortran, y aunque las fuentes de desarrollo actuales analizan un subconjunto de co-arrays, creo que en realidad no admite ninguno de ellos (es decir, acepta la sintaxis pero no implementa ninguna de las semánticas) . Por supuesto, esta es una observación general sobre los nuevos estándares de Fortran: que el retraso con el que los compiladores realmente admiten nuevos estándares se mide en varios años: los compiladores solo han implementado Fortran 2003 en los últimos años, y solo parcialmente Fortran 2008. Esto no debería impedir que uses nada si tienes un compilador que admite lo que usas,
(ii) Lo mismo es cierto con C ++ / Cilk +: Sí, Intel está desarrollando esto en una rama de GCC pero no está disponible en ninguna de las versiones de GCC y, probablemente, no lo estará por un tiempo. Puede esperar que demore otros 2-3 años por lo menos hasta que encuentre Cilk + con las versiones de GCC instaladas en máquinas típicas de Linux.
(iii) C ++ / TBB es una historia diferente: el TBB ha existido por un tiempo, tiene una interfaz muy estable y es compilable con la mayoría de los compiladores de C ++ que han existido durante los últimos años (en Linux y en Windows) . Lo hemos estado utilizando en el negocio. II durante varios años ya con buenos resultados. También hay un muy buen libro al respecto.
(iv) Tengo mi propia opinión sobre OpenMP, a saber, que es una solución en busca de un problema. Funciona bien para paralelizar los bucles internos, que es lo que podría ser de interés si tiene estructuras de datos muy regulares. Pero rara vez es lo que quieres hacer si necesitas paralelizar algo, porque lo que realmente quieres hacer es paralelizar los bucles externos . Y para eso, las soluciones como el TBB son soluciones mucho mejores porque usan los mecanismos del lenguaje de programación en lugar de tratar de describir lo que sucede fuera del lenguaje (a través de #pragmas) y de tal manera que no tiene acceso a los controladores de hilos , indicadores de estado de resultados, etc., desde su programa.
(v) Si eres experimental, también puedes echar un vistazo a los nuevos lenguajes de programación diseñados para la programación paralela y, en particular, para tareas como las que describes. Esencialmente, hay dos que echaría un vistazo: X10 y Chapel . He visto buenos tutoriales sobre Chapel, y parece estar bien diseñado, aunque ambos, por supuesto, también son soluciones insulares.
fuente
En general, si usted es realmente serio sobre este proyecto de software, sugeriría una reescritura completa en cualquier idioma con el que se sienta más cómodo. Parece que va a hacer el trabajo solo y, por lo tanto, obtendrá los mejores resultados en el idioma con el que se sienta más a gusto.
Sin embargo, más específicamente, con respecto al paralelismo, le animo a que trate de pensar un poco fuera de la caja. OpenMP tiene sus puntos fuertes, pero está atrapado en una mentalidad de tomar un código secuencial y poner paralelismo aquí y allá. Lo mismo ocurre, en esencia, para Intels TBB.
Cilk es definitivamente un paso en la dirección correcta, es decir, te obliga a repensar tu problema / solución en una configuración inherentemente paralela. Sin embargo, lo que no me gusta es que es otro idioma . Además, dado que solo puede inferir aproximadamente las relaciones entre tareas paralelas, el programador puede ser bastante conservador y puede que no se adapte bien a ciertos problemas.
Sin embargo, la buena noticia es que, una vez más, si se toma en serio su implementación, puede hacer lo que hace Cilk, por ejemplo, volver a escribir su problema como un conjunto de tareas interdependientes y distribuirlas en varios procesadores / núcleos, todo por su cuenta, ya sea utilizando pthreads o mal uso de OpenMP para generar procesos. Un buen ejemplo de cómo se puede hacer esto es el planificador QUARK utilizado en la biblioteca PLASMA . Aquí se ofrece una buena comparación de su rendimiento frente a Cilk .
fuente
pthreads-win32
o dentro delcygwin
proyecto.Se ha discutido poco sobre coarray fortran en los comentarios anteriores. En este momento, y para mi conocimiento limitado, el soporte de la matriz en los compiladores es aproximadamente el siguiente:
En general, tendría cuidado si comenzara un código basado en una matriz. La sintaxis es simple y mucho más conveniente que Fortran / C / C ++ con MPI, pero no es tan completa. Por ejemplo, MPI admite muchas operaciones de reducción, etc., lo que podría ser muy conveniente para usted. Realmente dependería de su necesidad de mucha comunicación. Si desea un ejemplo, hágamelo saber y puedo proporcionarle algunos, si puedo desenterrar los archivos.
fuente
Eche un vistazo a Spark , es un marco distribuido para cálculos en memoria que aprovecha la programación funcional. La estructura de un programa en Spark es muy diferente en comparación con MPI, básicamente se escribe un código como para una sola computadora, que se distribuye automáticamente como funciones a los datos ubicados en la memoria. Es compatible con Scala, Java y Python.
Regresión logística (scala):
Hay una extensión llamada MLib (biblioteca de Machine Learning) que usa una biblioteca Fortran para algunos cálculos de bajo nivel (supongo que para Python se usa numpy). Entonces, la idea es simple, concéntrese en su algoritmo y deje las optimizaciones en niveles más bajos (orden de procesamiento, distribución de datos, etc.).
fuente