Composition de Filtre Digitaux en compile-time [RESOLU] - C++ - Programmation
Marsh Posté le 19-05-2004 à 18:23:25
Je ne vais absolumment pas pouvoir t'aider étant donné que je ne suis pas assez bon pour ça, mais ça m'intéresse beaucoup car j'ai utilisé ce genre de filtre, et que ça m'intéresserait beaucoup de pouvoir les calculer à la volée, car moi bien sûr je les calculais un par un, puis je faisais le produit de polynôme tout ça avant avec Matlab ..
Marsh Posté le 19-05-2004 à 18:37:56
pourquoi t'utilise pas un tableau ? en optimisant bien, il aura disparu au final
je comprends pas ou tu les donnes tes A et B .. ton operator* il est louche ... il est binaire et en fonction membre ...
question con : tu connais les typedef ?
Marsh Posté le 19-05-2004 à 18:42:57
Taz a écrit : pourquoi t'utilise pas un tableau ? en optimisant bien, il aura disparu au final |
Non, car les coeff ne doivent pas stationner en mémoire , y a du SIMD derriere tout ca et la moindre lecture mémoire me tue les perfs.
Taz a écrit : |
A0,B0 ... sotn les parametres template des filtres f1 et f2.
et filter<M+N-1,....> est le type de retour.
Taz a écrit : |
oui, cela va t il m'aidé ?
Marsh Posté le 19-05-2004 à 19:03:15
1) tu devrais faire un test avec un tableau, tu sera surpris du travail du compilateur. je t'assure, c'est très impressionnant : ne ferme pas la porte. bien sur il faut mettre en place un parcours du tableau, ce qui peut être difficile ...
2) le typedef à quoi il sert ? ben à pas écrire
filter<M+N-1 ,
A0*B0*d<0,0,M,N>::k,
A1*B0*d<1,0,M,N>::k + A0*B1*d<0,1,M,N>::k,
A2*B0*d<2,0,M,N>::k + A1*B1*d<1,1,M,N>::k + A0*B2*d<0,2,M,N>::k,
A3*B0*d<3,0,M,N>::k + A2*B1*d<2,1,M,N>::k + A1*B2*d<1,2,M,N>::k + A0*B3*d<0,3,M,N>::k,
A4*B0*d<4,0,M,N>::k + A3*B1*d<3,1,M,N>::k + A2*B2*d<2,2,M,N>::k + A1*B3*d<1,3,M,N>::k + A0*B4*d<0,4,M,N>::k,
A5*B0*d<5,0,M,N>::k + A4*B1*d<4,1,M,N>::k + A3*B2*d<3,2,M,N>::k + A2*B3*d<2,3,M,N>::k + A1*B4*d<1,4,M,N>::k + A0*B5*d<0,5,M,N>::k,
// ... etc ...
plus d'une fois
sinon je vois pas trop quoi faire ...tu as déjà déroulé à la main ... peut être avec des classes intermédiaires tu peux laisser le compilateur s'en charger ?
sinon tu vas en écrire combien de fois des choses comme ça ? si ça marche, ça vaut vraiment le coup de simplifier ça ?
Marsh Posté le 19-05-2004 à 19:09:34
les filtres, j'en ai plus de 80 dans des boucles critiques.
En scalaire, je gagne déja +110% en vitesse, et en AltiVec, j'evite une PERTE de 95% (en bref je reste aux alentours d'une accél de x8 au lieu de chutait à x1.2) ...
AltiVec et la mémoire c'est le mal je t'assure.
Mais :
1/ Comment ferais tu avec un tabelau, j'ai peut etre oublié une astcue.
2/ Ou placer le typedef ??
3/ Classes intermediaires : je pourrais ecrire un template recursif qui calcule les Ci récursivement ?
Marsh Posté le 19-05-2004 à 19:36:50
oui le calculer récursivement, c'est bien. et si tu as un tableau + un paramètre template entier de comptage, tu te balades sur ton tableau et ça roule bien avec ça
Marsh Posté le 19-05-2004 à 19:53:37
Joel F a écrit : |
un générateur de code?
Marsh Posté le 19-05-2004 à 20:01:51
enfait pour les tableaux, j'ai parlé peut être un peu vite ..; j'en était resté sur l'exemple de , ou il allait me chercher valeur comme il faut, mais là sur un tableau, il est incapable
Code :
|
me génère N-1 addition inlinée
Marsh Posté le 19-05-2004 à 20:02:53
Joel F a écrit : j'ai du mal à voir l'astuche avec le tableau o_O |
bah je pensais qu'il serait capable de travailler correctement : tu as un tableau initialisé littéralement (statiquement), je pensais qu'il aurait était capable d'aller chercher les valeurs ... mais non
Marsh Posté le 27-05-2004 à 15:26:52
Up !
j'ai reflechi à la chose :
La classe filtre :
Code :
|
ORIENTATION est une classe qui définit le sens (vertical ou horizontal du filtre).
TYPE est le type de données du filtre (float, int etc ...)
SIZE est la taille du filtre.
Le filter se rempli via [] ou via , par une surcharge non présente ici.
Je définis * pour les filter de meme orientation par :
Code :
|
ensuite operator() fait ma tambouille SIMD.
Bref il me ne me reste qu'a metaprogrammer le produit des tableaux
Marsh Posté le 27-05-2004 à 15:55:11
Taz a écrit : bah voilà c'est bien plus propre comme ça |
N'est-ce pas ^^
Bon je pense que je peut prendre exemple sur ton StaticAdder ?
Marsh Posté le 27-05-2004 à 16:00:59
ben comme je t'ai dit, je suis un peu déçu, parce que le résultat est disponible à la compilation, mais au lieu d'y être calculé, j'ai juste déroullée la boucle ...
Marsh Posté le 27-05-2004 à 17:18:46
ok, tu me tiens au courant s'il te plaît, ce que tu fais es toujours très intéressant. si tu déroules par bloc, y a peut être moyen de mieux placer tes instructions SIMD, non ?
Marsh Posté le 27-05-2004 à 17:24:38
Taz a écrit : ok, tu me tiens au courant s'il te plaît, ce que tu fais es toujours très intéressant. si tu déroules par bloc, y a peut être moyen de mieux placer tes instructions SIMD, non ? |
Je te montre ce qui se passe avec AltiVec.
On va se placer dans le cas simple du filtre 1x3 horizontal sur une image de flottants.
Je génére les vecteurs C1,C2,C3 qui contiennent le coefficient du filtre :
C1 = [ 1 1 1 1 ]
C2 = [ 2 2 2 2 ]
C3 = [ 1 1 1 1 ]
Ensuite pour chaque vecteur V et W contigues (ie bloc de 4 éléments), j'effectue l'operation suivante ,je note V = [ a b c d ] et W = [ e f g h ]:
V1 = (V,W) >> 1 [ b c d e ]
V2 = (V,W) >> 2 [ c d e f ]
T = C1*V+C2*V1;
R = C3*V2+T;
J'ecris ensuite R dans le tableau résultat.
L'astuce ici est de précalculer els C1 ... Cn pour ne faire qu'une seule boucle. On peut aussi dérouler le calcul de V1,V et de T pour traiter plus de vecteurs simultanement.
Marsh Posté le 27-05-2004 à 17:47:04
Si tu veut je te file mon rapport de DEA si tu veut jeter un oeil
Marsh Posté le 28-05-2004 à 10:22:07
Bon voila une partie de la solution de la composition de filtre.
Code :
|
Que reste il à faire :
-> gérer l'application du filtre à un dataset.
-> gérer les vertical*horizontal.
Question : qui connait une formule pour décomposer des filtres séparables ?
Marsh Posté le 28-05-2004 à 10:55:01
fais gaffe il te manque quelques & par ci par là. niveau const, c'est un poil perfectible.
tip of the day : la définition d'une fonction membre dans la déclaration de la classe est implicitement inline (ARM 9.3.2)
Marsh Posté le 28-05-2004 à 10:55:50
Taz a écrit : fais gaffe il te manque quelques & par ci par là. niveau const, c'est un poil perfectible. |
Hmmm ou ça les & ??
Ok pr le tips
Marsh Posté le 31-05-2004 à 17:35:41
joelF :
Bonjour,
tu utilises quoi, comme librairie FFT, pour le filtrage ?
Marsh Posté le 31-05-2004 à 20:21:54
el muchacho a écrit : joelF : |
Rien, tout à la main optimisé AltiVec pour Power PC G5
Marsh Posté le 31-05-2004 à 20:35:54
A tout hasard, connais-tu FFTW ?
http://www.fftw.org/speed/g5-2GHz/
http://www.fftw.org/accuracy/g5-2GHz/
Marsh Posté le 31-05-2004 à 21:44:06
oui mais je n'utilise pas QUE de la FFT.
Mon but estd e fournir une bibliothéque de haut niveau pour AltiVec pas forcement focaliser sur des problematiques de FFT.
Marsh Posté le 19-05-2004 à 17:48:00
Voila mon problème :
Je devellope une série d'application de calcul assez gourmande en temps.
Parmi ceux ci, il existe une quantité astronomique de Filtre à Réponse
Impulsionelle Fine (FRIF ou FIRF en english). Pour optimiser ces filtrage,
dont les coeffcieint sont fixes, j'ai décidé de mettre en place un mécanisme
basé sur les templates pour accélérer la chose.
Le principe est le suivant :
Soit un filtre F 1x3 de coeff [ -1,0,1 ] (dérivée horizontale), je
declare une instance d'une classe filter :
Ensuite, j'applique ce filtre à une image de la maniére suivante :
Rien de bien fulgurant, l'operateur () de filter<W,H,A1,A2,A3> effectue le filtrage.
Maintenant j'aimerais bien ecrire :
Qui appliquerait successivement le filtre gaussian_x puis grad_x à image.
l'idée est donc de proposer un operateur * sur les filter pour calculer à la compilation
les nouveaux paramétres du filtre composé.
/!\ FORMULES /!\
Soit un filtre F de taille N [ F0 ... FN-1], un filtre G de taille M [ G0 .. GM-1 ]
La composée de F et de G , noté : F o G est un filtre H tel que :
Taille de H : P = M+N-1
Et de Coefficient H0 ... HP tel que :
Hi = Somme de j=0 à i-1 de F(j)*G(i-j)*delta(i,j)
aevc delta(i,j) = 1 si (i-j) < M et j<N, 0 sinon
Concretement, le coefficient est un produit de polynomes, minus un certains nombre
de coefficient non existent. (cf Transformée en Z d'un filtre pour retrouver la formule)
/!\ FIN DES FORMULES /!\
Voila une partie de la solution de la composition de filtre.
Que reste il à faire :
-> gérer l'application du filtre à un dataset.
-> gérer les vertical*horizontal.
Question : qui connait une formule pour décomposer des filtres séparables ?
Message édité par Joel F le 28-05-2004 à 11:02:52