1

J'ai une fonction dans mon programme qui préforme tout un tas de maths en virgule flottante. Il renvoie un tableau de valeurs qui n'est pas encore utilisé dans mon programme pour le moment. Je veux tester ce morceau de code pour la vitesse sous optimisations maximales, mais comme le code n'est pas utilisé, le compilateur saute commodément la fonction et je ne peux pas avoir de temps dessus. Comment forcer le compilateur à exécuter cette section de code sous les optimisations maximales même si le résultat n'est pas utilisé (je veux que l'ordinateur me donne juste une idée de la vitesse d'exécution de la section).Comment forcer une section de code inachevée à s'exécuter même sous des optimisations maximales?

Je suis en Visual C++ 2008.

+0

Ne serait-il pas plus simple d'utiliser le résultat? Comment proposez-vous de comparer les optimisations vraiment maximales si vous avez l'intention d'en désactiver un ou plusieurs (en supprimant le code inutilisé)? –

+1

Je pensais plus à un hack qu'à un truc sympa: Si ça renvoie un tas de maths en virgule flottante, quand il retourne ceci, utilisez rand() pour imprimer 1 point flottant depuis le tableau. De cette façon, le compilateur ne peut jamais omettre de calculs, car il ne sait pas lequel il aura besoin plus tard. Je ne connais pas de manière "élégante". – Yuri

Répondre

2

Je suis sûr qu'il y a beaucoup de trucs du compilateur, mais le plus simple est de donner l'impression que vous utilisez la valeur. Dans ce cas, passez simplement le tableau retourné à une autre fonction. L'autre fonction n'a pas besoin de faire quoi que ce soit, mais cela devrait suffire à convaincre le compilateur que vous avez besoin des résultats.

Si vous trouvez que votre seconde fonction vide est également optimisée, il suffit de la coller dans une bibliothèque partagée (DLL) et il est impossible pour le compilateur de savoir comment il est utilisé.

Comment vous allouez le résultat peut également changer cela. Si vous passez un pointeur à la fonction d'origine, vous pouvez lui passer un pointeur de tas. Comme ce pointeur peut être utilisé ailleurs, il est peu probable que le compilateur puisse optimiser le code, car il n'a aucune idée si les résultats seront utilisés ou non.


Vous pouvez également utiliser légitimement les données. Il est logique de vérifier les résultats dans une autre fonction. Si vous effectuez des tests de performance, placez simplement cette partie de vérification en dehors de la section temporisée. C'est généralement comme ça que je fais de tels tests de performance (assurez-vous que le résultat est vérifié/utilisé).

+0

Donc, il semble que la réponse simple est d'utiliser réellement les résultats d'une certaine manière ... ok, je peux vivre avec ça. Je vais créer une variable qui résume chacun des résultats et l'imprime à la fin du programme. – Faken

3

Vous pouvez utiliser SecureZeroMemory() pour écraser le résultat après avoir atteint reçu de la fonction. Vous n'avez même pas besoin d'écraser tout le résultat, un seul élément de tableau sera suffisant, peut-être vous pouvez même passer zéro comme "nombre d'octets", de sorte que rien n'est fait par la fonction.

Cela fera l'affaire sous Windows - SecureZeroMemory() est destiné à ne jamais être optimisé par le compilateur. L'utiliser est assez simple et c'est plutôt rapide.

0

si vous utilisez Visual Studio le code ici fonctionnerait, mais idon't connaissent d'autres solutions pour gcc

#pragma optimize("", off) 
. 
. 
. 
#pragma optimize("", on) 
+2

Cela ne marchera pas - il * veut * optimiser le code! – Gabe

2

C'est ce qu'un cas de test est pour. Ecrire un cas de test dans un binaire séparé (même juste dans la méthode main()) qui définit une variable locale throwaway au résultat de la fonction. Temps d'utilisation de votre méthode préférée (par exemple en capturant le temps (NULL) immédiatement avant et après l'affectation et en imprimant la différence de temps). Vous devriez avoir une bonne idée de la durée de cette course.

EDIT: le temps (NULL) est une précision d'une seconde entière = mauvais et mauvais. Utilisez clock(), comme indiqué here, pour obtenir la précision la plus précise dans la bibliothèque standard C/C++.

+1

Je recommande d'exécuter le code dans une boucle lorsque vous le chronométrer. Il est trop facile d'obtenir des lectures erronées et des erreurs aléatoires quand on a affaire à de si petits intervalles de temps. –

+0

Le compilateur peut toujours ignorer le résultat s'il voit qu'il n'est pas utilisé par la fonction de test. –

+0

+1 Cody, exécutez définitivement le devoir plusieurs fois. Cela devrait également aider à donner au compilateur un indice qu'il ne devrait pas être optimisé. – darvids0n

Questions connexes