Supongamos que estoy trabajando en un código científico en C ++. En una discusión reciente con un colega, se argumentó que las plantillas de expresión podrían ser algo realmente malo, lo que podría hacer que el software sea compilable solo en ciertas versiones de gcc. Supuestamente, este problema ha afectado algunos códigos científicos, como se alude en los subtítulos de esta parodia de Downfall . (Estos son los únicos ejemplos que conozco, de ahí el enlace).
Sin embargo, otras personas han argumentado que las plantillas de expresión son útiles porque pueden generar ganancias de rendimiento, como en este artículo en SIAM Journal of Scientific Computing , al evitar el almacenamiento de resultados intermedios en variables temporales.
No sé mucho acerca de la metaprogramación de plantillas en C ++, pero sí sé que es un enfoque utilizado en la diferenciación automática y en la aritmética de intervalos, que es cómo me metí en una discusión sobre plantillas de expresión. Dadas las ventajas potenciales en el rendimiento y las desventajas potenciales en el mantenimiento (si esa es la palabra correcta), ¿cuándo debo usar plantillas de expresión C ++ en ciencia computacional y cuándo debo evitarlas?
fuente
Respuestas:
Mi problema con las plantillas de expresión es que son una abstracción muy permeable. Pasas mucho trabajo escribiendo código muy complicado para hacer una tarea simple con una sintaxis más agradable. Pero si desea cambiar el algoritmo, tiene que meterse con el código sucio y si se desliza con los tipos o la sintaxis, recibirá mensajes de error completamente ininteligibles. Si su aplicación se asigna perfectamente a una biblioteca basada en plantillas de expresión, puede valer la pena considerarla, pero si no está seguro, recomendaría simplemente escribir código normal. Claro, el código de alto nivel es menos bonito, pero puedes hacer lo que hay que hacer. Como beneficio, el tiempo de compilación y los tamaños binarios disminuirán mucho y no tendrá que hacer frente a una gran variación en el rendimiento debido a la elección del compilador y el indicador de compilación.
fuente
Otros han comentado sobre el problema de lo difícil que es escribir programas ET, así como la complejidad de comprender los mensajes de error. Permítanme comentar sobre el tema de los compiladores: es cierto que hace un tiempo uno de los grandes problemas fue encontrar un compilador que cumpla lo suficiente con el estándar C ++ para que todo funcione y que funcione de manera portátil. Como consecuencia, encontramos muchos errores: tengo 2-300 informes de errores en mi nombre, distribuidos en gcc, Intel icc, IBM xlC y pgicc de Portland. En consecuencia, el script de configuración deal.II es un repositorio de una gran cantidad de pruebas de errores del compilador, principalmente en el área de plantillas, declaraciones de amigos, espacios de nombres, etc.
Pero resulta que los creadores de compiladores realmente han logrado actuar juntos: hoy, gcc e icc hoy pasan todas nuestras pruebas y es fácil escribir código que sea portátil entre los dos. Diría que PGI no está muy lejos, pero tiene una serie de peculiaridades que no parecen desaparecer con los años. xlC, por otro lado, es una historia completamente diferente: corrigen un error cada 6 meses, pero a pesar de presentar informes de errores con ellos durante años, el progreso es extremadamente lento y xlC nunca ha podido compilar el acuerdo.II con éxito.
Lo que todo esto significa es esto: si te quedas con los dos grandes compiladores, puedes esperar que funcionen hoy. Dado que la mayoría de las computadoras y sistemas operativos de hoy en día suelen tener al menos uno de ellos, es suficiente. La única plataforma donde las cosas son más difíciles es BlueGene, donde el compilador del sistema generalmente es xlC, con todos sus errores.
fuente
He experimentado un poco con ET's hace mucho tiempo cuando, como mencionaste, los compiladores todavía estaban luchando con ellos. He usado la biblioteca blitz para álgebra lineal en algún código mío. El problema era obtener el buen compilador y, como no soy un programador perfecto de C ++, interpretar los mensajes de error del compilador. Este último era simplemente inmanejable. El compilador generaría, en promedio, alrededor de 1000 líneas de mensajes de error. De ninguna manera pude encontrar rápidamente mi error de programación.
Puede encontrar más información en la página web de oonumerics (están las actas de dos talleres de ET).
Pero me quedaría lejos de ellos ...
fuente
El problema ya comienza con el término 'plantillas de expresión (ET)'. No sé si hay una definición precisa para ello. Pero en su uso común, de alguna manera combina "cómo codifica expresiones de álgebra lineal" y "cómo se calcula". Por ejemplo:
Usted codifica la operación del vector
Y se calcula mediante un bucle
En mi opinión, estas son dos cosas diferentes y deben desacoplarse: (1) es una interfaz y (2) una posible implementación. Quiero decir, esta es una práctica común en la programación. Claro (2) podría ser una buena implementación predeterminada, pero en general quiero poder utilizar una implementación especializada y dedicada. Por ejemplo, quiero que una función como
que me llamen cuando estoy codificando (1). Quizás (3) solo usa internamente un bucle como en (2). Pero dependiendo del tamaño del vector, otras implementaciones podrían ser más eficientes. De todos modos, algunos expertos en alto rendimiento pueden implementar y ajustar (3) tanto como sea posible. Entonces, si (1) no se puede asignar a una llamada de (3), prefiero evitar el azúcar sintáctico de (1) y llamar directamente a (3) de inmediato.
Lo que describo no es nada nuevo. Por el contrario, es la idea detrás de BLAS / LPACK:
Si el alcance de BLAS no es suficiente (por ejemplo, no proporciona una función como (3)), entonces se puede ampliar el alcance de BLAS. Entonces, este dinosaurio de los años 60 y 70 se da cuenta con su herramienta de la edad de piedra de una separación limpia y ortogonal de la interfaz y la implementación. Es curioso que (la mayoría) las bibliotecas numéricas de C ++ no alcancen este nivel de calidad de software. Aunque el lenguaje de programación en sí es mucho más sofisticado. Por lo tanto, no sorprende que BLAS / LAPACK siga vivo y desarrollado activamente.
Entonces, en mi opinión, los extraterrestres no son malvados per se. Pero cómo se usan comúnmente en bibliotecas numéricas de C ++ les ganó una muy mala reputación en los círculos de computación científica.
fuente