2012-09-18 4 views
1

J'ai une bibliothèque qui a quelques algorithmes de traitement d'image, y compris un algorithme de région d'intérêt (culture). Lors de la compilation avec GCC, le vectorizer automatique accélère une grande partie du code mais aggrave les performances de l'algorithme Crop. Y a-t-il un moyen de signaler une certaine boucle à ignorer par le vectorizer ou existe-t-il un meilleur moyen de structurer le code pour de meilleures performances?Auto vectorisation Région d'intérêt (culture)

for (RowIndex=0;RowIndex<Destination.GetRows();++RowIndex) 
{ 
    rowOffsetS = ((OriginY + RowIndex) * SizeX) + OriginX; 
    rowOffsetD = (RowIndex * Destination.GetColumns()); 
    for (ColumnIndex=0;ColumnIndex<Destination.GetColumns();++ColumnIndex) 
    { 
     BufferSPtr=BufferS + rowOffsetS + ColumnIndex; 
     BufferDPtr=BufferD + rowOffsetD + ColumnIndex; 
     *BufferDPtr=*BufferSPtr; 
    } 
} 

SizeX est la largeur de la source OriginX est la gauche de la région d'intérêt OriginY est la partie supérieure de la région d'intérêt

+0

Je ne suis pas sûr d'avoir mal compris votre question. Vous voulez soit marquer cette boucle pour ne pas la vectoriser, soit la restructurer pour de meilleures performances? Cela me semble être une contradiction. Mais en ce qui concerne la performance: Les deux gammes peuvent-elles se chevaucher? Si non: utilisez-vous '__restrict' sur le pointeur pour le rendre clair au compilateur? Pointeraliasing est un grand showstopper pour l'optimisation. D'ailleurs: avez-vous pensé à utiliser 'std :: copy' pour votre boucle interne? Cela pourrait être mieux optimisé et rend votre code plus court. – Grizzly

+0

Cela semble être une contradiction, mais c'est l'idée. La vectorisation dégrade actuellement les performances, donc soit la désactiver pour cette boucle soit améliorer le code sont deux options auxquelles je pourrais penser! Je vais restreindre et copier. – illumi

+0

Vous pourriez vouloir mentionner que la performance pour la culture s'aggrave dans ce cas dans votre question. En l'état, j'ai supposé que la performance de l'algorithme Crop demeurait inchangée par la vectorisation.Au cas où vous ne le sachiez pas encore, l'indicateur '-ftree-vectorizer-verbose = n' pourrait vous aider à obtenir des informations plus concrètes sur ce que fait l'optimiseur et pourquoi. – Grizzly

Répondre

0

Je n'ai pas trouvé quoi que ce soit de changer l'optimisation drapeaux pour une boucle, cependant selon la documentation, vous pouvez utiliser l'attribut optimize (regardez here et here) sur une fonction pour remplacer les paramètres d'optimisation pour cette fonction un peu comme ceci:

void foo() __attribute__((optimize("O2", "inline-functions"))) 

Si vous voulez changer pour plusieurs fonctions, vous pouvez utiliser #pragma GCC optimize pour le définir pour toutes les fonctions suivantes (look here).

Vous devriez donc pouvoir compiler la fonction contenant la culture avec un ensemble différent de drapeaux d'optimisation, en omettant la vectorisation automatique. Cela a l'inconvénient de coder en dur les drapeaux de compilation pour cette fonction, mais c'est le meilleur que j'ai trouvé.

En ce qui concerne la restructuration pour une meilleure performance des deux points je l'ai déjà mentionné dans les commentaires viennent à l'esprit (en supposant que les plages ne peuvent pas se chevaucher):

  • déclarant les pointeurs __restrict pour indiquer au compilateur que ils ne font pas d'alias (la zone pointée par un pointeur ne sera pas accessible par d'autres moyens à l'intérieur de la fonction). La possibilité d'aliasing de pointeur est une pierre d'achoppement majeure pour l'optimiseur, car il ne peut pas facilement réorganiser les accès s'il ne sait pas si écrire à BufferD changera le contenu de BufferS.

  • Remplacement de la boucle interne avec un appel à copier:

    std::copy(BufferS + rowOffsetS, BufferS + rowOffsetS + Destination.GetColumns(), BufferD + rowOffsetD); 
    

    La fonction copy est susceptible d'être assez bien optimisé (expédition probablement les arguments à memmove), de sorte que pourrait faire plus vite votre code, alors que en faisant également votre code plus court (toujours un plus).

+0

L'utilisation de la copie désactive la vectorisation automatique de cette boucle ** et ** fournit des performances légèrement supérieures à celles que j'avais précédemment. Merci! – illumi