2012-05-09 13 views
7

Leí en alguna parte que usar BOOL (typedef int) es mejor que usar el bool estándar de tipo C++ porque el tamaño de BOOL es 4 bytes (es decir, un múltiplo de 4) y guarda operaciones de alineación de variables en registros o algo similar ...C++ BOOL (typedef int) vs bool para rendimiento

¿Hay algo de cierto en esto? Me imagino que el compilador rellenaría los marcos de la pila para mantener las alineaciones de múltiplos de 4, incluso si usa bool (1 byte).

No soy de ninguna manera un experto en el funcionamiento subyacente de alineaciones, registros, etc., así que me disculpo por adelantado si tengo esto completamente mal. Espero ser corregido :)

¡Salud!

+6

Si 'bool' es más rápido que 4 bytes, el compilador lo convertirá en 4 bytes. Depende del escenario Entonces, no, 'BOOL' no da un beneficio de rendimiento. – tenfour

+0

Este es el tipo de cosas que solo puede descubrir a través de la creación de perfiles, pero ¿desea un bool que pueda tener valores distintos de 0,1? ¿Incluso valores negativos? – juanchopanza

+0

Esto no hará ninguna diferencia. El compilador rellena los valores para asegurarse de que estén alineados correctamente. Usa el tipo que tenga más sentido. Si se trata de un valor booleano, conviértalo en un 'bool', no en un' int' (o en un 'typedef'). –

Respuesta

7

En primer lugar, sizeof(bool) no es necesariamente 1. Es implementation-defined, dando al escritor del compilador la libertad de elegir un tamaño que sea adecuado para la plataforma de destino.

Además, sizeof(int) no es necesariamente 4.

hay varios problemas que podrían afectar al rendimiento:

  • alineación;
  • ancho de banda de memoria;
  • Capacidad de la CPU para cargar eficientemente valores que son más angostos que la palabra de la máquina.

Lo que - si alguna - diferencia que hace a una pieza particular de código solo se puede establecer mediante el perfil de esa pieza de código.

+0

Y el compilador probablemente habrá adaptado el tamaño de un 'bool' para reflejar estos problemas. –

+0

Hablando en general sin embargo; Por el bien del ejemplo, di que bool es 1 byte y di que un int es 4 bytes. Digamos que tienes una struct {bool x; int y}; ¿La x causa que y se alinee incorrectamente porque su tamaño no es un múltiplo de 4? ¿O el compilador rellena las direcciones para que y esté alineado? –

+1

@KarlHansson: el relleno es específico de la implementación. Las implementaciones con las que estoy familiarizado insertarían relleno después de 'x' para que' y' esté adecuadamente alineado. – NPE

2

El tamaño sólo se puede obtener garantizadas en C++ es con char, unsigned char y signed char2), que son siempre exactamente un byte y definida para cada plataforma. 0)1)


0) A pesar de un byte no tiene un tamaño definido. sizeof(char) siempre es 1 byte, pero podría ser de 40 bits binarios de hecho

1) Sí, hay uint32_t y amigos, pero no, su definición es opcional para las implementaciones reales de C++. Usarlas, pero puede que tenga errores de compilación de tiempo si no están disponibles (errores de compilación de tiempo son siempre buenas)

2) char, unsigned char y signed char son tipos distintos y no se define si char es signed o no. Tenga esto en cuenta al sobrecargar funciones y escribir plantillas.

0

Hay tres prácticas en función de resultados comúnmente aceptadas en lo que respecta a los booleanos:

  1. Para las sentencias if de comprobar los asuntos expresiones y uno tiene que tener cuidado con ellos.
  2. Si una comprobación de una expresión booleana provoca una gran cantidad de errores de predicción de bifurcación, debe (si es posible) sustituirse por un truco de twiddling bit.
  3. Dado que boolean es un tipo de datos más pequeño, las variables booleanas deben declararse como las últimas en estructuras y clases, de modo que el relleno no agregue agujeros perceptibles en el diseño de la memoria estructural.

Nunca he escuchado acerca de ninguna ganancia de rendimiento al sustituir un booleano con un entero (¿sin?).

+0

# 3 no es necesariamente cierto. En un escenario donde ya hay un espacio en la estructura (debido a la alineación/relleno automático), puede "llenar" la brecha de "libre" colocando allí el bool. Digamos que esta estructura hasta ahora tiene un tamaño que es un múltiplo perfecto del tamaño de la línea de caché, luego agregar un bool al final de la estructura (en lugar de llenar el vacío) en realidad causará una falla en la caché en algunas situaciones al intentar para acceder a ese miembro bool, (mientras que de otro modo no habría falta de caché). Debes juzgar cada estructura de forma independiente. –

+0

@PreetKukreti tiene razón, debería haber dicho 'prácticas comúnmente aceptadas que no requieren conocimiento de la plataforma subyacente'. Si conoce la plataforma en la que se ejecutará SW, entonces sí, puede conocer la alineación (4 u 8 o ...) y ajustarla en consecuencia: rellenar los huecos, alinearlos con las líneas de caché, etc. Lo que sugerí en el lista eran reglas generales para tratar con booleanos. –