7
votes

C Structure Structure Speedferinging Vitesse

J'ai une question concernant la vitesse de la derréférance du pointeur. J'ai une structure comme:

TD_RECT *pRect;
double left = pRect->left;
double top = pRect->top;
double right = pRect->right;
double bottom = pRect->bottom;
...
for(i = 0; i < m; i++)
{
   if(p[i].x < left) ...
   if(p[i].x > right) ...
   if(p[i].y < top) ...
   if(p[i].y > bottom) ...
}


5 commentaires

Arrêtez de perdre votre temps avec une optimisation prématurée qui ne fera probablement pas un Smidgen d'une différence.


Peut-être que la fraction d'une smidge est importante, mais si elle le fait, pourquoi ne pas le mesurer?


Pour Win32, pourrais-je utiliser GettickCount () pour mesurer le temps avant et après avoir appelé la boucle pour mesurer la vitesse ou y a-t-il une meilleure façon?


@ user482910 Vous pourriez, mais assurez-vous que vous êtes en moyenne sur plusieurs variables (comme un million +), car il y a une probabilité modérée d'un passage de contexte à un autre processus pendant que votre programme est exécuté.


"Je manque MSDOS" - maintenant Il y a trois mots que je n'avais jamais pensé entendre :-)


5 Réponses :


1
votes

Je pense que le second cas est susceptible d'être plus rapide parce que vous n'êtes pas la déséroférance du pointeur de prect sur chaque itération de la boucle.

Pratiquement, un compilateur effectuant une optimisation peut le remarquer et il pourrait ne pas y avoir de différence dans le code généré, mais la possibilité de PRECT étant un alias d'un élément de P [] pourrait empêcher cela.


0 commentaires

12
votes

Vous trouverez probablement que cela ne fera pas la différence avec les compilateurs modernes. La plupart d'entre eux effectueraient probablement une subexpréation commune d'élimination des expressions qui ne changent pas dans la boucle. Il n'est pas sage de supposer qu'il existe une simple mappage unique entre vos déclarations C et code de montage. J'ai vu le code de la pompe GCC qui mettrait la honte de mes compétences d'assembleur.

Mais ce n'est ni une question C ni C ++ depuis la norme ISO ne manda pas comment cela se fait. La meilleure façon de vérifier est sûre de générer le code de l'assembleur avec quelque chose comme GCC -S et examinez les deux cas en détail.

Vous aurez également plus de retour sur votre investissement si vous vous échapperez de ce type de micro-optimisation et concentrez-vous davantage sur le niveau macro, tel que la sélection d'algorithmes etc.

et, comme pour toutes les questions d'optimisation, mesure, ne devinez pas! Il y a trop de variables qui peuvent l'affecter, vous devez donc comparer différentes approches dans l'environnement cible et avec réaliste Données.


6 commentaires

Je demande parce que la fonction que j'écris est de couper des polygones pour des cartes vectorielles contenant des millions de sommets ... Tout un peu de vitesse que je peux en sortir aidera parce que je dois clipser chaque section à 1 degrés.


C'est très bien. La bonne chose à faire est de faire fonctionner des repères réels car cela dépend d'un grand nombre de facteurs, dont très peu, nous connaissons. Au minimum, votre machine cible, votre compilateur, la CPU, d'autres problèmes architecturaux tels que les sous-systèmes de mémoire et d'E / S, la composition de vos données, le niveau d'optimisation, etc.


Que vous ayez des millions d'entre eux, regardez mon commentaire ci-dessous. Créez un index sur votre carte de vecteur (c'est p?), Trié par x et par y. (Reste-t-il assez statique?). Ou triez-le sur x et avoir un index sur y. Utilisez une recherche binaire pour trouver tous les X à droite, tout y bas. Donc, si vous avez dit 4 millions de comparaisons pour chaque, 88 Total, au lieu des 16 millions, vous avez maintenant!


Eh bien, chaque partie de la carte de vecteur est structurée dans une zone spécifique (ESRI Shapefiles) ... Donc, j'ai la zone générale de chacun de l'appeler rapidement ... mais je dois ensuite diviser chacune de ces sections en 1 degré de zones carrées.


+1 pour " mesure, ne devinez pas! " BTW, ESRI Shapefiles? Je ressens ta douleur.


ouais sérieusement ... Je ne comprends pas pourquoi quelqu'un mettrait deux commandes d'octets différents dans une spécification de fichier



0
votes

Un compilateur d'optimisation constatera que les accès de la structure sont invariants en boucle et donc un Code de boucle-invariant Motion , faire ressembler à vos deux cas.


0 commentaires

3
votes

Ce n'est pas susceptible d'être une différence critique de performance extrêmement performante. Vous pouvez profiler faire chaque option plusieurs fois et voir. Assurez-vous que vos optimisations de compilateur définies dans le test.

En ce qui concerne stocker les doubles, vous pouvez obtenir des performances à l'aide de Const. Quelle est la taille de votre tableau?

En ce qui concerne l'utilisation d'un pointeur arithmétique, cela peut être plus rapide, oui.

Vous pouvez optimiser instantanément si vous connaissez la gauche à droite afin que vous puissiez mettre dans "autre".

Votre grande optimisation, s'il en existe un, viendrait de ne pas avoir à boucler à travers tous les éléments de votre réseau et ne pas avoir à effectuer 4 vérifications sur toutes.

Par exemple, si vous êtes indexé ou trié votre tableau sur X et Y, vous seriez capable, à l'aide de la recherche binaire, pour trouver toutes les valeurs atteignant x


0 commentaires

0
votes

Je serai surpris si même un compilé totalement non optimisé (- O0) produira un code différent pour les deux cas présentés. Afin d'effectuer toute opération sur un processeur moderne, les données doivent être chargées dans des registres. Donc, même lorsque vous déclarez des variables automatiques, ces variables n'existeront pas dans la mémoire principale, mais plutôt dans l'un des processeurs des registres de points flottants. Ce sera vrai même lorsque vous ne déclarez pas vous-même les variables vous-même et que je n'attends donc aucune différence dans le code de machine généré, même si vous déclarez les variables temporaires de votre code C ++.

Mais comme d'autres les ont dit, compilez le code dans l'assembleur et voyez par vous-même.


0 commentaires