Pourquoi ne vois-je pas une accélération significative lorsque j'utilise le compilateur MATLAB?

StackOverflow https://stackoverflow.com/questions/137011

Question

J'ai beaucoup de bons codes MATLAB qui fonctionnent trop lentement et qui me poseraient un problème difficile à écrire en C. Le compilateur MATLAB pour C ne semble pas beaucoup aider, voire pas du tout. Devrait-il accélérer l'exécution davantage? Est-ce que je suis foutu?

Était-ce utile?

La solution

Je vais faire écho à ce que dwj a dit: si votre code MATLAB est lent, c'est probablement parce qu'il n'est pas suffisamment vectorisé. Si vous faites des boucles explicites alors que vous pourriez effectuer des opérations sur des tableaux entiers, c'est le coupable.

Ceci s'applique également à tous les langages dynamiques orientés tableaux: Langage Perl, Python numérique, MATLAB / Octave, etc. C'est même vrai dans une certaine mesure dans le code compilé C et FORTRAN: les bibliothèques de vectorisation spécialement conçues utilisent généralement main boucles internes codées et instructions SIMD (par exemple, MMX, SSE, AltiVec).

Autres conseils

Si vous utilisez le complément à MATLAB (sur une version récente de MATLAB), alors vous presque certainement pas voir des accélérations du tout. En effet, tout ce que fait le compilateur, c'est de vous donner une façon d'empaqueter votre code afin qu'il puisse être distribué aux personnes ne disposant pas de MATLAB. Il ne le convertit pas en quelque chose de plus rapide (tel que le code machine ou le code C) - il l’enveloppe simplement en C pour que vous puissiez l’appeler.

Pour ce faire, votre code doit être exécuté sur le MCR (MATLAB Compiler Runtime), qui est essentiellement le noyau de calcul MATLAB. Votre code est toujours en cours d’interprétation. Grâce à la pénalité liée à l'invocation du MCR, vous constaterez peut-être que le code compilé s'exécute plus lentement que si vous l'aviez simplement exécuté sur MATLAB.

Autrement dit - vous pourriez dire que le compilateur ne compile pas réellement - au moins dans le sens traditionnel du mot.

Les anciennes versions du compilateur fonctionnaient différemment et des accélérations pouvaient se produire dans certaines situations. Pour prendre Mathwork, allez à

http://www.mathworks.com/support/solutions/ data / 1-1ARNS.html

Selon mon expérience, le code MATLAB lent provient généralement de ne pas vectoriser votre code (c'est-à-dire, écrire des boucles for au lieu de simplement multiplier des tableaux (exemple simple)).

Si vous effectuez des entrées / sorties sur un fichier, veillez à lire les données un par un. Recherchez dans les fichiers d’aide la version vectorisée de fscanf.

N'oubliez pas que MATLAB inclut également un profileur!

Tout d'abord, j'appuie tous les commentaires ci-dessus sur le profilage et la vectorisation.

Pour une perspective historique ...

L'ancienne version de Matlab permettait à l'utilisateur de convertir m fichiers en fonctions mex en analysant au préalable le code m et en le convertissant en un ensemble d'appels à la bibliothèque matlab. Toutes les erreurs vérifiées par ces appels ont été vérifiées par l'interpréteur, mais les anciennes versions de l'interpréteur et / ou de l'analyseur en ligne étaient lentes. Par conséquent, la compilation du fichier m pouvait parfois être utile. Habituellement, cela aide lorsque vous avez des boucles car Matlab est assez intelligent pour intégrer une partie de cela en C. Si vous avez une de ces versions de Matlab, vous pouvez essayer de dire au script mex de sauvegarder le fichier .c et de voir exactement ce que c'est. Faire.

Dans une version plus récente (probablement 2006a et ultérieure, mais je ne m'en souviens pas), Mathworks a commencé à utiliser un compilateur juste-à-temps pour l'interpréteur. En réalité, ce compilateur JIT compile automatiquement toutes les fonctions mex. Par conséquent, le faire explicitement hors ligne n’aide en rien. Depuis lors, chaque version a également fait beaucoup d'efforts pour rendre l'interprète beaucoup plus rapide. Je pense que les nouvelles versions de Matlab ne vous permettent même pas de compiler automatiquement m fichiers en fichiers mex car cela n’a plus de sens.

Le compilateur MATLAB encapsule votre code m et le distribue à un environnement d'exécution MATLAB. Ainsi, la performance que vous voyez dans MATLAB devrait être celle que vous voyez avec le compilateur.

Selon les autres réponses, la vectorisation de votre code est utile. Mais le MATLAB JIT est plutôt bon de nos jours et beaucoup de choses fonctionnent à peu près aussi bien vectorisées que non. Cela ne veut pas dire que la vectorisation ne présente aucun avantage en termes de performances: ce n’est tout simplement pas la solution miracle. La seule façon de vraiment savoir est d'utiliser le profileur pour savoir où votre code voit des goulots d'étranglement. Souvent, il existe des endroits où vous pouvez effectuer une refactorisation locale pour améliorer réellement les performances de votre code.

Il existe plusieurs autres approches matérielles que vous pouvez utiliser pour améliorer les performances. Premièrement, une grande partie du sous-système d’algèbre linéaire est multithread. Vous voudrez peut-être vous assurer que vous l'avez activé dans vos préférences si vous travaillez sur une plate-forme multicœur ou multiprocesseur. Deuxièmement, vous pourrez peut-être utiliser la boîte à outils du calcul parallèle pour tirer davantage parti des multiples processeurs. Enfin, si vous êtes un utilisateur Simulink, vous pourrez peut-être utiliser emlmex pour compiler m-code en c. Ceci est particulièrement efficace pour le travail en point fixe.

Avez-vous essayé de profiler votre code? Vous n'avez pas besoin de vectoriser TOUS votre code, mais uniquement les fonctions qui dominent le temps d'exécution. Le profileur MATLAB vous donnera des indications sur les endroits où votre code passe le plus de temps.

Il y a beaucoup d'autres choses que vous devriez lire sur Conseils pour améliorer les performances dans le manuel MathWorks.

mcc n'accélérera pas votre code - ce n'est pas vraiment un compilateur.

Avant d'abandonner, vous devez exécuter le profileur et déterminer où va votre temps (Outils -> Ouvrir le profileur). En outre, une utilisation judicieuse de " tic " et " toc " peut aider. N'optimisez pas votre code jusqu'à ce que vous sachiez où le temps passe (n'essayez pas de deviner).

N'oubliez pas que dans matlab:

  • les opérations au niveau des bits sont très lentes
  • l'entrée / la sortie du fichier est lente
  • Les boucles
  • sont généralement lentes, mais la vectorisation est rapide (si vous ne connaissez pas la syntaxe vectorielle, apprenez-la)
  • les opérations principales sont très rapides (par exemple, multiplier, fft)
  • si vous pensez pouvoir faire quelque chose de plus rapidement dans C / Fortran / etc, vous pouvez écrire un fichier MEX
  • il existe des solutions commerciales pour convertir matlab en C (google "matlab to c") et elles fonctionnent

Vous pouvez porter votre code sur " Matlab intégré ". puis utilisez Realtime-Workshop pour le traduire en C.

Matlab intégré est un sous-ensemble de Matlab. Il ne prend pas en charge Cell-Arrays, Graphics, Marices de taille dynamique ni certains modes d'adressage Matrix. Le portage vers Matlab intégré nécessite parfois des efforts considérables.

Realtime-Workshop est au cœur des produits de génération de code. Il génère du C générique ou peut optimiser une gamme de plates-formes intégrées. Le plus intéressant pour vous est peut-être xPC-Target, qui traite le matériel à usage général comme une cible intégrée.

Je voterais pour le profilage puis je regarderais quels sont les goulots d'étranglement.

Si le goulot d'étranglement est la matrice mathématique, vous n'allez probablement pas faire mieux ... SAUF un gros problème est l'allocation de tableau. par exemple. si vous avez une boucle:

s = [];
for i = 1:50000
  s(i) = 3;
end

Ceci doit continuer à redimensionner le tableau; il est beaucoup plus rapide de prescrire le tableau (commencez par zéros ou NaN) & amp; remplissez-le à partir de là:

s = zeros(50000,1);
for i = 1:50000
  s(i) = 3;
end

Si le goulot d'étranglement est constitué par l'exécution répétée de nombreux appels de fonction, c'est une tâche difficile.

Si le goulot d'étranglement est un problème que MATLAB ne traite pas rapidement (certains types d'analyse, XML, etc.), j'utiliserais Java, car MATLAB s'exécute déjà sur une machine virtuelle et s'interface très facilement avec des fichiers JAR arbitraires. J'ai regardé interfacer avec C / C ++ et c'est vraiment moche. Microsoft COM est ok (sous Windows uniquement) mais après avoir appris Java, je ne pense pas y revenir un jour.

Comme d'autres l'ont noté, le code Matlab lent résulte souvent d'une vectorisation insuffisante.

Cependant, parfois même un code parfaitement vectorisé est lent. Ensuite, vous avez plusieurs autres options:

  1. Voyez s'il y a des bibliothèques / boîtes à outils que vous pouvez utiliser. Celles-ci étaient généralement écrites pour être très optimisées.
  2. Définissez votre code, repérez les points faibles et réécrivez-les en langage C. La connexion de code C (sous forme de DLL, par exemple) à Matlab est simple et est décrite dans la documentation.

Par compilateur Matlab, vous entendez probablement la commande mcc, qui accélère un peu le code en contournant l’interpréteur Matlab. Ce qui accélèrerait considérablement le code MAtlab (d’un facteur 50-200) c’est l’utilisation du code C réel compilé par la commande mex.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top