2010-04-26 3 views
1

J'essaye d'écrire une Matrix3x3 en utilisant le Vector Floating Point sur l'iPhone, mais je rencontre quelques problèmes. C'est ma première tentative d'écriture d'un assemblage ARM, donc cela pourrait être une solution simple et défaillante que je ne vois pas.VFP Unit Matrix Multipliez le problème sur l'iPhone

J'ai actuellement une petite application en cours d'exécution en utilisant une bibliothèque de maths que j'ai écrite. J'étudie dans les avantages en utilisant l'unité de point flottant de vecteur fournirait ainsi j'ai pris ma matrice multipliez et l'ai converti en asm. Auparavant, l'application fonctionnait sans problème, mais maintenant mes objets disparaissent tous de manière aléatoire. Cela semble être causé par les résultats de ma multiplication de la matrice devenant NAN à un certain point.

Heres le code

IMatrix3x3 operator*(IMatrix3x3 & _A, IMatrix3x3 & _B) 
{ 
    IMatrix3x3 C; 

    //C++ code for the simulator 
#if TARGET_IPHONE_SIMULATOR == true 
    C.A0 = _A.A0 * _B.A0 + _A.A1 * _B.B0 + _A.A2 * _B.C0; 
    C.A1 = _A.A0 * _B.A1 + _A.A1 * _B.B1 + _A.A2 * _B.C1; 
    C.A2 = _A.A0 * _B.A2 + _A.A1 * _B.B2 + _A.A2 * _B.C2; 

    C.B0 = _A.B0 * _B.A0 + _A.B1 * _B.B0 + _A.B2 * _B.C0; 
    C.B1 = _A.B0 * _B.A1 + _A.B1 * _B.B1 + _A.B2 * _B.C1; 
    C.B2 = _A.B0 * _B.A2 + _A.B1 * _B.B2 + _A.B2 * _B.C2; 

    C.C0 = _A.C0 * _B.A0 + _A.C1 * _B.B0 + _A.C2 * _B.C0; 
    C.C1 = _A.C0 * _B.A1 + _A.C1 * _B.B1 + _A.C2 * _B.C1; 
    C.C2 = _A.C0 * _B.A2 + _A.C1 * _B.B2 + _A.C2 * _B.C2; 

//VPU ARM asm for the device 
#else 
    //create a pointer to the Matrices 
    IMatrix3x3 * pA = &_A; 
    IMatrix3x3 * pB = &_B; 
    IMatrix3x3 * pC = &C; 

//asm code 
asm volatile(
      //turn on a vector depth of 3 
      "fmrx r0, fpscr \n\t" 
      "bic r0, r0, #0x00370000 \n\t" 
      "orr r0, r0, #0x00020000 \n\t" 
      "fmxr fpscr, r0 \n\t" 

      //load matrix B into the vector bank 
      "fldmias %1, {s8-s16} \n\t" 

      //load the first row of A into the scalar bank 
      "fldmias %0!, {s0-s2} \n\t" 

      //calulate C.A0, C.A1 and C.A2 
      "fmuls s17, s8, s0 \n\t" 
      "fmacs s17, s11, s1 \n\t" 
      "fmacs s17, s14, s2 \n\t" 

      //save this into the output 
      "fstmias %2!, {s17-s19} \n\t" 

      //load the second row of A into the scalar bank 
      "fldmias %0!, {s0-s2} \n\t" 

      //calulate C.B0, C.B1 and C.B2 
      "fmuls s17, s8, s0 \n\t" 
      "fmacs s17, s11, s1 \n\t" 
      "fmacs s17, s14, s2 \n\t" 

      //save this into the output 
      "fstmias %2!, {s17-s19} \n\t" 

      //load the third row of A into the scalar bank 
      "fldmias %0!, {s0-s2} \n\t" 

      //calulate C.C0, C.C1 and C.C2 
      "fmuls s17, s8, s0 \n\t" 
      "fmacs s17, s11, s1 \n\t" 
      "fmacs s17, s14, s2 \n\t" 

      //save this into the output 
      "fstmias %2!, {s17-s19} \n\t" 

      //set the vector depth back to 1 
      "fmrx r0, fpscr \n\t" 
      "bic r0, r0, #0x00370000 \n\t" 
      "orr r0, r0, #0x00000000 \n\t" 
      "fmxr fpscr, r0 \n\t" 

      //pass the inputs and set the clobber list 
      : "+r"(pA), "+r"(pB), "+r" (pC) : 
      :"cc", "memory","s0", "s1", "s2", "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19" 
      ); 
#endif 
    return C; 
} 

Pour autant que je peux voir qui fait sence. Pendant le débogage, j'ai réussi à remarquer que si je devais dire _A = C avant le retour et après l'ASM, _A ne sera pas nécessairement égal à C ce qui n'a fait qu'augmenter ma confusion. Je pensais que c'était peut-être dû au fait que les pointeurs que je donne à la VFPU étaient incrémentés par des lignes telles que "fldmias %0!, {s0-s2} \n\t" cependant ma compréhension de asm n'est pas assez bonne pour comprendre correctement le problème, ni pour voir une approche alternative à cette ligne de code .

Quoi qu'il en soit, j'espérais que quelqu'un avec une meilleure compréhension que moi serait en mesure de voir une solution, et toute aide serait grandement appréciée, merci :-)

Edit: J'ai trouvé que pC semble être NULL lorsque le code asm est atteint malgré le réglage pC = &C. Je suppose que c'est dû au fait que le compilateur réorganise le code dans un manoir qui le casse? J'ai essayé les diverses méthodes que j'ai vues pour arrêter cela (comme ajouter tout ce qui se rapporte à la liste des entrées - je pense que cela ne devrait même pas être nessaire puisque je liste la mémoire dans la liste) et je reçois toujours les mêmes problèmes.

Éditer # 2: Droit, le problème de mémoire semble avoir été provoqué par moi ne comprenant pas "r0" dans la liste de clobber, cependant la fixation que (si elle est en effet fixée) ne semble pas avoir résolu le problème. J'ai remarqué que la multiplication d'une matrice de rotation par la matrice d'identité ne fonctionne correctement et donne lieu non 0,88 comme la dernière entrée dans la matrice au lieu de 1:

| 0.88 0.48 0 |  | 1 0 0 |  | 0.88 0.48 0 | 
|-0.48 0.88 0 | * | 0 1 0 | = |-0.48 0.88 0 | 
| 0 0 1 |  | 0 0 1 |  | 0 0 0.88| 

Je me suis dit alors que ma logique doit se tromper quelque part, donc je traversé l'assemblée. tout semble bien jusqu'à ce que les derniers "fmacs S17, S14, s2 \ n \ t" où:

s0 = 0 s14 = 0 s17 = 0 
s1 = 0 s15 = 0 s18 = 0 
s2 = 1 s16 = 1 s19 = 0 

donc sûrement le fmacs effectue l'opération:

s17 = s17 + s14 * s2 = 0 + 0 * 1 = 0 
s18 = s18 + s15 * s2 = 0 + 0 * 1 = 0 
s19 = s19 + s16 * s2 = 0 + 1 * 1 = 1 

Cependant, le résultat donne s19 = 0.88 qui m'a laissé encore plus confus: Suis-je mal comprendre comment fonctionne fmacs? (P.S désolé pour ce qui est maintenant devenu une question vraiment longue :-P)

Répondre

0

Résolu le problème! Je ne savais pas que les banques de vecteurs étaient «circulaires».

Les banques 0-7, 8-15, 16-23 et 24-31 peuvent contenir des vecteurs jusqu'à une longueur de 8, et peuvent être utilisées comme vecteurs en indiquant simplement que vous utilisez s16 avec une longueur de 4 par exemple.Cependant, dans mon cas, j'avais utilisé s14 avec une longueur de 3, en supposant que cela me donnerait s14, s15 et s16, mais plutôt parce que sa circulaire reviendrait à s8 - en d'autres termes, j'utilisais s14, s15 et s8 .

J'ai pris beaucoup de temps pour voir cela, donc j'espère que si quelqu'un d'autre a un problème similaire, ils vont trouver ceci :-)