Question

Comment pouvez-vous dire au compilateur de boucles Déroulez en fonction du nombre d'itérations ou certains autre attribut? Ou, Comment transformez-vous sur la boucle d'optimisation dans Visual Studio se déroulant 2005 ?

EDIT:. Par exemple

//Code Snippet 1
    vector<int> b;
    for(int i=0;i<3;++i) b.push_back(i);

Contrairement à

//Code Snippet 2
    vector<int> b;
    b.push_back(0);
    b.push_back(1);
    b.push_back(2);

push_back () est un exemple, je pourrais le remplacer par tout ce qui peut prendre beaucoup de temps.

Mais je lu quelque part que je peux utiliser le code 1 et le compilateur peut déroulez au code 2 si la boucle satisfait à certains critères. Donc, ma question est: comment faites-vous cela? Il y a déjà une discussion sur le SO à laquelle est plus efficace, mais tous les commentaires sur c'est apprécié de toute façon.

Était-ce utile?

La solution

Il est généralement assez simple:. "Vous activez des optimisations"

Si vous dites au compilateur d'optimiser votre code, puis déroulage de boucle est l'une des nombreuses optimisations qu'il essaie d'appliquer.

Gardez à l'esprit que, déroulage est pas toujours va produire un code plus rapide. Il peut provoquer des erreurs de cache (dans les données et le cache d'instructions). Et avec la prédiction de branchement avancée que CPU moderne de, les coûts des branches qui composent une boucle est souvent négligeable.

Parfois, le compilateur peut déterminer que déroulage produirait un code plus lent, et il ne le fera pas.

Autres conseils

En général, vous venez de laisser le compilateur à son travail. Si le nombre de boucles est connu à la compilation, et les optimisations du compilateur sont activées, le compilateur équilibrer la taille de code avec la réduction de la branche et les boucles déroulez déroulable.

Si c'est vraiment pas ce que vous voulez, il y a aussi la possibilité de faire vous-même avec le dispositif de Duff: (de wikipedia)

send(to, from, count)
register short *to, *from;
register count;
{
    register n=(count+7)/8;
    switch(count%8){
    case 0: do{ *to = *from++;
    case 7:     *to = *from++;
    case 6:     *to = *from++;
    case 5:     *to = *from++;
    case 4:     *to = *from++;
    case 3:     *to = *from++;
    case 2:     *to = *from++;
    case 1:     *to = *from++;
        }while(--n>0);
    }
}

Cela vous donne avec un nombre de déroulement itération déterminée d'exécution.

Si elle est la compilation que vous voulez encore dérouler, et construit dans les optimisations ne sont pas ce que vous voulez (si vous voulez un contrôle plus fin), vous pouvez créer un modèle de C ++ pour faire ce que vous voulez. Ceci est une application de modèle assez trivial, et comme il est fait au moment de la compilation, vous ne perdez pas inline de fonction ou d'autres optimisations que le compilateur peut faire en plus.

déroulage Loop ne fera pas comme par magie le code exécuté dans la course en boucle plus rapide. Tout ce qu'il fait est de sauver quelques cycles CPU utilisés pour comparer la variable de boucle. Donc, il est logique dans des boucles très serrées où le corps de la boucle elle-même ne presque rien.

En ce qui concerne votre exemple: Alors que push_back() prend du temps constant amorti, cela ne comprend le cycle occasionnel allocation-copie-deallocate ainsi que la copie des objets réels. Je doute fort que les comparaisons dans la boucle jouent un rôle important par rapport à cela. Et si vous le remplacer par quelque chose d'autre prendre beaucoup de temps, de même.

Bien sûr, cela pourrait se tromper sur une unité centrale de traitement spécifique et droit à un autre. Avec les idiosyncrasies des architectures CPU modernes avec leurs caches, les pipelines d'instructions et les systèmes de prédiction de branche, il est devenu très difficile à déjouer le compilateur dans l'optimisation de code. Que vous essayez d'optimiser une boucle avec un corps « lourd » par il semble dérouler une allusion au fait que vous ne savez pas assez pour faire beaucoup dans ce domaine. (Je suis en train difficile de dire ce que vous ne serez pas offensé. Je suis le premier à admettre que je suis un looser dans ce jeu moi-même.)

Si vous rencontrez des problèmes avec la performance, dans 9 ÉMI 10 cas d'erreurs stupides (éliminant comme la copie d'objets complexes) et l'optimisation des algorithmes et des structures de données est ce que vous devriez regarder.

(Si vous pensez toujours que votre problème tombe dans le 1-out-of-10 catégorie, essayez le compilateur Intel. La dernière fois que je l'ai regardé vous pouvez télécharger une version d'essai gratuite, branché sur VS, a été très facile à installer, et provoqué 0,5% de gain de vitesse dans l'application que je l'ai testé dans.)

Notez que vous dites:

  

push_back () est un exemple, je pourrais le remplacer par tout ce qui peut prendre beaucoup de temps.

En fait, si push_back () (ou tout ce que vous le remplacer par) prend beaucoup de temps, c'est une situation où déroulage boucle serait un gaspillage d'efforts. Looping est généralement pas particulièrement lent; les moments où déroulage de boucle est logique est l'endroit où le travail effectué à l'intérieur de la boucle est très faible -. Dans ce cas, les constructions en boucle peuvent commencer à dominer la transformation de cette séquence d'exécution

Comme je suis sûr que vous aurez dans beaucoup d'autres réponses - ne vous inquiétez pas ce genre de chose à moins que vous réellement constater que c'est un goulot d'étranglement. 99% du temps, il ne sera pas.

Faites un clic droit sur le projet, sélectionnez Propriétés et accédez: texte alt http://img200.imageshack.us/img200/8685/propsm.jpg

boucle WRT déroulage, notez qu'il est généralement admis que MS Visual Studio optimiser la taille plutôt que la vitesse produit en fait un code plus rapide en raison de coups de cache / misses.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top