petr
Por lo que he encontrado hasta ahora, está claro que los programas compilados para una arquitectura de 64 bits usan el doble de RAM para punteros que sus alternativas de 32 bits: https://superuser.com/questions/56540/32-bit-vs-64-bit-systems.
¿Significa eso que el código compilado para usos de 64 bits en promedio dos veces más RAM que la versión de 32 bits?
De alguna manera lo dudo, pero me pregunto cuál es la sobrecarga real. Supongo que los tipos pequeños, como short
, byte
y char
tienen el mismo tamaño en una arquitectura de 64 bits? no estoy muy seguro de byte
aunque. Dado que muchas aplicaciones funcionan con cadenas grandes (como navegadores web, etc.), que consisten principalmente en char
arreglos en la mayoría de las implementaciones, la sobrecarga puede no ser tan grande.
Entonces, incluso si los tipos numéricos como int
y long
son más grandes en 64 bits, ¿tendría un efecto significativo en el uso de RAM o no?
glglgl
Depende del estilo de programación (y del lenguaje, pero te refieres a C).
- Si trabajas mucho con punteros (o tienes muchas referencias en algunos idiomas), el consumo de RAM sube.
- Si usa muchos datos con un tamaño fijo, como
double
oint32_t
el consumo de RAM no sube. - Para tipos como
int
olong
, depende de la arquitectura; puede haber diferencias entre Linux y Windows. Aquí ves las alternativas que tienes. En resumen, Windows usa LLP64, lo que significa quelong long
y los punteros son de 64 bits, mientras que Linux usa LP64, dondelong
es de 64 bits también. Otras arquitecturas podrían hacerint
o inclusoshort
64 bits también, pero estos son bastante poco comunes. float
ydouble
debe permanecer del mismo tamaño en todos los casos.
Como puede ver, depende en gran medida del uso de los tipos de datos.
-
x86-64 también tiene x32 ABI que usa punteros de 32 bits. Tiene la ventaja sobre el uso de x86 de 32 bits de tener una convención de llamadas más orientada al registro y poder usar los 8 GPR adicionales (y 8 registros SIMD/FP adicionales). Además, GCC admite ILP32 en AArch64.
–Paul A. Clayton
19 de marzo de 2015 a las 11:25
-
Entonces, es más probable que lenguajes como Java/C# obtengan este efecto 2x que C/C++ (especialmente si no usa muchos punteros), ¿correcto?
– David dice Reincorporar a Monica
19 de marzo de 2015 a las 16:02
-
@DavidGrinberg Aquí también, eso depende de los datos. Por ejemplo, un programa que tiene la mayoría de sus datos en una matriz nativa como
int[]
odouble[]
, no cambiará mucho. Sin embargo, un programa que trabaje con muchos objetos pequeños necesitará más memoria RAM.– glglgl
19 de marzo de 2015 a las 20:14
-
@DavidGrinberg Debido a comprimida upslos programas Java que usan menos de ~4GiB de almacenamiento dinámico probablemente permanecerán igual.
–Tavian Barnes
19 de marzo de 2015 a las 20:16
-
@TavianBarnes en realidad, una JVM puede abordar 64 GB con referencias de 32 bits utilizando una alineación de objetos de 8 o 26 bytes.
– Peter Lawrey
25 de marzo de 2015 a las 3:21
VAndrei
Hay algunas razones por las que el consumo de memoria aumenta. Sin embargo, la sobrecarga de 64b frente a 32b depende de una aplicación a otra.
-
La razón principal es usando muchos punteros en tu código. Sin embargo, una matriz asignada dinámicamente en un código compilado para 64 bits y que se ejecuta en un sistema operativo de 64 bits tendría el mismo tamaño que la matriz asignada en un sistema de 32 bits. Solo la dirección de la matriz será más grande, el tamaño del contenido será el mismo (excepto cuando el tamaño de letra cambió – sin embargo, eso no debería suceder y debería estar bien documentado).
-
Otro aumento de la huella se debe a alineación de memoria. En el modo de 64 bits, la alineación debe considerar una dirección de 64 bits, por lo que debería agregar una pequeña sobrecarga.
-
Probablemente el el tamaño del código aumentará. En algunas arquitecturas, el ISA de 64 bits podría ser un poco más grande. Además, ahora tendría que hacer llamadas a direcciones de 64 bits.
-
al correr en 64 bits los registros son más grandes (64 bits), por lo que si usa muchos tipos numéricos, el compilador también podría colocarlos en registros, por lo que eso no debería significar necesariamente que su huella de RAM aumentaría. Usando variables dobles es probable que produzca un aumento de huella de memoria si no se almacenan en registros 64b.
-
Cuando usas Lenguajes compilados JIT como Java, .NET, es probable que el aumento de la huella del código 64b sea mayor, ya que el entorno de tiempo de ejecución generará una sobrecarga adicional a través del uso de punteros, estructuras de control ocultas, etc.
Sin embargo, no hay un número mágico que describa la sobrecarga de la huella de memoria de 64 bits. Eso hay que medirlo de una aplicación a otra. Por lo que he visto, Nunca obtuve más del 20% de aumento en la huella para una aplicación que se ejecuta en 64 bits, en comparación con 32 bits. Sin embargo, eso se basa puramente en las aplicaciones que encontré y estoy usando principalmente C y C++.
-
Un salto típicamente será relativo a 32 bits. No puede saltar a una dirección absoluta de 64 bits con una sola instrucción jmp
– phuclv
19 de marzo de 2015 a las 8:50
-
la única instrucción que tiene una dirección inmediata de 64 bits es movabs, por lo que tampoco puede llamar a una función en una dirección inmediata de 64 bits
– phuclv
19 de marzo de 2015 a las 9:05
-
Estoy bastante seguro de que puede hacer una llamada a una dirección absoluta 64b. Chequea aquí: intel.com/content/dam/www/public/us/en/documents/manuals/…
– VAndrei
19 de marzo de 2015 a las 9:19
-
También es posible un salto con un desplazamiento de 64 bits según la misma referencia.
– VAndrei
19 de marzo de 2015 a las 9:25
-
estás leyendo algo mal. “En el modo de 64 bits, los inmediatos y los desplazamientos generalmente tienen solo 32 bits de ancho. Por lo tanto, NASM truncará la mayoría de los desplazamientos e inmediatos a 32 bits. La única instrucción que toma un inmediato completo de 64 bits es: MOV reg64,imm64” nasm.us/doc/nasmdo11.html
– phuclv
19 de marzo de 2015 a las 13:31
Creo que puede haber otra razón que se remonta a que las variables deben almacenarse en la memoria en un límite de 64 bits en una dirección que es … xxxxx000 para leerse en un solo bocado, si no es así, debe leerlo en un byte a la vez
byte
es no un tipo estandarizado. Con C99 o superior, incluye<stdint.h>
entonces usauint8_t
si necesita “bytes” de 8 bits sin firmar.– Basile Starynkevitch
19 de marzo de 2015 a las 8:42
el uso de la memoria aumentará, pero (casi) nunca se duplicará
– phuclv
19 de marzo de 2015 a las 8:50
El objetivo de crear nuevas CPU con direcciones más amplias y buses de datos es aumentar la velocidad de ejecución a costa del tamaño del programa y el consumo de RAM. Este ha sido el caso del 8 al 16 al 32 al 64. Así que nada nuevo aquí.
– Lundin
19 de marzo de 2015 a las 9:03
@Lundin Me doy cuenta de que hay una sobrecarga causada por eso, pero lo que me gustaría saber es qué tan grande es esa sobrecarga. Es posible que algunos sistemas deban optimizarse más para el consumo de RAM en lugar del consumo de CPU
– Petr
19 de marzo de 2015 a las 9:25
Por supuesto. La memoria RAM no importa, un programa de 64 bits usa el caché del procesador de manera mucho menos efectiva. No es el doble de malo, depende de lo que esté pasando. Un En t sigue siendo de 32 bits por esta misma razón. Gracias a AMD, compensaron esta pérdida de rendimiento al agregar todas las funciones adecuadas para obtener un resultado comparable. Comenzando con 8 registros adicionales.
-Hans Passant
19 de marzo de 2015 a las 10:09