Se eu tiver um array, ou um ponteiro para um array, do tipo uint32_t
, meus arrays são quase sempre menores em comprimento do que o máximo que eu precisaria indexar com um uint32_t
. No entanto, descobri que ao usar uint64_t
em vez de uint32_t
como um índice, o compilador evita algumas mov
instruções.
Aqui está um exemplo muito simples para ilustrar isso:
Código fonte:
#include <cstdint>
void set_value(uint32_t* __restrict array, const uint32_t idx, const uint32_t value)
{
array[idx] = value;
}
void set_value(uint32_t* __restrict array, const uint64_t idx, const uint32_t value)
{
array[idx] = value;
}
Montagem gerada usando Clang 14.0.0 com -O3 -march=skylake -std=c++17 -mno-vzeroupper
:
set_value(unsigned int*, unsigned int, unsigned int):
mov eax, esi
mov dword ptr [rdi + 4*rax], edx
ret
set_value(unsigned int*, unsigned long, unsigned int):
mov dword ptr [rdi + 4*rsi], edx
ret
Alguém pode explicar as diferentes saídas do compilador? Por que a uint64_t
versão pula a mov
instrução?