J'ai l'extrait de code C ++ suivant (la partie C ++ est la classe de profileur qui est omise ici), compilée avec VS2010 (machine Intel 64 bits). Le code multiplie simplement un tableau de flotteurs ( La pièce de lecture à partir de fichier et le profilage (c'est-à-dire que la mesure du temps d'exécution) est omise ici pour la simplicité. P> lorsque code complet est ici: https: // gist .github.com / 1676742 , la ligne de commande de compilation est dans un commentaire dans Les fichiers de données sont ici: p> Arr2 code>) avec un scalaire et met le résultat dans un autre tableau (
arr1 code>):
arrate code> est initialisé à des nombres aléatoires dans la plage [0 1 ], le code fonctionne environ 10 fois plus rapide par rapport à un cas où
arrate code> est initialisé sur un tableau de race dans lequel environ 2/3 des valeurs sont des zéros. J'ai joué avec les options du compilateur
/ fp code> et
/ o code>, qui a changé le temps d'exécution un peu, mais le rapport de 1:10 était approximativement conservé. p>
test.cpp code>. P>
3 Réponses :
C'est probablement parce que vos données "rapides" consistent que des nombres de points flottants normaux, mais que vos données "lentes" contiennent de nombreux nombres dénormalisés.
Quant à votre deuxième question, vous pouvez essayer d'améliorer la vitesse avec ceci (et Traitez tous les nombres dénormalisés comme zéros exacts): p>
Je peux penser à deux raisons pour cela. P>
Premièrement, le prédicteur de la branche peut prendre des décisions incorrectes. Il s'agit d'une cause potentielle de lacunes de performance causées par des modifications de données sans changement de code. Cependant, dans ce cas, il semble très improbable. P>
La deuxième raison possible est que vos données "principalement des zéros" ne consistent pas vraiment de zéros, mais plutôt de presque zéros, ou que vous gardez arr1 code> dans la plage presque zéro . Voir Ce lien Wikipedia . P>
Il n'y a rien d'étrange que les données de i.bin prend plus de temps à traiter: vous avez beaucoup de chiffres comme '1.401e-045 # den' ou '2.214e-043 # den', où #den signifie que le nombre ne peut pas être normalisé à la précision standard du flotteur. Étant donné que vous allez le multiplier par 6.6e-14, vous aurez certainement des exceptions de sousfaction, ce qui ralentit considérablement les calculs. P>
Veuillez vous fournir des versions complètes et compilables des deux tests afin que nous puissions expérimenter avec eux?
Pourrait-il s'agir que lorsque vous passez
0 code> à votre flotteur dans votre matrice piquante, la conversion de
int code> sur
float code> introduit des frais généraux?
Vous ne mettez à jour que les éléments qui ne sont pas 0? Alors, peut-il être que les zéros ne sont pas dans le cache?
@ degedl0r: cette pensée m'ont eue aussi. Cependant, cet argument s'appliquerait uniquement à la première itération de 20 000 car la boucle d'addition traverse toute la matrice.
@aix: hmm oui, vous pourriez avoir raison. Mais vous ne savez jamais que le compilateur génère :) Dans ce cas, il peut allumer la boucle pour les boucles, de sorte que la boucle code> Niter code> est la boucle intérieure, non? Peut-être qu'il génère même
arr1 [n] + = niter * échelle * arr2 [n] code> s'il est vraiment fou;)
Je ne passe pas
0 code> S puisque j'ai lu des données binaires à partir de fichiers. Voir ma réponse modifiée pour les liens vers le code et les données.
@aix: En fait, je ne voulais pas accumuler la somme sur toute l'itération, j'ai juste oublié une ligne code> memset code> - mais de toute façon, cela ne modifie pas les résultats de la durée d'exécution.
Question pour les experts FPU: Pourrait-il être que le FPU considère que 0.0 un nombre sous-formel dans ce scénario? Les OPS de la FP, y compris les sous-formulaires, sont plus lents que les OP ordinaires sur certains FPU, de sorte que cela pourrait l'expliquer si 0 est considéré comme sous-formulaire.
Est-ce que ce devoir? Je demande car les chiffres des fichiers de données semblent mal diriger la manière dont vous interprétez les résultats.
@Danielfischer, les zéros exacts (0,0) ne sont pas considérés comme désormalisés et sont traités rapidement.
@Evenykluev J'espérais et prévu que, mais je ne savais pas. Merci.
@Marksynowiec: Je ne comprends pas votre commentaire - mais non, ce n'est pas des devoirs.
Drôle, une autre question avec le même sous-jacent Problème a montré seulement 3 semaines après celui-ci.