Supposons que je travaille sur un code scientifique en C ++. Lors d'une récente discussion avec un collègue, il a été avancé que les modèles d'expression pouvaient être une très mauvaise chose, rendant potentiellement le logiciel compilable uniquement sur certaines versions de gcc. Soi-disant, ce problème a affecté quelques codes scientifiques, comme mentionné dans les sous-titres de cette parodie de Downfall . (Ce sont les seuls exemples que je connaisse, d'où le lien.)
Cependant, d'autres personnes ont fait valoir que les modèles d'expression sont utiles car ils peuvent générer des gains de performances, comme dans cet article du SIAM Journal of Scientific Computing , en évitant le stockage des résultats intermédiaires dans des variables temporaires.
Je ne sais pas grand-chose sur la métaprogrammation de modèles en C ++, mais je sais que c'est une approche utilisée dans la différenciation automatique et dans l'arithmétique d'intervalle, c'est ainsi que je suis entré dans une discussion sur les modèles d'expression. Étant donné à la fois les avantages potentiels des performances et les inconvénients potentiels de la maintenance (si c'est le bon mot), quand dois-je utiliser des modèles d'expression C ++ en science informatique et quand dois-je les éviter?
la source
Réponses:
Mon problème avec les modèles d'expression est qu'ils sont une abstraction très fuite. Vous passez beaucoup de travail à écrire du code très compliqué pour effectuer une tâche simple avec une syntaxe plus agréable. Mais si vous voulez changer l'algorithme, vous devez jouer avec le code sale et si vous vous trompez avec les types ou la syntaxe, vous obtenez des messages d'erreur complètement inintelligibles. Si votre application correspond parfaitement à une bibliothèque basée sur des modèles d'expression, cela peut valoir la peine d'être considéré, mais si vous n'êtes pas sûr, je recommanderais simplement d'écrire du code normal. Bien sûr, le code de haut niveau est moins joli, mais vous pouvez simplement faire ce qui doit être fait. En tant qu'avantage, le temps de compilation et les tailles binaires diminueront considérablement et vous n'aurez pas à faire face à d'énormes variations de performances en raison du choix du compilateur et de l'indicateur de compilation.
la source
D'autres ont commenté la difficulté d'écrire des programmes ET ainsi que la complexité de la compréhension des messages d'erreur. Permettez-moi de commenter la question des compilateurs: il est vrai qu'il y a quelque temps, l'un des gros problèmes était de trouver un compilateur suffisamment conforme à la norme C ++ pour que tout fonctionne et qu'il fonctionne de manière portable. En conséquence, nous avons trouvé beaucoup de bogues - j'ai 2 à 300 rapports de bogues en mon nom, distribués sur gcc, Intel icc, IBM xlC et pgicc de Portland. Par conséquent, le script de configuration deal.II est un référentiel d'un grand nombre de tests de bogues du compilateur, principalement dans le domaine des modèles, des déclarations d'amis, des espaces de noms, etc.
Mais, il s'avère que les fabricants de compilateurs se sont vraiment mis d'accord: aujourd'hui, gcc et icc passent tous nos tests aujourd'hui et il est facile d'écrire du code portable entre les deux. Je dirais que l'IGP n'est pas loin derrière, mais il a un certain nombre de bizarreries qui ne semblent pas disparaître au fil des ans. xlC, d'autre part, est une toute autre histoire - ils corrigent un bogue tous les 6 mois, mais malgré le dépôt de rapports de bogues avec eux pendant des années, les progrès sont extrêmement lents et xlC n'a jamais été en mesure de compiler deal.II avec succès.
Ce que tout cela signifie, c'est ceci: si vous vous en tenez aux deux gros compilateurs, vous pouvez vous attendre à ce qu'ils fonctionnent juste aujourd'hui. Étant donné que la plupart des ordinateurs et des systèmes d'exploitation en ont aujourd'hui au moins un, cela suffit. La seule plate-forme où les choses sont plus difficiles est le BlueGene, où le compilateur système est généralement xlC, avec tous ses bogues.
la source
J'ai expérimenté un peu avec ET il y a longtemps quand, comme vous l'avez mentionné, les compilateurs étaient toujours en difficulté avec eux. J'ai utilisé la bibliothèque Blitz pour l'algèbre linéaire dans un de mes codes. Le problème était alors d'obtenir le bon compilateur et comme je ne suis pas un programmeur C ++ parfait, d'interpréter les messages d'erreur du compilateur. Ce dernier était tout simplement ingérable. Le compilateur générerait en moyenne environ 1 000 lignes de messages d'erreur. Pas moyen que j'ai pu trouver rapidement mon erreur de programmation.
Vous pouvez trouver plus d'informations sur la page Web oonumerics (il y a les actes de deux ateliers ET).
Mais je resterais loin d'eux ...
la source
Le problème commence déjà avec le terme «modèles d'expression (ET)». Je ne sais pas s'il existe une définition précise. Mais dans son utilisation courante, il associe en quelque sorte «comment vous codez des expressions d'algèbre linéaire» et «comment il est calculé». Par exemple:
Vous codez l'opération vectorielle
Et il est calculé par une boucle
À mon avis, ce sont deux choses différentes et doivent être découplées: (1) est une interface et (2) une implémentation possible. Je veux dire que c'est une pratique courante en programmation. Bien sûr, (2) peut être une bonne implémentation par défaut, mais en général, je veux pouvoir utiliser une implémentation spécialisée et dédiée. Par exemple, je veux qu'une fonction comme
être appelé quand je suis en train de coder (1). Peut-être que (3) utilise simplement en interne une boucle comme dans (2). Mais en fonction de la taille du vecteur, d'autres implémentations pourraient être plus efficaces. Quoi qu'il en soit, un expert en hautes performances peut implémenter et régler (3) autant que possible. Donc, si (1) ne peut pas être mappé à un appel de (3), j'évite plutôt le sucre syntaxique de (1) et j'appelle directement (3) tout de suite.
Ce que je décris n’a rien de nouveau. Au contraire, c'est l'idée derrière BLAS / LPACK:
Si la portée de BLAS n'est pas suffisante (par exemple, elle ne fournit pas une fonction comme (3)), alors on peut étendre la portée de BLAS. Ce dinosaure des années 60 et 70 réalise donc avec son outil de l'âge de pierre une séparation nette et orthogonale de l'interface et de la mise en œuvre. C'est assez drôle que (la plupart) des bibliothèques numériques C ++ n'atteignent pas ce niveau de qualité logicielle. Bien que le langage de programmation lui-même soit beaucoup plus sophistiqué. Il n'est donc pas surprenant que BLAS / LAPACK soit toujours en vie et activement développé.
Donc, à mon avis, les ET ne sont pas mauvais en soi. Mais la façon dont ils sont couramment utilisés dans les bibliothèques numériques C ++ leur a valu une très mauvaise réputation dans les cercles de calcul scientifique.
la source