J'ai une application C ++ dans laquelle la fonction "Supprimer" est lente à exécuter. Ce qui pourrait causer cela et où devrais-je commencer ma recherche d'une solution? P>
Ce code C ++ est dans un fichier arx fonctionnant à l'intérieur de AutoCAD, qui est essentiellement juste une DLL. P>
L'ordinateur spécifique où Delete est lent est en cours d'exécution Autocad 2011, Windows 7, 64 bits. Les arx pour AutoCAD 2011 doivent être compilés à l'aide de Service Pack de Visual Studio 2008 1. P>
L'ordinateur avec le problème est un ordinateur d'un client. Il n'a pas de version de Visual Studio installé sur elle. P>
sur mon ordinateur de développement, le code n'a aucun problème dans AutoCAD 2011. P>
Pour tester, j'ai un code qui supprime une liste liée. Sur l'ordinateur avec le problème, il faut 0,7 seconde pour supprimer la liste. Sur les ordinateurs et les configurations sans problème, le même code prend 0,02 seconde. Les temps spécifiques ne sont pas importants - les grands différents entre les deux nombres sont. P>
Je me suis assuré d'exécuter la même version du code sur les deux ordinateurs, de sorte qu'il ne s'agit pas d'un problème de construction de débogage par rapport à débogage. P>
5 Réponses :
pourrait être dû à une efficacité de cache différente entre le système de travail / défaillance. Il peut y avoir plus de fragmentation de la mémoire sur le système de défaillance qui provoque le grand suppression de la mémoire cache. Sur un système de repos, les données peuvent se retrouver plus séquentielles et obtenir plus de hits de cache pendant la grande suppression. P>
Essayez le moniteur de compteur de performance Intel? P>
S'il est acceptable et possible, essayez d'utiliser un profileur sur l'ordinateur du client. P>
Vous pouvez essayer AMD CodeAnyste ou le profileur Intel (bien que ça on n'est pas gratuit). P>
Si cela n'est pas possible, ajoutez le code de profilage à votre version de votre version et collecte des résultats du client. Même le code de profilage simple peut vous aider à trouver le vrai goulot d'étranglement. P>
On ne ressemble pas à la suppression elle-même est le problème, mais le problème peut être une autre partie du code. P>
E.g. - Quel est le type de tête-> resval.rstring code>? p>
grossièrement dans l'ordre je les vérifierais: p>
nouveau code> est-il inhabituellement long? Comment la personne Supprimer code> fois distribuée? LI>
ul>
Nous courons dans cela tout le temps. Il n'ya rien de mal à votre code, supprimant des milliers d'articles peut prendre plusieurs secondes (et je l'ai vu atteindre des minutes, même) même en mode de libération. P>
La réponse est de ne pas supprimer. Obtenez vous-même un réel allocateur de mémoire et, au lieu d'allouer individuellement chaque objet, créez un pool de mémoire (ou un tas personnalisé ou tout ce que vous voulez l'appeler). Nedmalloc est ce que nous utilisons et recommandons, et vous pouvez créer un "NEDPOOL". Fondamentalement, une piscine est un bloc de mémoire où vos objets seront alloués. Vous allouez toujours la mémoire pour chaque objet, mais elle est prise à partir de la piscine plutôt que directement du système d'exploitation. P>
Lorsque le délai de suppression est venu, vous supprimez simplement la piscine entière plutôt que de supprimer les objets un par un. Utilisez une piscine différente pour chaque lot d'objets qui expireront en même temps. Vous n'avez pas besoin d'allouer de la mémoire pour toute la piscine, mais vous ne pouvez que supprimer le tout à la fois. P>
La plupart des objets C ++ ont un comportement non défini si vous faites cela. Vous avez au moins besoin d'organiser que les destructeurs des objets contenus soient appelés.
Bien sûr. Vous devez utiliser de nouveau sur place, puis appelez-vous manuellement le destructeur vous-même, mais n'effectuez pas la mémoire.
Comment est générée la rétlienne? De plus, y a-t-il une raison pour laquelle vous allouez et la suppression manuellement des resbufs au lieu d'utiliser ACUTNEWRB et ACUTRELRB? p>
En outre, vous en avez probablement vérifié, mais l'utilisateur dispose-t-il du dessin par défaut chargé dans AutoCAD 2009 2009 et 2011? Sinon, sont les dessins identiques (sauf pour la version acad) et sont-ils situés localement ou sur un lecteur réseau? Vous pouvez également consulter si l'utilisateur dispose des mêmes applications LISP / .NET / ObjectARX exécutées dans les deux cas. En outre, l'AutoCAD 2011 est-il un réseau ou une installation locale? P>
Enfin, vous voudrez peut-être ajouter des balises AutoCAD et ObjectARX à la question. P>
La répertoire est générée à l'aide d'une acutbuildlist. J'utilisais Acutrelrb pour libérer la mémoire, mais tout en profilant du code, j'ai trouvé que la fonction est le problème. Je l'ai réécrit manuellement à la fois de voir si cela résoudrait le problème (ce ne serait pas) et que j'aurais une meilleure idée de ce qui causait le problème. Dans tous les cas, j'exécute le code sur le même dessin.
Combien d'articles étaient dans la liste et quelle était leur taille?
Partagez le code de test que vous utilisez pour référence.
Et êtes-vous de manière statique / dynamique sur les deux systèmes? Et s'il vous plaît confirmer que vous ne comparez pas les constructions de débogage / libération?
Les chiffres donnés indiquent de très grands ensembles de données. Host OS Memory Management va certainement entrer en jeu. Même 0,02 secondes pour une suppression semble très élevée.
Êtes-vous sûr de ne pas comparer les versions de débogage et de libération? La différence est 35 fois!
J'ai ajouté des mises à jour de la question en réponse aux commentaires. Et oui, les listes liées sont Yuck, mais c'est ce que les bibliothèques AutoCAD utilisent pour le passage des données, c'est donc ce que je dois faire face.
Si vous êtes préoccupé par la vitesse, vous pouvez aussi bien supprimer la ligne
tête-> resval.rstring = null; code> mais bien sûr, ce code ne doit pas prendre 0,7 seconde, qu'il s'agisse de débogage ou de libération.
Vous devez obtenir un profileur sur l'ordinateur problématique, soit intrusivement (dans le programme), soit avec un programme externe. De toute façon, il n'est pas utile de faire référence à un faux programme, en particulier une implémentation manuelle de
std :: Liste code> et
std :: chaîne code>, que vous devriez utiliser. (Bien sûr,
std :: list code> est sans doute le conteneur pire, mais il démontre le problème
Supprimer code>, si c'est réellement le problème.)
J'ai eu une petite application qui a calculé des nombres premiers et il a été lent lorsque je le construisie avec VS2008SP1 et plus de deux fois plus rapidement lorsque je le construit avec VS2005 (à la fois en mode de libération). Mon problème était également lié à l'allocation et à la suppression, mais je n'ai pas trouvé la raison d'une telle grande différence entre binaire compilé avec 2 version de VC ++ ... j'aimerais connaître la réponse aussi :)
Basé sur la suggestion de Peterchen, j'ai utilisé Perfmon pour vérifier les défauts de la page. Mon ordinateur a 0 quand ralenti. L'ordinateur problématique avait 100k / second lors du ralenti! Je suis à peu près sûr que c'est le problème.
@David Robison: Un allocator personnalisé - Arena ou Pool - pourrait aider dans ce cas.
Enfin trouvé la source de toutes ces défauts de page: le service de recherche Windows. Disabled que, le total des défaillances de la page a diminué de 3 000 / seconde, et tout fonctionne bien.