Pregunta

Con cantidades muy grandes de memoria RAM en estos días, me preguntaba: ¿es posible asignar una sola porción de memoria que sea más grande que 4GB? ¿O necesitaría asignar un montón de trozos más pequeños y manejar el cambio entre ellos?

¿Por qué? Estoy trabajando en el procesamiento de algunos datos xml de openstreetmap y estos archivos son enormes. Actualmente los estoy transmitiendo ya que no puedo cargarlos todos de una sola vez, pero simplemente sentí curiosidad por los límites superiores de malloc o nuevos.

¿Fue útil?

Solución

Respuesta corta: No es probable

Para que esto funcione, absolutamente tendrías para utilizar un procesador de 64 bits. En segundo lugar, dependería de la compatibilidad del sistema operativo para asignar más de 4G de RAM a un solo proceso.

En teoría, sería posible, pero tendría que leer la documentación del asignador de memoria. También sería más susceptible a los problemas de fragmentación de la memoria.

Hay buena información en Administración de memoria de Windows .

Otros consejos

Una introducción a los diseños físicos y de memoria virtual

Necesitaría una CPU de 64 bits y una compilación O / S y, casi con toda seguridad, suficiente memoria para evitar golpear su conjunto de trabajo. Un poco de fondo:

Una máquina de 32 bits (en general) tiene registros que pueden almacenar uno de 2 ^ 32 (4,294,967,296) valores únicos. Esto significa que un puntero de 32 bits puede dirigirse a cualquiera de 2 ^ 32 ubicaciones de memoria únicas, que es de donde proviene el límite mágico de 4GB.

Algunos sistemas de 32 bits como el SPARCV8 o Xeon tienen MMU que hacen un truco para permitir más memoria física. Esto permite que múltiples procesos ocupen memoria que suman más de 4 GB en total, pero cada proceso está limitado a su propio espacio de direcciones virtuales de 32 bits. Para un solo proceso que busca un espacio de direcciones virtuales, solo se pueden asignar 2 ^ 32 ubicaciones físicas distintas mediante un puntero de 32 bits.

No entraré en detalles, pero Esta presentación (advertencia: powerpoint) describe cómo funciona esto. Algunos sistemas operativos tienen instalaciones (como las descritas Aquí - gracias a FP arriba) para manipular la MMU e intercambiar diferentes ubicaciones físicas en el espacio de direcciones virtuales bajo el control de nivel de usuario.

El sistema operativo y la E / S asignada a la memoria ocuparán parte del espacio de direcciones virtuales, por lo que no todos los 4 GB están necesariamente disponibles para el proceso. Como ejemplo, Windows toma por defecto 2GB de esto, pero se puede configurar para que solo tome 1GB si se invoca el conmutador / 3G en el arranque. Esto significa que un solo proceso en una arquitectura de 32 bits de este tipo solo puede construir una estructura de datos contiguos de algo menos de 4 GB de memoria.

Esto significa que tendría que usar explícitamente el PAE instalaciones en Windows o Instalaciones equivalentes en Linux para intercambiar manualmente las superposiciones. Esto no es necesariamente tan difícil, pero tomará algún tiempo comenzar a trabajar.

Alternativamente, puede obtener una caja de 64 bits con mucha memoria y estos problemas desaparecerán más o menos. Una arquitectura de 64 bits con punteros de 64 bits puede construir una estructura de datos contigua con un máximo de 2 ^ 64 (18,446,744,073,709,551,616) direcciones únicas, al menos en teoría. Esto permite construir y gestionar estructuras de datos contiguas más grandes.

La ventaja de los archivos asignados en memoria es que puede abrir un archivo mucho más grande que 4Gb (¡casi infinito en NTFS!) y tener varias ventanas de memoria de < 4Gb en él.
Es mucho más eficiente que abrir un archivo y leerlo en la memoria, en la mayoría de los sistemas operativos utiliza el soporte de paginación incorporado.

Esto no debería ser un problema con un sistema operativo de 64 bits (y una máquina que tenga tanta memoria).

Si malloc no puede hacer frente, el sistema operativo proporcionará API que le permitirán asignar memoria directamente. En Windows, puede usar la VirtualAlloc API.

depende de qué compilador de C está utilizando y de qué plataforma (por supuesto), pero no hay ninguna razón fundamental por la que no pueda asignar la mayor parte de la memoria disponible de forma contigua, que puede ser menos de lo que necesita. Y, por supuesto, es posible que tenga que usar un sistema de 64 bits para hacer frente a mucha RAM ...

vea Malloc para conocer el historial y los detalles

llame a HeapMax en alloc.h para obtener el mayor tamaño de bloque disponible

¿Ha considerado usar archivos asignados en memoria? Ya que estás cargando archivos realmente grandes, parece que esta podría ser la mejor manera de hacerlo.

Depende de si el sistema operativo le proporcionará un espacio de direcciones virtuales que permita direccionar la memoria por encima de 4 GB y si el compilador admite asignarlo usando new / malloc.

Para Windows de 32 bits, no podrá obtener un solo fragmento de más de 4 GB, ya que el tamaño del puntero es de 32 bits, lo que limita su espacio de direcciones virtuales a 4 GB. (Puede usar Extensión de dirección física para obtener más información de 4 GB de memoria; sin embargo, creo que usted debe asignar esa memoria al espacio de direcciones virtuosas de 4 GB usted mismo)

Para Windows de 64 bits, el compilador VC ++ admite punteros de 64 bits con límite teórico del espacio de direcciones virtuales a 8 TB.

Sospecho que lo mismo se aplica para Linux / gcc: 32 bits no te permiten, mientras que 64 bits te permiten.

Como señaló Rob, VirtualAlloc para Windows es una buena opción para esto, como lo es una asignación de archivos de anonymouse. Sin embargo, específicamente con respecto a su pregunta, la respuesta a " si C o C ++ " se puede asignar, la respuesta es NO ESTO NO ESTÁ SOPORTE AÚN EN WIN7 RC 64

En la especificación PE / COFF para archivos exe, el campo que especifica la reserva HEAP y la confirmación HEAP, es una cantidad de 32 bits. Esto está en línea con las limitaciones de tamaño físico de la implementación del montón actual en el CRT de Windows, que es apenas inferior a 4 GB. Por lo tanto, no hay forma de asignar más de 4GB desde C / C ++ (técnicamente, las funciones de soporte de sistema operativo de CreateFileMapping y VirtualAlloc / VirtualAllocNuma, etc. no son C o C ++).

También, CONSCIENTE de que existen construcciones ABI x86 o amd64 subyacentes conocidas como tablas de páginas. Este HARÁ en efecto hará lo que le preocupa, asignando porciones más pequeñas para su solicitud más grande, aunque esto está sucediendo en la memoria del núcleo, hay un efecto en el sistema en general, estas tablas son finitas.

Si está asignando memoria en tales grandes usos, le recomendamos que asigne según la granularidad de la asignación (que aplica VirtualAlloc) y también que identifique banderas opcionales o métodos para habilitar páginas más grandes.

4kb páginas fueron el tamaño de página inicial para el 386, subsecuentemente el pentium agregó 4MB. Hoy, el AMD64 (Guía de optimización de software para AMD Procesadores familiares de 10 h) tiene un tamaño máximo de entrada de tabla de páginas de 1 GB. Esto significa para su caso aquí, digamos que acaba de hacer 4 GB, solo se necesitarían 4 entradas únicas en el directorio del kernel para ubicar y asignar permiso a la memoria de su proceso.

Microsoft también ha lanzado este manual que articula algunos de los puntos más finos de la memoria de la aplicación y su uso para la plataforma Vista / 2008 y más reciente.

Contenidos

Introducción. 4

Acerca del Administrador de memoria 4

Espacio de direcciones virtuales. 5

Asignación dinámica de Kernel Virtual Espacio de dirección. 5

Detalles para arquitecturas x86. 6

Detalles para arquitecturas de 64 bits. 7

Salto de pila en modo kernel en x86 Arquitecturas 7

Uso de Excess Pool Memory. 8

Seguridad: Diseño del espacio de direcciones Aleatorización 9

Efecto de ASLR en la carga de la imagen Direcciones 9

Beneficios de ASLR .. 11

Cómo crear de forma dinámica Imagenes 11

E / S ancho de banda. 11

Microsoft SuperFetch. 12

Escrituras de archivo de página. 12

Coordinación del Administrador de Memoria y Administrador de caché 13

Agrupación previa al estilo de agrupación. 14

Administración de archivos grandes 15

Hibernate y Standby. 16

Modelo de video avanzado 16

Soporte NUMA 17

Asignación de recursos. 17

Nodo y afinidad predeterminados. 18

Afinidad de interrupción. 19

Funciones del sistema NUMA-Aware para Aplicaciones 19

Funciones del sistema NUMA-Aware para Conductores 19

Paginacion 20

Escalabilidad 20

Eficiencia y paralelismo. 20

Número de marco de página y base de datos PFN. 20

Páginas grandes. 21

Asignación de agrupaciones alineadas en caché. 21

Maquinas virtuales. 22

Balanceo de carga. 22

Optimizaciones adicionales. 23

Integridad del sistema. 23

Diagnóstico de errores de hardware. 23

Integridad del Código y Firma del Conductor. 24

Preservación de datos durante las verificaciones de errores. 24

Lo que debes hacer. 24

Para fabricantes de ferretería. 24

Para desarrolladores de controladores. 24

Para desarrolladores de aplicaciones. 25

Para administradores de sistemas. 25

Recursos 25

Si size_t es mayor de 32 bits en su sistema, ha superado el primer obstáculo. Pero los estándares C y C ++ no son responsables de determinar si alguna llamada particular a new o malloc tiene éxito (excepto malloc con un tamaño 0). Eso depende completamente del sistema operativo y del estado actual del montón.

Como todos los demás dijeron, obtener una máquina de 64 bits es el camino a seguir. Pero incluso en una máquina Intel de 32 bits, puede abordar áreas de memoria de más de 4 GB si su sistema operativo y su CPU son compatibles con PAE . Desafortunadamente, 32bit WinXP no hace esto (¿32bit Vista?). Linux le permite hacer esto de manera predeterminada, pero estará limitado a áreas de 4 gb, incluso con mmap (), ya que los punteros siguen siendo de 32 bits.

Lo que debes hacer es dejar que el sistema operativo se encargue de la administración de la memoria por ti. Entra en un entorno que puede manejar esa cantidad de RAM, luego lee el (los) archivo (s) XML (s) en (a) la (s) estructura (s) de datos y deja que asigne el espacio para ti. Luego opere en la estructura de datos en la memoria, en lugar de operar en el propio archivo XML.

Sin embargo, incluso en sistemas de 64 bits, no va a tener mucho control sobre qué partes de su programa realmente se encuentran en la memoria RAM, en la memoria caché, o están paginados al disco, al menos en la mayoría de los casos, ya que el sistema operativo y la MMU se encarga de esto ellos mismos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top