Je suis en train de tester Intel ADX ajouter avec report et ajouter avec débordement à pipeline ajoute sur grands entiers. J'aimerais voir à quoi devrait ressembler la génération de code attendue. De _addcarry_u64 and _addcarryx_u64 with MSVC and ICC, je pensais que ce serait un test approprié:Cas de test pour adcx et adox
#include <stdint.h>
#include <x86intrin.h>
#include "immintrin.h"
int main(int argc, char* argv[])
{
#define MAX_ARRAY 100
uint8_t c1 = 0, c2 = 0;
uint64_t a[MAX_ARRAY]={0}, b[MAX_ARRAY]={0}, res[MAX_ARRAY];
for(unsigned int i=0; i< MAX_ARRAY; i++){
c1 = _addcarryx_u64(c1, res[i], a[i], (unsigned long long int*)&res[i]);
c2 = _addcarryx_u64(c2, res[i], b[i], (unsigned long long int*)&res[i]);
}
return 0;
}
Quand je l'examinerai generated code from GCC 6.1 en utilisant -O3
et -madx
, il révèle addc
sérialisé. -O1
et -O2
produit des résultats similaires:
main:
subq $688, %rsp
xorl %edi, %edi
xorl %esi, %esi
leaq -120(%rsp), %rdx
xorl %ecx, %ecx
leaq 680(%rsp), %r8
.L2:
movq (%rdx), %rax
addb $-1, %sil
adcq %rcx, %rax
setc %sil
addb $-1, %dil
adcq %rcx, %rax
setc %dil
movq %rax, (%rdx)
addq $8, %rdx
cmpq %r8, %rdx
jne .L2
xorl %eax, %eax
addq $688, %rsp
ret
donc je suppose que le cas de test est pas tout à fait frappant la marque, ou je fais quelque chose de mal, ou je me sers quelque chose de mal, ...
Si je suis correctement pars les documents Intel sur _addcarryx_u64
, je crois que le code C devrait générer le pipeline. Donc je suppose que je fais quelque chose de mal:
Description de
Ajouter unsigned entiers 64 bits a et b avec unsigned report 8 bits c_in (porte ou drapeau de trop-plein), et mémoriser le résultat 64 bits non signé, et le report dans dst (indicateur de report ou de dépassement).
Comment puis-je générer le pipeline'd ajouter avec carry/ajouter avec trop-plein (adcx
/adox
)?
J'ai en fait obtenu une 5e génération Core i7 prêt pour le test (notez le drapeau cpu adx
):
$ cat /proc/cpuinfo | grep adx
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush
dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc
arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni
pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 fma cx16 xtpr pdcm pcid sse4_1
sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm
3dnowprefetch ida arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase
tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt
...
Je pense que ces intrinsèques sont principalement là parce que MSVC ne permet pas l'assemblage en ligne en mode 64 bits. Avec GCC, vous devez utiliser l'assemblage en ligne dans ce cas. En fait, la meilleure façon d'utiliser 'adc 'qui existe depuis des décennies avec GCC est l'assemblage en ligne. C'est sympa d'avoir l'assemblage en ligne en option mais c'est dommage, comme PITA à utiliser dans GCC. –