c++ - Optimización de inicialización de matriz
x86-64 compiler-optimization (1)
Al compilar el siguiente fragmento de código (clang x86-64
-O3
)
std::array<int, 5> test()
{
std::array<int, 5> values {{0, 1, 2, 3, 4}};
return values;
}
Produjo el montaje típico que yo esperaría.
test(): # @test()
mov rax, rdi
mov ecx, dword ptr [rip + .L__const.test().values+16]
mov dword ptr [rdi + 16], ecx
movups xmm0, xmmword ptr [rip + .L__const.test().values]
movups xmmword ptr [rdi], xmm0
ret
.L__const.test().values:
.long 0 # 0x0
.long 1 # 0x1
.long 2 # 0x2
.long 3 # 0x3
.long 4 # 0x4
Sin embargo, para arreglos pequeños, parece haber descubierto un truco?
std::array<int, 3> test()
{
std::array<int, 3> values {{0, 1, 2}};
return values;
}
This fue la asamblea correspondiente.
test(): # @test()
movabs rax, 4294967296
mov edx, 2
ret
¿De dónde vino ese número mágico (
4294967296
)?
¿Es eso esencialmente un valor que puede
reinterpret_cast
nuevo en una matriz de
int
alguna manera?
Un
std::array<int, 3>
tiene 96 bits de ancho en su implementación.
Como tal, ABI declara que debe devolverse en RAX + los 32 bits bajos de RDX (también conocido como EDX).
4294967296 es 2
32
, en hexadecimal es
$1''0000''0000
.
Así que
movabs
almacena 0 en los 32 bits de RAX de orden inferior, y 1 en los bits de RAX de orden superior.
El
mov
almacena 2 en EDX (que es exactamente lo que querías).