Pire rendement à l'aide d'Eigen que d'utiliser ma propre classe
Un couple de semaines, j'ai posé une question sur les performances de la multiplication de matrices.
M'a dit que, pour améliorer les performances de mon programme je dois utiliser spécialisées de la matrice des classes plutôt que de ma propre classe.
StackOverflow utilisateurs recommandé:
- uBLAS
- PROPRES
- BLAS
J'ai d'abord voulu utiliser uBLAS cependant la lecture la documentation il s'est avéré que cette bibliothèque ne prend pas en charge multiplication matrice-matrice.
Après tout, j'ai décidé d'utiliser EIGEN bibliothèque. Donc j'ai échangé ma classe matrix pour Eigen::MatrixXd
- cependant il s'est avéré que mon application fonctionne même plus lent qu'avant.
L'heure avant d'utiliser EIGEN a été de 68 secondes, et après avoir échangé ma classe matrix pour PROPRES de la matrice de programme s'exécute 87 secondes.
Parties de programme qui prend le plus de temps ressemble à ça
TemplateClusterBase* TemplateClusterBase::TransformTemplateOne( vector<Eigen::MatrixXd*>& pointVector, Eigen::MatrixXd& rotation ,Eigen::MatrixXd& scale,Eigen::MatrixXd& translation )
{
for (int i=0;i<pointVector.size();i++ )
{
//Eigen::MatrixXd outcome =
Eigen::MatrixXd outcome = (rotation*scale)* (*pointVector[i]) + translation;
//delete prototypePointVector[i]; //((rotation*scale)* (*prototypePointVector[i]) + translation).ConvertToPoint();
MatrixHelper::SetX(*prototypePointVector[i],MatrixHelper::GetX(outcome));
MatrixHelper::SetY(*prototypePointVector[i],MatrixHelper::GetY(outcome));
//assosiatedPointIndexVector[i] = prototypePointVector[i]->associatedTemplateIndex = i;
}
return this;
}
et
Eigen::MatrixXd AlgorithmPointBased::UpdateTranslationMatrix( int clusterIndex )
{
double membershipSum = 0,outcome = 0;
double currentPower = 0;
Eigen::MatrixXd outcomePoint = Eigen::MatrixXd(2,1);
outcomePoint << 0,0;
Eigen::MatrixXd templatePoint;
for (int i=0;i< imageDataVector.size();i++)
{
currentPower =0;
membershipSum += currentPower = pow(membershipMatrix[clusterIndex][i],m);
outcomePoint.noalias() += (*imageDataVector[i] - (prototypeVector[clusterIndex]->rotationMatrix*prototypeVector[clusterIndex]->scalingMatrix* ( *templateCluster->templatePointVector[prototypeVector[clusterIndex]->assosiatedPointIndexVector[i]]) ))*currentPower ;
}
outcomePoint.noalias() = outcomePoint/=membershipSum;
return outcomePoint; //.ConvertToMatrix();
}
Comme Vous pouvez le voir, ces fonctions effectue beaucoup d'opérations matricielles. C'est pourquoi je pensais à l'aide de Eigen permettrait d'accélérer ma demande. Malheureusement (comme je l'ai mentionné ci-dessus), le programme fonctionne plus lent.
Est-il un moyen d'accélérer ces fonctions?
Peut-être que si j'ai utilisé DirectX opérations matricielles, je voudrais obtenir de meilleures performances ?? (toutefois, j'ai un ordinateur portable avec graphique intégré de la carte).
A
, B
, et C
matrix sont les types): C = prod(A, B); C = prec_prod(A, B); C = element_prod(A, B); axpy_prod(A, B, C, true); axpy_prod(A, B, C, false);
Alors qu'est-ce que vous voulez qu'il ne le fait pas..?boost.org/doc/libs/1_46_1/libs/numeric/ublas/doc/blas.htm. Le modèle gmm est général multiplication matrice-matrice.
J'ai aussi trouvé Propres lent. J'ai juste utilisé pour le calcul sur chaque pixel dans une image, dans VS2010 Express avec le Débogage activé, et il a été unusably lent (> 50 * code personnalisé). Je me rends compte qu'il vaudrait mieux dans un communiqué de construire, mais je ne peux même pas faire de débogage avec ceux des temps de chargement. Réfléchir à deux fois avant de l'utiliser pour quoi que ce soit à distance critique pour les performances!
La Performance de Eigen est BEAUCOUP mieux dans les versions release que dans les versions de débogage. Vous avez raison que la vitesse dans le debug est incroyablement lent.
visual studio C++ de la performance en général, est épouvantablement lent dans les versions debug; tous les types de conteneurs standard ne la vérification des limites (et de l'exécution elle-même insère boundschecking même pour les matières premières, tableaux). Si c'est un problème, vous pouvez définir NDEBUG qui désactive ces contrôles; bien sûr, qui permet de rendre votre code plus difficile à déboguer (toujours mieux que de sortir car il ne sera pas en ligne, comme beaucoup).
OriginalL'auteur george | 2011-05-31
Vous devez vous connecter pour publier un commentaire.
Si vous utilisez Eigen du
MatrixXd
types, ceux qui sont dynamiquement la taille. Vous devriez obtenir beaucoup de meilleurs résultats en utilisant la taille fixe les types de e.gMatrix4d
,Vector4d
.Aussi, assurez-vous que vous êtes à la compilation de telles que le code peut obtenir vectorisé; voir la pertinentes Propres à la documentation.
Re votre pensée sur l'utilisation de la 3d de la bibliothèque d'extensions de trucs (D3DXMATRIX etc): c'est OK (si un peu vieux jeu) pour les graphiques de la géométrie (4x4 transforme etc), mais c'est certainement pas grâce à l'accélération GPU (juste bon vieux ESS, je pense). Aussi, notez que c'est de la précision en virgule flottante seulement (vous semblez être mis sur l'utilisation de doubles). Personnellement, je préfèrerais utiliser Eigen que si j'étais réellement coder une application Direct3D.
Eigen appelle un Vector2d, plutôt qu'à une matrice. Je suis surpris de voir si c'est pas déjà définie (depuis Vector2d est mentionné dans la Vectorisation docs ci-dessus comme étant de 16 octets, et comme l'ESS compatible). Si vous devez définir votre propre, tout ça va être, c'est une définition de type Matrice<double, 2, 1> Vector2d;
Changer MatrixXd en Vector2d et Matrix2d j'ai eu seulement 2 meilleur temps. Non, c'est 85 s au lieu de 87.Encore plus lent que si j'utilise mon propre matrice de classe. Étrange 🙁
Vous pouvez créer de taille fixe des matrices de dimension à l'aide de Eigen::Matrice<double, n_rows, n_cols>.
OriginalL'auteur timday
Vous devriez profil et de l'optimiser d'abord l'algorithme, puis la mise en œuvre. En particulier, la posté code est assez innefficient:
Je ne sais pas la bibliothèque, donc je ne vais même pas essayer de deviner le nombre de inutiles temporaires que vous créez, mais un simple refactoriser:
Peut vous faire économiser une bonne quantité de cher multiplications (et encore, probablement temporaire de matrices qui se jeter tout de suite.
OriginalL'auteur David Rodríguez - dribeas
Assurez-vous d'avoir optimisation du compilateur sous tension (par exemple, au moins -O2 sur gcc). Eigen est fortement basé sur un modèle et n'effectuera pas très bien si vous ne tournez pas sur l'optimisation.
Notez que
-o2
signifie "fichier de sortie est2
". Pour les options d'optimisation avec GCC utilisation-O2
(notez la majuscule " O "à la place de petit "o").Wow. Mon code est passé de 29sec à 1,2 sec
OriginalL'auteur Jakob
La version de Eigen utilisez-vous? Ils ont récemment publié 3.0.1, qui est censé être plus rapide que 2.x. Aussi, assurez-vous de jouer un peu avec les options du compilateur. Par exemple, assurez-vous que l'ESS est utilisé dans Visual Studio:
J'utilise Eigen 3.0.1, mais je n'ai pas d'activer les "Permettent d'améliorer le jeu d'instructions". Je vais essayer cela
OriginalL'auteur Bob
Un couple de points.
Pourquoi êtes-vous en multipliant rotation*échelle à l'intérieur de la boucle lorsque le produit aura la même valeur à chaque itération? C'est beaucoup de gaspillage d'efforts.
Vous utilisez dynamiquement la taille des matrices plutôt que fixe la taille des matrices. Quelqu'un d'autre déjà mentionné, et vous avez dit que vous vous êtes rasé de 2 sec.
Vous êtes de passage des arguments comme un vecteur de pointeurs sur des matrices. Cela ajoute un pointeur supplémentaire d'indirection et détruit toute garantie de la localité des données, qui va donner de mauvaises performances du cache.
J'espère que ce n'est pas insultant, mais êtes-vous de compiler en Release ou Debug? Eigen est très lente dans les versions debug, car il utilise beaucoup de trivial basées sur des modèles de fonctions optimisées de la libération, mais qui restent en debug.
En regardant ton code, je suis hésitant à blâmer Propres pour les problèmes de performances. Cependant, la plupart des bibliothèques d'algèbre linéaire (y compris les Propres) ne sont pas vraiment conçues pour votre cas d'utilisation de beaucoup de petites matrices. En général, Eigen sera mieux optimisé pour 100x100 ou de matrices de grandes. Vous avez très bien peut-être mieux à l'aide de votre propre matrice de classe ou le programme de mathématiques des classes d'assistance. Le programme de mathématiques des classes sont complètement indépendants de votre carte vidéo.
OriginalL'auteur Joe
À la recherche de retour à votre précédent post, et le code n', ma suggestion serait d'utiliser l'ancien code, mais d'améliorer son efficacité en déplaçant les choses autour de vous. Je poste sur cette question précédente pour garder les réponses distinctes.
OriginalL'auteur Chris A.