Alineación de memoria: ¿cómo usar alignof / alignas?


Ahora mismo trabajo con memoria compartida.

No puedo entender alignof y alignas.

Cppreference no está claro: alignof devuelve "alineación" pero ¿qué es "alineación" ? ¿número de bytes a agregar para que el siguiente bloque se alinee ? ¿tamaño acolchado ? Stack overflow / las entradas de blogs tampoco están claras.

Puede alguien explicar claramente alignof y alignas ?

Author: Community, 2013-06-13

3 answers

La alineación es una restricción sobre la cual se puede almacenar el primer byte de un valor. (Es necesario mejorar el rendimiento de los procesadores y permitir el uso de ciertas instrucciones que funcionan solo en datos con alineación particular, por ejemplo, SSE necesita estar alineado a 16 bytes, mientras que AVX a 32 bytes.)

La alineación de 16 significa que las direcciones de memoria que son un múltiplo de 16 son las únicas direcciones válidas.

alignas

Forzar la alineación al número requerido de bytes (cppreference no lo menciona, pero creo que sólo se puede alinear a los poderes de 2: 1, 2, 4, 8, 16, 32, 64, 128, ...)

#include <cstdlib>
#include <iostream>

int main() {
    alignas(16) int a[4];
    alignas(1024) int b[4];
    printf("%p\n", a);
    printf("%p", b);
}

Ejemplo de salida:

0xbfa493e0
0xbfa49000  // note how many more "zeros" now.
// binary equivalent
1011 1111 1010 0100 1001 0011 1110 0000
1011 1111 1010 0100 1001 0000 0000 0000 // every zero is just a extra power of 2

La otra palabra clave

alignof

Es muy conveniente, no se puede hacer algo como

int a[4];
assert(a % 16 == 0); // check if alignment is to 16 bytes: WRONG compiler error

Pero puedes hacer

assert(alignof(a) == 16);
assert(alignof(b) == 1024);

Tenga en cuenta que en realidad esto es más estricto que una simple operación "%" (módulo). De hecho, sabemos que algo alineado a 1024 bytes está necesariamente alineado a 1, 2, 4, 8 bytes pero

 assert(alignof(b) == 32); // fail.

Así que más preciso, "alignof" devuelve la mayor potencia de 2 para que algo esté alineado.

También alignof es una buena manera de conocer de antemano el requisito mínimo de alineación para los tipos de datos básicos (probablemente devolverá 1 para caracteres, 4 para flotador, etc.).

Sigue siendo legal:

alignas(alignof(float)) float SqDistance;

Algo con una alineación de 16 entonces se colocará en la siguiente dirección disponible que es un múltiplo de 16 (puede haber un relleno implícito de la última dirección utilizada).

 47
Author: GameDeveloper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-14 17:14:47

La alineación no es relleno (aunque a veces se introduce relleno para satisfacer los requisitos de alineación). Es una propiedad intrisic de tipo C++. Para ponerlo en standardese (3.11[basic.align])

Los tipos de objetos tienen requisitos de alineación (3.9.1, 3.9.2) que imponen restricciones a las direcciones en las que se puede asignar un objeto de ese tipo. Una alineación es un valor entero definido por la implementación que representa el número de bytes entre direcciones sucesivas en las que un objeto dado puede be allocated. Un tipo de objeto impone un requisito de alineación a cada objeto de ese tipo; se puede solicitar una alineación más estricta utilizando el especificador de alineación (7.6.2).

 6
Author: Cubbi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-13 18:20:37

Cada tipo tiene un requisito de alineación. Generalmente, esto es para que las variables del tipo puedan ser accedidas eficientemente, sin tener que causar que la CPU genere más de un acceso de lectura/escritura para llegar a cualquier miembro dado del tipo de datos. Además, también garantiza una copia eficiente de toda la variable. alignof devolverá el requisito de alineación para el tipo dado.

alignas se utiliza para forzar una alineación en un tipo de datos (siempre y cuando no sea menos estricto que lo que alignof dicho tipo de datos regresaría)

 3
Author: levengli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-13 19:47:57