A documentação para vzeroall
parece inconsistente. A prosa diz:
A instrução zera o conteúdo de todos os registros XMM ou YMM.
O pseudocódigo a seguir que, contudo, indica que no modo de 64 bits única regista ymm0
através ymm15
são afectados:
IF (64-bit mode)
limit ←15
ELSE
limit ← 7
FOR i in 0 .. limit:
simd_reg_file[i][MAXVL-1:0] ← 0
Em AVX-512 máquinas de suporte de compensação até ymm15
não é o mesmo que clearing "todos" porque ymm16
através ymm31
existir.
A prosa ou o pseudocódigo estão corretos?
// clear only 16 registers even if AVX-512 is present
vzeroupper
em CPUs mais recentes pode ser muito pior devido ao efeito de mesclar uops e alargamento implícito (foi o que foi mencionado nos comentários que Peter vinculou).Respostas:
Parece que foi um problema de descrição. Se você olhar o SDM mais recente , verá que a descrição foi alterada recentemente e agora diz que o VZEROALL não está alterando YMM16 ... YMM31.
fonte
ymm16
para salvar uma__m256
volta_mm256_zeroall()
: godbolt.org/z/HK7_Xy . Isso só faz sentido se souber que zeroall não toca em ymm16. O clang3.9.1 é derramado na memória, então talvez ele esteja nessa versão ou talvez não seja otimizado com a mesma eficiência. Hmm, clang (3.9 e atual) não sabe que a__m128
pode ser deixada em xmm0 de diâmetro_mm256_zeroupper()
. godbolt.org/z/DwMyMV