2011-10-16 1 views
1

Je suis jongler avec l'assistant de performance dans VS2010, celui qui teste l'instrumentation (fonction nombre d'appels et le calendrier.)C++ performance vectorielle résultat non intuitif?

Après avoir appris des vecteurs dans la STL C++, j'ai décidé de voir ce que les informations que je peux obtenir sur la performance de remplir un vecteur avec 1 million d'entiers:

#include <iostream> 
#include <vector> 

void generate_ints(); 

int main() { 
    generate_ints(); 
    return 0; 
} 

void generate_ints() { 
    typedef std::vector<int> Generator; 
    typedef std::vector<int>::iterator iter; 
    typedef std::vector<int>::size_type size; 

    Generator generator; 

    for (size i = 0; i != 1000000; ++i) { 
    generator.push_back(i); 
    } 
} 

Ce que je reçois est: 2402.37 millisecondes de temps écoulé pour ce qui précède. Mais j'ai appris que les vecteurs doivent se redimensionner quand ils manquent de capacité car ils sont contigus dans la mémoire. Donc, je pensais obtenir de meilleures performances en faisant un ajout à ce qui précède était:

generate.reserve(1000000); 

Cependant ce double le temps d'exécution du programme à environ 5000 millisecondes. Voici une capture d'écran des appels de fonction, côté gauche sans la ligne de code ci-dessus et côté droit avec. Je ne comprends vraiment pas ce résultat et cela n'a aucun sens compte tenu de ce que j'ai appris sur la façon de définir une capacité de vecteurs si vous savez que vous allez le remplir avec une tonne est une bonne chose. La spécification de réserve a pratiquement doublé la plupart des appels de fonction.

http://imagebin.org/179302

+0

Je me demande aussi ce qu'est ce _RTC_CheckESP qui est toujours la fonction la plus souvent appelée. –

+1

Comment compilez-vous le code? Quel compilateur, et avec ou sans optimisations? – jalf

+0

Je viens d'installer une nouvelle version de Visual studio ultimate 2010, je n'ai pas fait d'optimisation car je n'ai pas appris comment. Donc, je viens d'appuyer sur le bouton vert essentiellement. En cliquant sur l'assistant de performance, cela fonctionne pour moi. –

Répondre

6

la capture d'écran que vous avez publié, il semble que vous compilez sans optimisation, qui invalident toute analyse comparative que vous faites.

Vous faites un benchmark lorsque vous tenez à la performance, et quand vous vous souciez des performances, vous appuyez sur le bouton "aller plus vite" sur le compilateur, et activer les optimisations. Dire que le compilateur a tendance à ralentir, puis s'inquiéter de la lenteur de son fonctionnement est inutile. Je ne sais pas pourquoi le code devient plus lent lorsque vous insérez un appel reserve, mais dans les versions de débogage, un grand nombre de vérifications d'exécution sont insérées pour intercepter plus d'erreurs, et il est tout à fait possible que l'appel reserve provoque plus de vérifications à être effectué, en ralentissant le code.

Activez les optimisations et voyez ce qui se passe. :)

+0

Et wow quelle différence quand je choisis le mode de libération. J'ai dû apprendre à ce sujet un jour je suppose! –

+1

Bien sûr, une fois que vous activez les optimisations, vous rencontrez probablement un autre problème: tout votre code est entièrement optimisé. Voir quelque chose comme [this] (http://latedev.wordpress.com/2011/10/15/the-joy-of-benchmarks/) pour un exemple de la façon d'éviter cela – jalf

+0

Mais aussi intéressant comment il peut remplir un vecteur avec un million d'ints et je ne vois aucune fonction qui est appelée plus de 35 fois. Je m'attendais à un million d'appels à chaque fois en ajoutant un int mais ce n'est pas ce que je vois arriver. –

0

Avez-vous effectué tous vos tests sous la configuration de version? En outre, essayez d'exécuter en dehors de profiler, dans le cas où vous avez frappé un artefact induit par profiler (ajouter des mesures de temps manuel à votre code - vous pouvez utiliser clock() pour cela).

Aussi, avez-vous fait une faute de frappe et en fait appelé resize au lieu de reserve?