2015-12-08 1 views
0

J'ai écrit un code pour ajouter deux tableaux en utilisant des instructions KNC avec des vecteurs longs de 512 bits sur le coprocesseur Xeon Phi intel. Cependant, j'ai une partie de segmentation dans la partie d'assemblage en ligne.erreur de segmentation pour `vmovaps '

Ici, il est mon code:

int main(int argc, char* argv[]) 
{ 
    int i; 
    const int length = 65536; 
    const int AVXLength = length/16; 
    float *A = (float*) aligned_malloc(length * sizeof(float), 64); 
    float *B = (float*) aligned_malloc(length * sizeof(float), 64); 
    float *C = (float*) aligned_malloc(length * sizeof(float), 64); 
    for(i=0; i<length; i++){ 
      A[i] = 1; 
      B[i] = 2; 
    } 

    float * pA = A; 
    float * pB = B; 
    float * pC = C; 
    for(i=0; i<AVXLength; i++){ 
     __asm__("vmovaps %1,%%zmm0\n" 
        "vmovaps %2,%%zmm1\n" 
        "vaddps %%zmm0,%%zmm0,%%zmm1\n" 
        "vmovaps %%zmm0,%0;" 
      : "=m" (pC) : "m" (pA), "m" (pB)); 

      pA += 512; 
      pB += 512; 
      pC += 512; 
    } 
    return 0; 
} 

J'utilise le compilateur gcc (parce que je n'ai pas d'argent pour acheter compilateur intel). Et voici ma ligne de commande pour compiler ce code:

k1om-mpss-linux-gcc add.c -o add.out 

Le problème était dans l'ensemble en ligne. L'assembly en ligne suivant l'a corrigé.

__asm__("vmovaps %1,%%zmm1\n" 
     "vmovaps %2,%%zmm2\n" 
     "vaddps %%zmm1,%%zmm2,%%zmm3\n" 
     "vmovaps %%zmm3,%0;" 
     : "=m" (*pC) : "m" (*pA), "m" (*pB)); 
+0

Il existe de nombreux commutateurs de compilation qui contrôlent le point flottant. Et certains contrôlent avx. Pouvez-vous nous dire lesquels vous utilisez? –

+0

Lorsque vous avez posté [une question presque identique récemment] (http://stackoverflow.com/questions/34114092/vector-sum-using-avx-inline-assembly-on-xeonphi), il vous a été signalé que le premier génération Xeon Phi (Knight's Corner) ne supporte pas AVX] (http://stackoverflow.com/a/34115089/253056). –

+0

Pour 'KNCI', vous devez utiliser les registres' zmm' avec 'vaddps'. Notez également que les intrinsèques sont * beaucoup * plus faciles à utiliser pour cela que l'initialisation inline brute (comme noté également dans les commentaires sur votre question précédente). Voir aussi [cette réponse très pertinente] (http://stackoverflow.com/a/22719429/253056). –

Répondre

3

Comme already explained, Knights Corner (KNC) n'a pas AVX512. Cependant, il a quelque chose de similaire. Il se trouve que le problème KNC vs AVX512 est un hareng rouge ici. Le problème est dans l'assemblage en ligne OPs.

Au lieu d'utiliser l'assemblage en ligne, je vous suggère d'utiliser des intrinsèques. Les intrinsèques KNC sont décrites au Intel Intrinsic Guide online.

De plus, Przemysław Karpiński at CERN extend Agner Fog's Vector Class Library to use KNC. Vous pouvez trouver le dépôt git here. Si vous regardez dans le fichier vectorf512_mic.h, vous pouvez en apprendre beaucoup sur les intrinsèques KNC.

Je converti votre code pour utiliser ces intrinsics (qui se révèlent dans ce cas être le même que les AVX512 intrinsics):

int main(int argc, char* argv[]) 
{ 
    int i; 
    const int length = 65536; 
    const int AVXLength = length /16; 
    float *A = (float*) aligned_malloc(length * sizeof(float), 64); 
    float *B = (float*) aligned_malloc(length * sizeof(float), 64); 
    float *C = (float*) aligned_malloc(length * sizeof(float), 64); 
    for(i=0; i<length; i++){ 
     A[i] = 1; 
     B[i] = 2; 
    } 
    for(i=0; i<AVXLength; i++){ 
     __m512 a16 = _mm512_load_ps(&A[16*i]); 
     __m512 b16 = _mm512_load_ps(&B[16*i]); 
     __m512 s16 = _mm512_add_ps(a16,b16); 
     _mm512_store_ps(&C[16*i], s16); 
    } 
    return 0; 
} 

Les intrinsics KNC ne sont pris en charge par la CCI. Cependant, KNC vient avec le Manycore Platform Software Stack (MCSS) qui vient avec une version spéciale de gcc, k1om-mpss-linux-gcc, qui peut utiliser les caractéristiques de KNX de l'AVX512 en utilisant l'assemblage en ligne.


Les mnémoncis pour KNC et AVX512 sont les mêmes dans ce cas. Par conséquent, nous pouvons utiliser AVX512 intrinsics pour découvrir l'ensemble à utiliser

void foo(int *A, int *B, int *C) { 
    __m512i a16 = _mm512_load_epi32(A); 
    __m512i b16 = _mm512_load_epi32(B); 
    __m512i s16 = _mm512_add_epi32(a16,b16); 
    _mm512_store_epi32(C, s16); 
} 

et gcc -O3 -mavx512 knc.c produit

vmovaps (%rdi), %zmm0 
vaddps (%rsi), %zmm0, %zmm0 
vmovaps %zmm0, (%rdx) 

A partir de cette seule solution en utilisant l'assembleur en ligne serait

__asm__("vmovaps (%1), %%zmm0\n" 
     "vpaddps (%2), %%zmm0, %%zmm0\n" 
     "vmovaps %%zmm0, (%0)" 
     : 
     : "r" (pC), "r" (pA), "r" (pB) 
     : 
); 

Avec la code précédent GCC génère des instructions d'ajout pour chaque tableau. Voici une meilleure solution utilisant un registre d'index qui ne génère qu'un seul ajout.

for(i=0; i<length; i+=16){ 
    __asm__ __volatile__ (
      "vmovaps (%1,%3,4), %%zmm0\n" 
      "vpaddps (%2,%3,4), %%zmm0, %%zmm0\n" 
      "vmovaps %%zmm0, (%0,%3,4)" 
      : 
      : "r" (C), "r" (A), "r" (B), "r" (i) 
      : "memory" 
    ); 
} 

La dernière version de la SSPM (3.6) comprend GCC 5.1.1 qui prend en charge intrinsics AVX512. Donc, je pense que vous pouvez utiliser les intrinsèques AVX512 chaque fois qu'ils sont les mêmes que les intrinsèques KNC et n'utiliser que l'assemblage en ligne quand ils ne sont pas d'accord. En regardant le guide Intel Intrinsic montre qu'ils sont les mêmes dans la plupart des cas.

+0

Merci pour votre réponse. Mon problème est que je n'ai pas de compilateur Intel et je veux utiliser GCC. Donc, je ne peux pas utiliser intrinsics. Pouvez-vous me dire comment remplacer l'intrinsèque avec l'assemblage en ligne pour utiliser GCC? –

+0

Je trouve le problème avec mon code ... merci –

+0

@Hamid_UMB, si vous avez corrigé votre problème, pourriez-vous mettre à jour votre question avec la solution? Ou pourriez-vous fournir une réponse à [ma question] (http://stackoverflow.com/questions/26933394/xeon-phi-knights-corner-intrinsics-with-gcc) avec un exemple de votre code et les instructions que vous avez utilisées pour le faire fonctionner sur KNC. Je ne possède pas KNC mais si j'en avais un, ce serait bien de savoir comment faire. –