como - malloc sizeof c++
¿Se puede asignar un pedazo de memoria muy grande(> 4GB) en c o c++? (10)
Con cantidades muy grandes de ram en estos días me preguntaba, ¿es posible asignar un solo trozo de memoria que sea más grande que 4GB? ¿O tendría que asignar un grupo 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 en un solo fragmento, pero tengo curiosidad acerca de los límites superiores en malloc o nuevo.
¿Ha considerado usar archivos mapeados en memoria? Dado que está cargando archivos realmente grandes, parece que esta podría ser la mejor manera de hacerlo.
Como Rob señaló, VirtualAlloc para Windows es una buena opción para esto, como lo es una asignación de archivos anonymouse. Sin embargo, específicamente con respecto a su pregunta, la respuesta a "si C o C ++" puede asignar, la respuesta es NO ESTO NO ES SOPORTADO INCLUSO EN WIN7 RC 64
En la especificación PE / COFF para archivos exe, el campo que especifica HEAP reserve y HEAP commit, es una cantidad de 32 bits. Esto está en línea con las limitaciones de tamaño físico de la implementación actual del montón en el CRT de Windows, que es poco menos de 4 GB. Por lo tanto, no hay forma de asignar más de 4 GB de C / C ++ (técnicamente todas las funciones de soporte de SO de CreateFileMapping y VirtualAlloc / VirtualAllocNuma, etc. no son C o C ++).
Además, TENGA EN CUENTA que existen construcciones ABI x86 o amd64 subyacentes conocidas como tablas de la página. Esto REALMENTE hará lo que le preocupa, al asignar trozos más pequeños para su pedido mayor, aunque esto está ocurriendo en la memoria del núcleo, hay un efecto en el sistema general, estas tablas son finitas.
Si está asignando memoria en tales grandiosas relaciones, sería recomendable que la asigne en función de la granularidad de la asignación (que VirtualAlloc aplica) y también para identificar banderas opcionales o métodos para habilitar páginas más grandes.
Las páginas de 4kb eran el tamaño de página inicial para el 386, subsaquently el pentium agregaba 4MB. Hoy, AMD64 (Guía de optimización de software para procesadores 10h de la familia AMD) tiene un tamaño máximo de entrada de tabla de páginas de 1 GB. Esta es la razón para su caso aquí, digamos que acaba de hacer 4 GB, requeriría solo 4 entradas únicas en el directorio del kernel para localizar / asignar y permitir 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 aplicaciones y su uso para la plataforma Vista / 2008 y más reciente.
Contenido Introducción. 4 Acerca del Administrador de memoria 4 Espacio de direcciones virtuales. 5 Asignación dinámica del espacio de direcciones virtuales del Kernel. 5 Detalles para x86 Architectures. 6 Detalles para arquitecturas de 64 bits. 7 Kernel-Mode Stack Jumping en arquitecturas x86. 7 Uso del exceso de memoria de la piscina. 8 Seguridad: aleatorización del diseño del espacio de direcciones. 9 Efecto de ASLR en las direcciones de carga de imagen. 9 Beneficios de ASLR .. 11 Cómo crear imágenes basadas dinámicamente 11 Ancho de banda de E / S. 11 Microsoft SuperFetch. 12 Archivo de página escrito. 12 Coordinación de Memory Manager y Cache Manager 13 Agrupación previa al estilo. 14 Gran gestión de archivos 15 Hibernate y Standby. dieciséis Modelo de video avanzado 16 Soporte NUMA 17 Asignación de recursos. 17 Nodo predeterminado y afinidad. 18 Interrumpir la afinidad. 19 Funciones del sistema NUMA-Aware para aplicaciones. 19 Funciones del sistema NUMA-Aware para controladores. 19 Paginación. 20 Escalabilidad 20 Eficiencia y Paralelismo .. 20 Número de fotograma y base de datos PFN. 20 Páginas grandes 21 Asignación de grupo alineada con 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 comprobaciones de errores. 24 Lo que debes hacer 24 Para fabricantes de hardware. 24 Para desarrolladores de controladores. 24 Para desarrolladores de aplicaciones. 25 Para los administradores del sistema. 25 Recursos. 25Como 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 máquina 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 (¿Vista de 32 bits?). Linux le permite hacer esto de forma predeterminada, pero estará limitado a áreas de 4 GB, incluso con mmap () ya que los punteros siguen siendo de 32 bits.
Sin embargo, lo que debe hacer es dejar que el sistema operativo se encargue de la gestión de memoria. Entre en un entorno que pueda manejar esa cantidad de RAM, luego lea los archivos XML en (a) la (s) estructura (s) de datos, y permita que asigne el espacio por usted. Luego opere en la estructura de datos en memoria, en lugar de operar en el archivo XML en sí.
Sin embargo, incluso en sistemas de 64 bits, no tendrás mucho control sobre qué partes de tu programa se encuentran realmente en la memoria RAM, en el caché o en el disco, al menos en la mayoría de los casos, ya que el sistema operativo y el controlador MMU esto ellos mismos
Depende de si el sistema operativo le proporcionará un espacio de direcciones virtual que permita direccionar la memoria a más de 4GB 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 utilizar Here para obtener más de 4 GB de memoria, sin embargo, creo que tiene que asignar esa memoria en el espacio virtualaddress de 4 GB)
Para Windows de 64 bits, el compilador de VC ++ admite punteros de 64 bits con un límite teórico del espacio de direcciones virtuales de 8TB.
Sospecho que lo mismo aplica para Linux / gcc: 32 bits no te permiten, mientras que 64 bits te lo permite.
Esto no debería ser un problema con un sistema operativo de 64 bits (y una máquina que tiene tanta memoria).
Si malloc no puede hacer frente, el sistema operativo proporcionará API que le permiten asignar memoria directamente. En Windows, puede usar la API de VirtualAlloc .
La ventaja de los archivos mapeados en memoria es que puedes abrir un archivo mucho más grande que 4Gb (¡casi infinito en NTFS!) Y tener varias ventanas de memoria <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.
Respuesta corta: no es probable
Para que esto funcione, tendrías que usar un procesador de 64 bits. En segundo lugar, dependería del soporte del sistema operativo para asignar más de 4G de RAM a un único 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 problemas de fragmentación de memoria.
Hay buena información sobre la administración de memoria de Windows .
Si size_t es mayor que 32 bits en su sistema, ha borrado el primer obstáculo. Pero los estándares C y C ++ no son responsables de determinar si una llamada particular a new o malloc tiene éxito (excepto malloc con un tamaño 0). Eso depende completamente del sistema operativo y el estado actual del montón.
depende de qué compilador de C esté utilizando y de qué plataforma (por supuesto), pero no hay una razón fundamental por la que no pueda asignar la mayor parte de la memoria contigua disponible, que puede ser menor de lo que necesita. Y, por supuesto, puede que tenga que usar un sistema de 64 bits para abordar que mucha RAM ...
ver Malloc para la historia y detalles
llame a HeapMax en alloc.h para obtener el tamaño de bloque más grande disponible
Un manual sobre diseños de memoria física y virtual
Necesitaría una CPU de 64 bits y una estructura de O / S, y casi con certeza suficiente memoria para evitar agotar su conjunto de trabajo. Un poco de historia:
Una máquina de 32 bits (por lo 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 abordar cualquiera de las 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 el Xeon tienen MMU que hacen un truco para permitir más memoria física. Esto permite que múltiples procesos ocupen memoria total de más de 4 GB, pero cada proceso está limitado a su propio espacio de direcciones virtuales de 32 bits. Para un único proceso que busca un espacio de direcciones virtual, solo se pueden mapear 2 ^ 32 ubicaciones físicas distintas mediante un puntero de 32 bits.
No entraré en los detalles, pero esta presentación (advertencia: PowerPoint) describe cómo funciona esto. Algunos sistemas operativos tienen funciones (como las que se describen Here , gracias a FP más arriba) para manipular la MMU e intercambiar ubicaciones físicas diferentes en el espacio de direcciones virtuales bajo control de nivel de usuario.
El sistema operativo y la E / S mapeada en memoria ocuparán parte del espacio de direcciones virtuales, por lo que no todos los 4 GB estarán necesariamente disponibles para el proceso. Como ejemplo, Windows toma por defecto 2GB de esto, pero puede configurarse para que solo tome 1GB si se invoca el modificador / 3G al arrancar. Esto significa que un solo proceso en una arquitectura de 32 bits de este tipo solo puede construir una estructura de datos contigua de algo menos de 4 GB en memoria.
Esto significa que tendría que usar explícitamente las instalaciones de PAE instalaciones de Windows o Equivalente en Linux para intercambiar manualmente las superposiciones. Esto no es necesariamente tan difícil, pero tomará un tiempo para ponerse a trabajar.
Alternativamente, puede obtener una caja de 64 bits con mucha memoria y estos problemas desaparecen más o menos. Una arquitectura de 64 bits con punteros de 64 bits puede construir una estructura de datos contigua con hasta 2 ^ 64 (18,446,744,073,709,551,616) direcciones únicas, al menos en teoría. Esto permite que se construyan y administren estructuras de datos contiguas más grandes.