¿Cuál es la sobrecarga de uso de memoria para una aplicación de 64 bits?

7 minutos de lectura

avatar de usuario
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?

  • byte es no un tipo estandarizado. Con C99 o superior, incluye <stdint.h> entonces usa uint8_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

avatar de usuario
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 o int32_tel consumo de RAM no sube.
  • Para tipos como int o long, 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 que long long y los punteros son de 64 bits, mientras que Linux usa LP64, donde longes de 64 bits también. Otras arquitecturas podrían hacer int o incluso short 64 bits también, pero estos son bastante poco comunes.
  • float y double 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[] o double[], 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

avatar de usuario
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

¿Ha sido útil esta solución?