2010-05-06 27 views
6

int, char y bool generalmente tienen diferentes tamaños. Donde int> char> bool, supongo.¿Puede RAM manejar diferentes tamaños de datos?

  • Pero, ¿la RAM incluso admite esto?
  • ¿Cómo se acumula?
  • ¿Puede aprovechar bool de solo 1 byte y almacenarlo en un pequeño "registro"?
+1

Para las personas que responden con No me tiene que importar, hay mucho espacio: Gracias, lo sé, pero tengo curiosidad :) – tstbu

+0

No está manejado por RAM, el procesador lee fragmentos de , típicamente, 16 bytes a la vez en el caché. Un multiplexor grande baraja los bytes correctos desde allí a un registro de CPU. Mezclar un byte toma el mismo tiempo que un int. –

+0

¿Alguna vez resolvió esto con éxito? ¿Aún necesitas ayuda con esto? – jcolebrand

Respuesta

1

¿Se supone que te refieres a caché? Sólo curiosidad por qué estás preocupado por el tamaño de las estructuras de datos, ¿estás programando para integrar? Por lo general, es la única huella de memoria que vale la pena preocuparse.

Si tiene varios campos de bits que desea mantener al mismo tiempo se puede utilizar un byte como un campo de bits y recordar que los valores como

0x0001 
0x0010 
0x0100 
0x1000 

son cada uno por separado el uno del otro y se puede comprobar de forma independiente de la otros. La gente hace esto todo el tiempo para tratar de ahorrar un poco de espacio. ¿Es ese tipo de lo que intentas descubrir?

Así, por ejemplo, si cada bool ocupa un byte de espacio, obviamente solo se usa un bit por byte. Entonces, si encadenas 8 bits, solo consumirá un byte de espacio.

Pero no olvide que cada variable en la memoria también tiene algún tipo de alineación (más evidente en .NET que en los idiomas de nivel "inferior", pero siempre hay algo que rastrea las variables en uso). Entonces, como en el caso de C#, un byte en realidad necesita 3 bytes de RAM.

Pero la RAM es transferida por el bloque, que es mucho más grande, según tengo entendido, que un solo byte. Usualmente eso se mide en al menos palabras, y el tamaño normal es 32, 64 o 128 bits a la vez. Esos números dependen de la plataforma.

+1

¿Los números hexadecimales en el poder de 2 lograrán lo mismo? es decir: '0x0001',' 0x0002', '0x0004',' 0x0008', '0x0010', etc. –

+0

Como los números hexadecimales son una abreviatura de binario, entonces sí. Se trata de la ubicación binaria. Además, 0x0003 sería una abreviatura para que la primera y la segunda posición sean verdaderas/establecidas (por así decirlo). – jcolebrand

+0

Derecha. Otra pregunta es, ¿no harían dos dígitos hexadecibles un byte? Tu ejemplo usa medio byte para un campo. Esto no importa mucho. '=]' –

1

Si con 'soporte' quiere decir que la RAM en una máquina tiene una unidad de almacenamiento nativa que coincida con cada tamaño, la respuesta es 'depende de la máquina y del compilador'.

Las máquinas modernas suelen tener tamaños de almacenamiento direccionables mínimos que son múltiplos de 8 bits (8/16/32/64 bits). Los compiladores pueden usar cualquiera de esos tamaños para almacenar y manipular datos. Un compilador puede optimizar el almacenamiento y registrar el uso, pero no es necesario.

0

¿Qué tiene eso que ver con la RAM?

Un bool puede ser verdadero o falso, que generalmente se representa como 0 o 1 (1 bit). Un char puede tener diferentes tamaños, dependiendo del juego de caracteres utilizado. ASCII usa 7 bits. Unicode usa hasta 32 bits. Los enteros son números enteros, que a menudo soportan el rango de -2^31 .... 2^31-1 (32 bits), pero también vienen en otros tamaños.

+0

En memoria, un bool generalmente ocupa un byte completo. Como es mucho más fácil para el procesador y el administrador de memoria tratar con un byte que con un solo bit. –

+0

Hoy en día los booleanos a menudo incluso "usan" 32 o incluso 64 bits, pero eso es solo relleno para una mayor eficiencia. Al mismo tiempo, no debes olvidar las "banderas" que no son más que un grupo de booleanos. Aún así, el valor booleano solo usa un bit. El diseño de la memoria está sujeto a la plataforma y al compilador. – Lucero

0

Puede utilizar campos de bits C++, si se quiere, pero que será uno de los pocos en este planeta que lo hacen (técnicamente, campos de bits están bien definidos en C, pero nunca fueron realmente utilizan mucho)

El compilador de C++ le oculta cómo se accede a la RAM por buenas razones. Hay casos en los que desea optimizar esto, pero son extremadamente raros. En el mundo actual de cantidades masivas de RAM en las PC del cliente, no vale la cantidad de micro-optimización.

En general, debe confiar en su compilador (optimizador) para hacer lo correcto. El código fuente que entrega al compilador solo se asemeja vagamente al código de máquina producido por el compilador. Es un mito que las micro-optimizaciones ayudan mucho si su compilador es bueno. Debe saber exactamente dónde necesita el compilador su proceso de optimización para optimizarlo mejor que el compilador. Incluso puede empeorar las cosas si el compilador decide que su código es demasiado complicado para optimizarlo.

Si quieres un poco de antecedentes técnicos:

El nivel de lenguaje de máquina que depende del procesador. Por ejemplo el Motorola 680x0 línea de procesadores le permite hacer

move.l 
move.w 
move.b 

a leer y escribir diferentes "unidades" de RAM (largo/palabra/byte). El procesador tiene una apariencia diferente en su RAM dependiendo de qué instrucción procesa. Algunos procesadores integrados pueden incluso usar 4 bits como su unidad más pequeña.

1

RAM realmente no se preocupa por los tamaños de tipo de datos. Simplemente almacena datos en bytes. La CPU controla los tipos de datos básicos, sabiendo cuántos bytes son. Al crear un int, por ejemplo, la CPU decide utilizar, por ejemplo, 4 u 8 bytes (arquitectura de 32 o 64 bits respectivamente)

No se puede abordar un bit, pero puede crear una estructura personalizada donde almacene 8 booleanos en un byte. En C++, puede utilizar este uso de campos de bits.

+0

Además, el '' conjunto de bits '' de STL es útil para manejar matrices con uso eficiente del espacio de valores booleanos. – foraidt

5

La memoria de la computadora está organizada en "palabras", una secuencia de bytes de un tamaño dado (a menudo una potencia de 2). Por lo general, la memoria se lee y escribe en estas unidades, que a menudo son compatibles con el tamaño de los registros y el soporte nativo de la CPU para operadores aritméticos. Esta suele ser la fuente de la "calificación de bits" de una máquina (por ejemplo, una CPU de 32 bits, una CPU de 64 bits, las antiguas consolas de videojuegos de 8 bits).

Por supuesto, a menudo necesita un tamaño diferente del tamaño de la palabra nativa. Las instrucciones de la máquina y la codificación inteligente le permiten dividir estas palabras en unidades más pequeñas al aplicar varios operadores lógicos de nivel de bit, o combinarlos en unidades más grandes "combinando" varias palabras.

Por ejemplo, si tiene una palabra de 32 bits, podría Y una palabra contra un patrón como 0xff0000ff para obtener el primer y último byte en esa palabra, o 0x0000ffff para obtener solo el contenido del segundo int de 16 bits .

En el caso de los bools, es común usar la memoria como un mapa de bits. En esencia, puede colocar X "bools" en una palabra de X bits y acceder a un bit específico mediante ANDing u ORing contra una "máscara" que se refiere a ese bool. Por ejemplo, 1 para el primer bit, 2 para el segundo bit, 4 para el cuarto bit, etc.

En la mayoría de las máquinas, no es aconsejable dividir un tipo de datos más pequeño en dos palabras (esto se llama alighment).

Cuando trabajas con un lenguaje de nivel superior como C o C++, por lo general no tienes que preocuparte por todo este asunto de la organización de la memoria. Si asigna un int, un short y un double, el compilador generará el código de máquina apropiado. Solo hace esto directamente cuando desea organizar inteligentemente cosas en la memoria asignada dinámicamente, por ejemplo cuando se implementa manualmente un mapa de bits.

Al trabajar con unidades más grandes que el tamaño de palabra nativa, el compilador volverá a manejar la mayoría de las cosas por usted. Por ejemplo, en una máquina de 32 bits puede manejar fácilmente operaciones int de 32 bits, pero para ejecutar el mismo código en una máquina de 8 bits o una máquina de 16 bits, el compilador generará código para hacer las operaciones más pequeñas y combinarlas para obtener los resultadosEsto es parcialmente por lo que generalmente se considera aconsejable ejecutar un sistema operativo de 64 bits en una máquina de 64 bits, ya que de lo contrario podría estar realizando múltiples instrucciones y lecturas/escrituras para simular 64 bits en un sistema operativo de 32 bits en lugar de una sola instrucción o acceso a la memoria.

5

En una computadora normal y moderna, todas las memorias son direccionables por byte. Es decir, cada ubicación de almacenamiento de tamaño de byte en la RAM tiene un número único asignado. Si desea almacenar un valor de un byte como un bool (aunque bool s no son requiere ser un byte en C++, simplemente por lo general son), se necesita una única ubicación de almacenamiento, por ejemplo la ubicación 42.

Si desea almacenar algo más grande que un byte, digamos int, se necesitarán varias ubicaciones de almacenamiento consecutivas. Por ejemplo, si su tipo int tiene una longitud de 16 bits (2 bytes), la mitad se almacenará en la ubicación 42 y la otra mitad en la ubicación 43. Esto se generaliza a tipos más grandes. Supongamos que tiene un tipo long long int de 64 bits (8 bytes). Un valor de este tipo se puede almacenar en las ubicaciones 42, 43, 44, 45, 46, 47, 48 y 49.

Existen algunas consideraciones más avanzadas denominadas "alineación" que algunos tipos de procesadores deben respetar. . Por ejemplo, un procesador puede tener una regla de que un valor de dos bytes debe comenzar en una dirección par, o que un valor de cuatro bytes debe comenzar en una dirección divisible por 4. Su compilador se encargará de los detalles de este para ti.

El compilador también sabe cuánto tiempo es cada tipo, de modo que cuando genera el código de máquina para su programa, sabrá en qué dirección comienza el almacenamiento para cada variable, y sabrá cuántos bytes consecutivos se almacena la variable en.

"Registros" por el contrario, son algo que existe en el procesador, no en la RAM, y suelen ser de un tamaño fijo. Un uso de los registros del procesador es almacenar un valor recuperado de la RAM. Por ejemplo, si su procesador tiene registros de 32 bits (4 bytes), entonces un valor bool cargado desde la RAM seguirá consumiendo un registro completo de 4 bytes, aunque consumió solo un byte cuando estaba en la RAM.

+0

Esto no es verdad, pero la CPU lo hace así. En una computadora moderna normal, la RAM está organizada en módulos DIMM. No puede direccionar un solo byte de un DIMM, solo 8 bytes/64 bits. – MSalters

+0

Bueno, depende del nivel al que estés hablando. Si está hablando sobre qué tipo de direcciones acepta el procesador (que es el nivel más bajo que normalmente le interesaría a un programador), entonces es cierto que la memoria es direccionable por bytes, aunque a un nivel de hardware inferior, eso puede no será el caso. –

0

La mayoría de los hardware básico tienen memoria direccionable por bytes. Mirando un poco más profundo, vemos que a los registros de la CPU se les da ancho de bits (32 o 64 bits para cosas cotidianas). Luego, los cachés y los buses funcionan en bloques de estos (64 o 128 bytes de algo). Puede intentar aprovechar esto, pero necesitaría una comprensión bastante detallada del hardware, y estaría vinculado a una plataforma en particular. Por otro lado, no tiene que aprovechar esto ya que su compilador ya lo hace.

Cuestiones relacionadas