Bien que Knights Corner (KNC) ne possède pas AVX512, il a quelque chose de très similaire. Beaucoup de mnémoniques sont les mêmes. En fait, dans le cas de l'OP, les mnémotechniques vmovdqa32 et vpaddd sont les mêmes pour AVX512 et KNC.
Les opcodes sont probablement différents mais le compilateur/assembleur s'en charge. Dans le cas d'OP, il/elle utilise une version spéciale de GCC, k1om-mpss-linux-gcc
qui fait partie du many core software stack KNC qui génère vraisemblablement les opcodes corrects. On peut compiler sur l'hôte en utilisant k1om-mpss-linux-gcc
puis scp
le binaire à la carte KNC. J'ai appris à ce sujet à partir d'un commentaire au this question.
Quant à savoir pourquoi le code ne parvient pas OPs je ne peux pas faire deviner que je n'ai pas une carte KNC pour tester avec. Dans mon expérience limitée avec l'assemblage en ligne GCC, j'ai appris qu'il est bon de regarder l'assemblage généré dans le fichier objet pour s'assurer que le compilateur a fait ce que vous attendiez.
Lorsque je compile votre code avec une version normale de GCC, je vois que la ligne "vpaddd %0,%%zmm0,%%zmm1;"
produit l'assemblage avec le point-virgule. Je ne pense pas que le point-virgule devrait être là. Cela pourrait être un problème.
Mais depuis organophosphorés mnémoniques sont les mêmes que AVX512 nous pouvons en utilisant intrinsics AVX512 pour comprendre l'assemblage correct
#include <x86intrin.h>
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 -mavx512f -O3 -S knc.c
procudes
vmovdqa64 (%rsi), %zmm0
vpaddd (%rdi), %zmm0, %zmm0
vmovdqa64 %zmm0, (%rdx)
GCC a choisi vmovdqa64
au lieu de vmovdqa32
même si la documentaion Intel dit qu'il devrait être vmovdqa32
. Je ne suis pas sûr pourquoi. Je ne sais pas quelle est la différence. J'aurais pu utiliser le _mm512_load_si512
intrinsèque qui existe et selon Intel devrait correspondre à vmovdqa32
mais GCC le mappe également à vmovdqa64
. Je ne suis pas sûr pourquoi il y a aussi _mm512_load_epi32
et _mm512_load_epi64
maintenant. SSE et AVX n'ont pas ces intrinsèques correspondants.
Basé sur le code de GCC est l'ensemble en ligne ici, j'utiliser
__asm__ ("vmovdqa64 (%1), %%zmm0\n"
"vpaddd (%2), %%zmm0, %%zmm0\n"
"vmovdqa64 %%zmm0, (%0)"
:
: "r" (pC), "r" (pA), "r" (pB)
: "memory"
);
Peut-être vmovdqa32
doit être utilisé au lieu de vmovdqa64
mais je pense qu'il n'a pas d'importance.
J'ai utilisé le modificateur de registre r
au lieu du modificateur de mémoire m
parce que l'expérience passée m
le modificateur de mémoire n'a pas produit l'ensemble je m'y attendais.
Une autre possibilité d'envisager est d'utiliser une version de GCC qui prend en charge pour générer intrinsics AVX512 l'assemblage, puis utiliser la version KNC spéciale de GCC pour convertir l'ensemble en binaire. Par exemple
gcc-5.1 -O3 -S foo.c
k1om-mpss-linux-gcc foo.s
Cela peut avoir des ennuis depuis k1om-mpss-linux-gcc
est probablement une ancienne version de GCC. Je n'ai jamais fait quelque chose comme ça avant mais ça peut marcher.
Comme expliqué here la raison pour laquelle les intrinsics AVX512
_mm512_load/store(u)_epi32
_mm512_load/store(u)_epi64
_mm512_load/store(u)_si512
est que les paramètres ont été convertis en void*
. Par exemple avec SSE vous devez jeter
int *x;
__m128i v;
__mm_store_si128((__m128*)x,v)
alors qu'avec SSE vous ne devez plus
int *x;
__m512i;
__mm512_store_epi32(x,v);
//__mm512_store_si512(x,v); //this is also fine
Il est toujours pas clair pour moi pourquoi il est vmovdqa32
et vmovdqa64
(GCC semble seulement utiliser vmovdqa64
actuellement) mais il est probablement similaire à movaps
et movapd
dans SSE qui n'ont pas de réelle différence et n'existe que dans le cas où ils peuvent faire une différence dans le futur.
Le but de vmovdqa32
et vmovdqa64
est pour le masquage qui peut être fait avec ces intrsics
_mm512_mask_load/store_epi32
_mm512_mask_load/store_epi64
Sans masque les instructions sont équivalentes.
KNC ne prend pas en charge AVX-512. Vous devez attendre KNL pour cela. Vous devrez regarder si et comment le faire avec KNC en utilisant son ISA. – Jeff
Et essayez intrinsèques d'abord avec le compilateur Intel. – Jeff
Merci Jeff, mais ce n'est pas la source de mon erreur de segmentation. J'ai essayé 256 bits aussi, mais je n'ai pas réussi –