9
votes

Multiplication matricielle plus rapide en C #

J'ai comme petit projet C # qui implique des matrices. Je traite de grandes quantités de données en le divisant dans des morceaux de N-Longueur, traitant les mandrins comme des vecteurs et en multipliant par une matrice VANDERMONDE **. Le problème est que, selon les conditions, la taille des mandrins et une matrice VANDERMONDE ** correspondante peut varier. J'ai une solution générale facile à lire, mais trop lente: xxx

Ceci peut traiter environ 1/4 mégaoctets par seconde sur mon i5 u470 @ 1.33gHz. Je peux rendre cela plus rapide en alignant manuellement la multiplication matricielle: xxx

Ceci peut traiter environ 1 mégre une seconde.

(Veuillez noter que "MOD" fonctionne des opérations sur gf (2 ^ 8) MODULO mon polynôme irréductible préféré.)

Je sais que cela peut être beaucoup plus rapide: après tout, La VANDERMONDE ** matrice est principalement des zéros. Je devrais pouvoir faire une routine ou trouver une routine, qui peut prendre ma matrice et renvoyer une méthode optimisée qui multipliera efficacement les vecteurs par la matrice donnée, mais plus vite. Ensuite, lorsque je donne cette routine une matrice Vandermonde 5x5 (la matrice d'identité), il n'y a tout simplement pas d'arithmétique à effectuer, et les données d'origine sont simplement copiées.

** Veuillez noter: ce que j'utilise le terme "VANDERMONDE", j'entends réellement une matrice d'identité avec un certain nombre de lignes de la matrice Vandermonde en annexe (voir commentaires). Cette matrice est merveilleuse à cause de tous les zéros, et parce que si vous retirez assez de lignes (de votre choix) pour le rendre carré, c'est une matrice inverseuse. Et, bien sûr, j'aimerais utiliser cette même routine pour convertir l'une de ces matrices inversées en une série optimisée d'instructions.

Comment puis-je rendre cette multiplication de matrice plus rapidement?

merci!

(édité pour corriger mon erreur avec la matrice VANDERMONDE)


2 commentaires

La matrice d'identité ou toute matrice qui a des zéros, n'est pas une matrice VANDERMONDE par les définitions de EN.Wikipedia. org / wiki / vandermonde_matrix ou mathworld.wolfram.com/vandermondematrix.html ( ou GVL) mais vous dites que votre matrice a des zéros. Pouvez-vous clarifier votre définition?


Mon erreur. La matrice que je cherche n'est pas vandermonde, mais plutôt une matrice d'identité, avec Vandermonde ajoutée, en tant que lignes supplémentaires. Veuillez vous reporter à CS.TAU.AC.IL/~OHADRODE/SLIDE/ Reedsolomon.pdf Page 11.


4 Réponses :


0
votes

du point de vue des mathématiques

Vous pouvez regarder les espaces propres d'Eigen, les vecteurs d'Eigen, les valeurs d'Eigen. Je ne suis pas sûr de votre application et si cela vous aidera.

Vous pouvez regarder la décomposition LU.

Tous les sujets ci-dessus peuvent être trouvés à Wikipedia

d'une perspective de programmation

Vous pouvez essayer simd, mais ils sont conçus pour les matrices 4x4 pour faire des transformations homogènes de l'espace 3D, principalement pour les graphiques informatiques.

Vous pouvez écrire des algorithmes spéciaux pour vos dimensions les plus courantes.

Utiliser SSE en C # est-il possible?


1 commentaires

Malheureusement, les matrices 4x4 utilisées dans des graphismes 3D sont trop petites et ne fonctionnent pas sur le champ GF (2 ^ 8) dont j'ai besoin.



2
votes

Peut-être que vous pouvez définir une interface matricielle et créer des implémentations à l'exécution à l'aide de reflet.emit .

IMatrix m = MatrixGenerator.CreateMatrix(data);

m.multiplyBy(...)


0 commentaires

3
votes

J'ai vu des solutions à l'aide de la réflexion.emit et j'ai vu des solutions qui impliquent TPL. La vraie réponse ici est, pour la plupart des situations, que vous souhaitez utiliser une bibliothèque existante non gérée telle que Intel MKL via p / invoke. Sinon, si vous utilisez le GPU, vous pouvez accéder à l'approche GPGPU qui irait beaucoup plus vite.

et oui, SSE ainsi que le traitement multicœur est le moyen le plus rapide de le faire sur une CPU. Mais je ne recommanderais pas d'écrire votre propre algorithme - à la place, va chercher quelque chose qui est déjà là-bas. Très probablement, cela finira par être une bibliothèque C ++, éventuellement avec un emballage C #.


2 commentaires

+1. .NET N'en utilise pas de SSE, mais géré C ++ peut envelopper une bibliothèque native C ++, puis utiliser des méthodes / code non gérées pour exécuter des opérations SSE. Ceci est aussi rapide que d'utiliser le GPU, qui ne sera pas plus efficace pour les transformations individuelles (vous utilisez un certain temps sur le téléchargement des données / télécharger les résultats - ceci est pour des choses fortement parallèles).


Mon inquiétude avec SSE ou avec GPU est le champ GF (2 ^ 8) que j'utilise pour effectuer ces opérations. Je doute qu'ils soutiennent ce type de mathématiques.



1
votes

Bien que cela ne accélère pas les mathématiques, vous pouvez au moins utiliser tous vos cœurs avec le parallèle.Pour en .NET 4.0. Microsoft Link


0 commentaires