web-dev-qa-db-fra.com

Compromis de performance - Quand MATLAB est-il meilleur / plus lent que C / C ++

Je suis conscient que C/C++ est un langage de bas niveau et génère un code machine relativement optimisé lorsque nous le comparons à tout autre langage de haut niveau. Mais je suppose qu'il y a bien plus que cela, ce qui ressort également de la pratique.

Lorsque je fais des calculs simples comme la moyenne montecarlo d'une collection d'échantillons gaussiens, je vois qu'il n'y a pas beaucoup de différence entre une implémentation C++ ou MATLAB, parfois en fait MATLAB fonctionne un peu mieux dans le temps.

Lorsque je passe à des simulations à plus grande échelle avec des milliers de lignes de code, la vraie image apparaît lentement. Les simulations C++ montrent des performances supérieures comme 100 fois mieux en complexité temporelle qu'une implémentation MATLAB équivalente.

La plupart du temps, le code en C++ est à peu près série et aucune optimisation hi-fi n'est effectuée explicitement. Alors que, à ma connaissance, MATLAB fait intrinsèquement beaucoup d'optimisation. Cela apparaît par exemple lorsque j'essaie de générer un énorme morceau d'échantillons aléatoires, alors que l'équivalent en C++ en utilisant une bibliothèque comme IT ++/GSL/Boost fonctionne relativement plus lentement (l'algorithme utilisé est le même, à savoir mt19937).

Ma question est simplement de savoir s'il y a un compromis plus simple entre MATLAB/C++ dans les performances. Est-ce juste comme ce que les gens disent, "Chaque fois que vous le pouvez, C/C++ est le meilleur" (Le plus expérimenté)?. Dans une perspective différente, "À quoi sert MATLAB, autre que le confort?"

Soit dit en passant, je ne vois pas le paramètre d'efficacité de codage être significatif ici, en pensant au même programmeur dans les deux cas. Et aussi, je pense que les autres alternatives comme python, R ne sont pas pertinentes ici. Mais la dépendance à l'égard des bibliothèques spécifiques que nous utilisons devrait être intéressante.

[Je suis doctorant en théorie du codage dans les systèmes de communication. Je fais des simulations en utilisant matlab/C++ tout le temps, et j'ai une expérience raisonnable de coder quelques 10K de lignes dans les deux cas]

45
Loves Probability

J'utilise Matlab et C++ depuis environ 10 ans. Pour chaque algorithme numérique implémenté pour mes recherches, je pars toujours du prototypage avec Matlab, puis je traduis le projet en C++ pour obtenir une amélioration des performances de 10x à 100x (je ne plaisante pas). Bien sûr, je compare le code C++ optimisé au code Matlab entièrement vectorisé. En moyenne, l'amélioration est d'environ 50x.

Il y a beaucoup de subtilités derrière les deux langages de programmation, et voici quelques malentendus:

  1. Matlab est un langage de script mais C++ est compilé

    Matlab utilise le compilateur JIT pour traduire votre script en code machine, vous pouvez améliorer votre vitesse au maximum d'un facteur 1,5 à 2 en utilisant le compilateur fourni par Matlab.

  2. Le code Matlab peut être entièrement vectorisé mais vous devez optimiser votre code à la main en C++

    Le code Matlab entièrement vectorisé peut appeler des bibliothèques écrites en C++/C/Assembly (par exemple Intel MKL). Mais le code C++ ordinaire peut être raisonnablement vectorisé par les compilateurs modernes.

  3. Les boîtes à outils et routines fournies par Matlab devraient être très bien ajustées et devraient avoir des performances raisonnables

    Non. À part les routines d'algèbre linéaire, les performances sont généralement mauvaises.

Les raisons pour lesquelles vous pouvez gagner des performances 10x ~ 100x en C++ par rapport au code Matlab vectorisé:

  1. Appeler des bibliothèques externes (MKL) dans Matlab coûte du temps.

  2. La mémoire dans Matlab est allouée et libérée dynamiquement. Par exemple, multiplication de petites matrices:
    A = B*C + D*E + F*G
    nécessite que Matlab crée 2 matrices temporaires. Et en C++, si vous allouez votre mémoire au préalable, vous ne créez AUCUN. Et maintenant, imaginez que vous bouclez cette instruction 1000 fois. Une autre solution en C++ est fournie par la référence Rvalue C++ 11. C'est l'une des plus grandes améliorations en C++, maintenant le code C++ peut être aussi rapide que le code C ordinaire.

  3. Si vous souhaitez effectuer un traitement parallèle, le modèle Matlab est multi-processus et la méthode C++ est multi-thread. Si de nombreuses petites tâches doivent être parallélisées, C++ fournit un gain linéaire jusqu'à plusieurs threads, mais vous pouvez avoir un gain de performances négatif dans Matlab.

  4. La vectorisation en C++ implique l'utilisation intrinsèque/Assembly, et parfois la vectorisation SIMD n'est possible qu'en C++.

  5. En C++, il est possible pour un programmeur expérimenté d'éviter complètement le manque de cache L2 et même le cache L1, poussant ainsi le CPU à sa limite de débit théorique. Les performances de Matlab peuvent être inférieures à C++ d'un facteur 10x pour cette seule raison.

  6. En C++, les instructions de calcul intensif peuvent parfois être regroupées en fonction de leurs latences (code soigneusement dans Assembly ou intrinsèques) et des dépendances (la plupart du temps se fait automatiquement par le compilateur ou le matériel CPU), de telle sorte que théorique IPC = (les instructions par cycle d'horloge) peuvent être atteintes et les pipelines CPU sont remplis.

Cependant, le temps de développement en C++ est également un facteur 10 fois supérieur à Matlab!

Les raisons pour lesquelles vous devriez utiliser Matlab au lieu de C++:

  1. Visualisation de données. Je pense que ma carrière peut continuer sans C++ mais je ne pourrai pas survivre sans Matlab juste parce qu'il peut générer de belles parcelles!

  2. Routines et boîtes à outils intégrées à faible efficacité mais mathématiquement robustes. Obtenez d'abord la bonne réponse, puis parlez d'efficacité. Les gens peuvent faire des erreurs subtiles en C++ (par exemple, convertir implicitement double en int ) et obtenez une sorte de résultats corrects.

  3. Exprimez vos idées et présentez votre code à vos collègues. Le code Matlab est beaucoup plus facile à lire et beaucoup plus court que C++, et le code Matlab peut être correctement exécuté sans compilateur. Je refuse simplement de lire le code C++ des autres. Je n'utilise même pas C++ GNU bibliothèques scientifiques car la qualité du code n'est pas garantie. Il est dangereux pour un chercheur/ingénieur d'utiliser une bibliothèque C++ comme boîte noire et de prendre la précision comme accordée Même pour les bibliothèques C/C++ commerciales, je me souviens que le compilateur Intel avait une erreur sign dans sa fonction sin () l'année dernière et des problèmes de précision numérique se sont également produits dans MKL.

Dernier point mais non le moindre:

Parce qu'une fois le code Matlab vectorisé, il ne reste plus grand-chose pour un programmeur à optimiser, les performances du code Matlab sont beaucoup moins sensibles à la qualité du code par rapport au code C++. Par conséquent, il est préférable d'optimiser les algorithmes de calcul dans Matlab, et les algorithmes légèrement meilleurs ont normalement des performances légèrement meilleures dans Matlab. D'autre part, le test d'algorithme en C++ nécessite un programmeur décent pour écrire des algorithmes optimisés plus ou moins de la même manière, et pour s'assurer que le compilateur n'optimise pas les algorithmes différemment.

Mon expérience récente en C++ et Matlab:

J'ai réalisé plusieurs grands outils d'analyse de données Matlab au cours de la dernière année et j'ai souffert de la lenteur de Matlab. Mais j'ai pu améliorer la vitesse de mon programme Matlab de 10 fois grâce aux techniques suivantes:

  • Exécutez/profilez le script Matlab, réimplémentez les routines critiques en C/C++ et compilez avec MEX. Les routines critiques sont généralement logiquement simples mais numériquement lourdes. Cela améliore la vitesse de 5 fois.

  • Simplifiez les fichiers ".m" livrés avec les boîtes à outils Matlab en commentant toutes les vérifications de sécurité et les calculs de paramètres de sortie inutiles. N'oubliez pas que le code modifié ne peut pas être distribué avec le reste des scripts utilisateur. Cela améliore la vitesse d'un autre 2x (après C/C++ et MEX).

Le code amélioré est de ~ 98% dans Matlab et de ~ 2% en C++.

Je crois qu'il est possible d'améliorer la vitesse d'un autre 2x (total 20x) si l'outil entier est codé en C++, c'est une amélioration de la vitesse ~ 100x des routines de calcul. Les E/S du disque dur domineront alors le temps d'exécution du programme.

Question pour les ingénieurs Mathworks:

Lorsque le code Matlab est entièrement vectorisé, l'un des facteurs limitant les performances est l'opération d'indexation matricielle. Par exemple, une opération de différence finie doit être effectuée sur la matrice A qui a une dimension de 5000x5000:

B = A(:,2:end)-A(:,1:end-1)

L'opération d'indexation matricielle rend le code Matlab plusieurs fois plus lent que le code C++. Les performances d'indexation matricielle peuvent-elles être améliorées?

98
PhD AP EcE

D'après mon expérience (plusieurs années de vision par ordinateur et de traitement d'image dans les deux langues), il n'y a pas de réponse simple à cette question, car les performances de Matlab dépendent fortement (et bien plus que les performances C++) de votre style de codage.

Généralement, Matlab encapsule les bibliothèques d'algèbre linéaire classiques basées sur C++/Fortran. Donc, quelque chose comme x = A\b va être très rapide. De plus, Matlab fait un bon travail en choisissant le solveur le plus efficace pour ces types de problèmes, donc pour x = A\b Matlab examinera la taille de vos matrices et choisira les routines de bas niveau appropriées.

Matlab brille également dans la manipulation de données de grandes matrices si vous "vectorisez" votre code, c'est-à-dire si vous évitez les boucles for et utilisez des tableaux d'index ou des tableaux booléens pour accéder à vos données. Ce truc est hautement optimisé.

Pour d'autres routines, certaines sont écrites en code Matlab, tandis que d'autres pointent vers une implémentation C/C++ (par exemple le truc Delaunay). Vous pouvez vérifier cela vous-même en tapant edit some_routine.m. Cela ouvre le code et vous voyez s'il s'agit uniquement de Matlab ou simplement d'un wrapper pour quelque chose de compilé.

Matlab, je pense, est principalement pour le confort - mais le confort se traduit par du temps de codage et, finalement, de l'argent, c'est pourquoi Matlab est utilisé dans l'industrie. En outre, il est facile à apprendre pour les ingénieurs d'autres domaines que l'informatique, avec peu de formation en programmation.

10
DCS

En tant que doctorant et utilisateur de Matlab depuis 10 ans, je suis heureux de partager mon POV:

Matlab est un excellent outil pour développer et prototyper des algorithmes, en particulier lorsqu'il s'agit d'interfaces graphiques, d'analyses de haut niveau (domaine fréquentiel, optimisation LS, etc.): codage rapide, syntaxe puissante (pensez à [], {} ,: etc.).

Dès que votre chaîne de traitement est plus stable et définie et que les dimensions des données augmentent, passez en C/C++.

La limite principale de Matlab augmente lorsque l'on considère que son langage est de type script: tant que vous évitez tout cicle (en utilisant arrayfun, cellfun ou d'autres procédures matricielles), les performances sont élevées car le sous-programme appelé est à nouveau en C/C++.

5
Fabio Veronese

Il est difficile de répondre à votre question. En général, C++ est plus rapide, mais si vous utilisez les algorithmes bien écrits de Matlab, il peut surpasser C++. Dans certains cas, Matlab peut paralléliser votre code, ce qui doit être fait manuellement dans de nombreux cas pour C++. Mathlab peut exporter du code C++.

Ma conclusion est donc que vous devez mesurer la performance des deux programmes pour obtenir une réponse. Mais ensuite, vous comparez vos deux implémentations et non Matlab et C++ en général.

4
usr1234567

Matlab fait très bien avec les opérations d'algèbre linéaire et de tableau/matrice, car ils semblent avoir fait quelques optimisations supplémentaires sur les opérations sous-jacentes - si vous voulez battre Matlab là-bas, vous auriez besoin d'une bibliothèque BLAS/LAPACK optimisée de la même manière.

En tant que langage interprété, Matlab perd du temps chaque fois qu'une fonction Matlab est appelée, en raison de la surcharge interne, ce qui signifiait traditionnellement que les boucles Matlab étaient lentes. Cela a été quelque peu atténué ces dernières années grâce à une amélioration significative du compilateur JIT (recherche de questions "performances" sur Matlab sur SO pour des exemples). En conséquence de la surcharge de l'appel de fonction, tous les Fonctions Matlab non implémentées en C/C++ en arrière-plan (appelez edit functionName pour voir s'il est écrit en Matlab) risque d'être plus lent qu'un homologue C/C++.

Enfin, Matlab tente d'être convivial et peut effectuer des vérifications d'entrée "inutiles" qui peuvent prendre du temps (en raison de la surcharge des appels de fonction). Par exemple, si vous savez que ismember obtient des entrées triées, vous pouvez appeler ismembc directement (la fonction compilée en arrière-plan), ce qui vous fait gagner beaucoup de temps.

4
Jonas

Je pense que vous pouvez considérer la différence en quatre volets au moins.

  1. Compilé vs interprété
  2. Fortement typé vs Dynamiquement typé
  3. Performance vs prototypage rapide
  4. Force spéciale

Pour 1-3 peut être facilement généralisé en comparaison entre deux familles de langages de programmation.

Pour 4, MATLAB est optimisé pour les opérations matricielles. Donc, si vous pouvez vectoriser plus de code dans MATLAB, les performances peuvent être considérablement améliorées. Inversement, si plusieurs loops sont nécessaires, n'hésitez pas à utiliser C++ ou créez un fichier mex.

C'est une question difficile après tout.

4
Ray

J'ai vu une amélioration de la vitesse de 5,5 fois lors du passage de MATLAB à C++. C'était pour un contrôleur de robot - beaucoup de boucles et de résolution d'odes. J'ai passé de nombreuses heures à essayer d'optimiser le code MATLAB, presque jamais à optimiser le C++ (je suis sûr qu'il aurait pu être 10 fois plus rapide avec un peu plus d'effort).

Cependant, il était facile d'ajouter une interface graphique pour le code MATLAB, donc je l'utilise toujours plus souvent. Comme d'autres l'ont dit, c'était agréable de faire un prototype en premier sur MATLAB. Cela a rendu l'implémentation sur C++ beaucoup plus simple.

3
AndyZe

Outre la vitesse du programme final, vous devez également prendre en compte le temps de développement total de votre code, c'est-à-dire non seulement le temps d'écrire, mais aussi de déboguer, etc. Matlab (et son équivalent open-source, - Octave ) peut être bon pour le prototypage rapide en raison de ses capacités de visualisation.

Si vous utilisez du C++ simple (c.-à-d. Pas de bibliothèques matricielles), cela peut vous prendre beaucoup plus de temps pour écrire du code C++ équivalent au code Matlab (par exemple, il pourrait être inutile de passer 10 heures à écrire du code C++ qui ne dure que 10 secondes plus rapide, par rapport à un programme Matlab qui a pris 5 minutes pour écrire).

Cependant, il existe des bibliothèques de matrices C++ dédiées, telles que Armadillo , qui fournissent une API de type Matlab. Cela peut être utile pour écrire du code critique pour les performances qui peut être appelé depuis Matlab, ou pour convertir du code Matlab en "vrais" programmes.

2
mtall

Certains codes Matlab utilisent des fictions d'algèbre linéaire standard avec du multithreading intégré. Il semble donc qu'ils soient plus rapides qu'un code C séquentiel.

2
Alex Granit