Подтвердить что ты не робот

Можете ли вы выделить очень большой единый блок памяти (> 4 ГБ) в c или С++?

С очень большим количеством бара в эти дни мне было интересно, можно выделить один кусок памяти размером более 4 ГБ? Или мне нужно выделить кучу меньших кусков и переключиться между ними?

Почему??? Я работаю над обработкой некоторых данных openstreetmap xml, и эти файлы огромны. В настоящее время я их транслирую, так как я не могу загрузить их всех в один кусок, но мне просто любопытно узнать верхние ограничения на malloc или new.

4b9b3361

Ответ 1

Короткий ответ: Вероятно

Чтобы это сработало, вы бы имели использовать 64-разрядный процессор. Во-вторых, это будет зависеть от поддержки операционной системы для распределения более 4 ГБ ОЗУ на один процесс.

Теоретически это было бы возможно, но вам нужно будет прочитать документацию для распределителя памяти. Вы также были бы более восприимчивы к проблемам фрагментации памяти.

Существует хорошая информация о управлении памятью Windows.

Ответ 2

Направляющая на макетах физической и виртуальной памяти

Вам понадобится 64-битный процессор и сборка O/S и почти наверняка память, чтобы не потревожить ваш рабочий набор. Немного фона:

32-разрядная машина (по большому счету) имеет регистры, которые могут хранить одно из 2 ^ 32 (4 294 967 296) уникальных значений. Это означает, что 32-разрядный указатель может адресовать любой из 2 ^ 32 уникальных мест памяти, из которых исходит магия 4 ГБ.

В некоторых 32-разрядных системах, таких как SPARCV8 или Xeon, есть MMU, которые вызывают трюк, чтобы обеспечить большую физическую память. Это позволяет нескольким процессам занимать память общей суммой более 4 ГБ в совокупности, но каждый процесс ограничивается собственным 32-битным виртуальным адресным пространством. Для одного процесса, который ищет виртуальное адресное пространство, 32-битный указатель может отображать только 2 ^ 32 различных физических местоположения.

Я не буду вдаваться в подробности, но Эта презентация (предупреждение: powerpoint) описывает, как это работает. В некоторых операционных системах есть средства (например, описанные здесь - благодаря вышеописанному FP), чтобы манипулировать MMU и менять различные физические местоположения на виртуальный адрес пространство под контролем уровня пользователя.

Операционная система и память, подключенные к I/O, будут занимать часть виртуального адресного пространства, поэтому не все из этого 4 ГБ обязательно доступны для процесса. Например, Windows по умолчанию использует 2 ГБ, но может быть установлена ​​только на 1 ГБ, если при загрузке запускается/3G-коммутатор. Это означает, что один процесс в 32-битной архитектуре такого типа может создавать только непрерывную структуру данных размером менее 4 ГБ в памяти.

Это означает, что вам нужно будет явно использовать PAE в Windows или Эквивалентные средства в Linux для ручной замены в оверлеях. Это не обязательно так сложно, но потребуется некоторое время для работы.

В качестве альтернативы вы можете получить 64-битную коробку с большим количеством памяти, и эти проблемы более или менее уходят. 64-битная архитектура с 64-разрядными указателями может построить непрерывную структуру данных с целыми 2 ^ 64 (18,446,744,073,709,551,616) уникальными адресами, по крайней мере теоретически. Это позволяет создавать и управлять большими смежными структурами данных.

Ответ 3

Преимущество файлов с отображением памяти заключается в том, что вы можете открыть файл, который намного больше, чем 4Gb (почти бесконечный на NTFS!) и иметь в нем несколько окон памяти объемом 4 ГБ.
Он намного эффективнее, чем открытие файла и чтение его в память, в большинстве операционных систем он использует встроенную поддержку поискового вызова.

Ответ 4

Это не должно быть проблемой с 64-разрядной ОС (и машиной с большим объемом памяти).

Если malloc не может справиться, ОС обязательно предоставит API-интерфейсы, которые позволят вам напрямую распределять память. В Windows вы можете использовать API VirtualAlloc.

Ответ 5

это зависит от того, какой компилятор C вы используете, и на какой платформе (конечно), но нет основополагающей причины, по которой вы не можете выделить самый большой кусок доступной памяти, которая может быть меньше, чем вам нужно. И, конечно, вам, возможно, придется использовать 64-битную систему для адресации, чем много оперативной памяти...

см. Malloc для истории и деталей

вызовите HeapMax в alloc.h, чтобы получить самый большой доступный размер блока

Ответ 6

Считаете ли вы использование файлов с отображением памяти? Поскольку вы загружаете в действительно огромные файлы, кажется, что это может быть лучший способ.

Ответ 7

Это зависит от того, предоставит ли ОС виртуальное адресное пространство, позволяющее адресовать память выше 4 ГБ и поддерживает ли компилятор ее выделение с помощью new/malloc.

Для 32-битной Windows вы не сможете получить единый фрагмент размером более 4 ГБ, так как размер указателя составляет 32 бит, что ограничивает ваше виртуальное адресное пространство до 4 ГБ. (Вы можете использовать Physical Address Extension, чтобы получить более 4 ГБ памяти, однако я считаю, что вам нужно нанести эту память на виртуальное пространство 4 ГБ самостоятельно )

Для 64-битной Windows компилятор VС++ поддерживает 64-разрядные указатели с теоретическим пределом виртуального адресного пространства до 8 ТБ.

Я подозреваю, что то же самое относится и к Linux/gcc - 32-бит не позволяет вам, тогда как 64-битный позволяет вам.

Ответ 8

Как заметил Роб, VirtualAlloc для Windows является хорошим вариантом для этого, так же как и отображение анонимного файла. Однако, в частности, в отношении вашего вопроса ответ на "если C или С++" может выделить, ответ НЕТ ЭТО НЕ ПОДДЕРЖИВАЕТСЯ ДАЖЕ НА WIN7 RC 64

В спецификации PE/COFF для exe файлов поле, определяющее резерв HEAP и HEAP-commit, составляет 32-битное количество. Это соответствует физическим ограничениям размера текущей кучевой имплантации в окне CRT, что всего лишь 4 ГБ. Таким образом, нет возможности выделить более 4 ГБ из C/С++ (технически все средства поддержки ОС CreateFileMapping и VirtualAlloc/VirtualAllocNuma и т.д. Не являются C или С++).

Кроме того, BE AWARE, что существует базовая конструкция ARI x86 или amd64, известная как таблица страниц. Эта WILL фактически выполняет то, о чем вы конкретизируете, выделяя меньшие куски для вашего более крупного запроса, хотя это происходит в памяти ядра, и это влияет на общую систему, эти таблицы являются конечными.

Если вы выделяете память в таких грандиозных целях, вам было бы целесообразно распределить их на основе гранулярности распределения (которые VirtualAlloc обеспечивает), а также для определения необязательных флагов или методов для включения больших страниц.

4kb страницы были начальным размером страницы для 386, подъязычно pentium добавил 4MB. Сегодня AMD64 (Руководство по оптимизации программного обеспечения для процессоров семейства AMD 10h) имеет максимальный размер записи в таблице 1GB. Это означает для вашего случая, скажем, вы только что сделали 4 ГБ, для поиска\назначения и разрешения вашей памяти процесса потребуется всего 4 уникальных записи в каталоге ядра.

Microsoft также выпустила этот руководство, в котором излагаются некоторые из более тонких точек памяти приложения, и он используется для платформы Vista/2008 и более поздних версий.

Содержание Введение. 4 О диспетчере памяти 4 Виртуальное адресное пространство. 5 Динамическое распределение ядра Virtual Адресное пространство. 5 Подробная информация для архитектуры x86. 6 Подробности для 64-битных архитектур. 7 Ядро-режим Stack Jumping в x86 Архитектуры. 7 Использование избыточной памяти пула. 8 Безопасность: макет адресного пространства Рандомизации. 9 Влияние ASLR на загрузку изображения Адреса. 9 Преимущества ASLR.. 11 Как создать динамически основанный Изображений. 11 Полоса пропускания ввода-вывода. 11 Microsoft SuperFetch. 12 Псевдоним файла. 12 Координация диспетчера памяти и Менеджер кэшей 13 Кластеризация в стиле выборки. 14 Управление большими файлами 15 Спящий режим и режим ожидания. 16 Расширенная видео модель 16 Поддержка NUMA 17 Распределение ресурсов. 17 По умолчанию Node и Affinity. 18 Прерывание близости. 19 Функции NUMA-Aware для Приложения. 19 Функции NUMA-Aware для Драйверы. 19 Пейджинг. 20 Масштабируемость. 20 Эффективность и Parallelism.. 20 Номер кадра страницы и база данных PFN. 20 Большие страницы. 21 Распределение пула в кэше. 21 Виртуальные машины. 22 Балансировка нагрузки. 22 Дополнительные оптимизации. 23 Целостность системы. 23 Диагностика ошибок оборудования. 23 Целостность кода и подписание драйверов. 24 Сохранение данных во время проверки ошибок. 24 Что ты должен делать. 24 Для производителей оборудования. 24 Для разработчиков драйверов. 24 Для разработчиков приложений. 25 Для системных администраторов. 25 Ресурсы. 25

Ответ 9

Если size_t больше 32 бит в вашей системе, вы очистили первое препятствие. Но стандарты C и С++ не несут ответственности за определение того, успешно ли выполняется какой-либо конкретный вызов для нового или malloc (кроме malloc с размером 0). Это полностью зависит от ОС и текущего состояния кучи.

Ответ 10

Как и все остальные, получение 64-битной машины - это путь. Но даже на 32-битной машинной машине Intel вы можете адресовать области памяти более 4 ГБ, если ваша ОС и ваш процессор поддерживают PAE. К сожалению, 32-битный WinXP этого не делает (32-битная Vista?). Linux позволяет делать это по умолчанию, но вы будете ограничены областями 4gb, даже с mmap(), поскольку указатели все еще 32-разрядные.

Что вам следует делать, пусть операционная система позаботится об управлении памятью для вас. Займитесь в среду, которая может обрабатывать столько ОЗУ, а затем прочитайте XML файл в (а) структуру данных и дайте ему выделить пространство для вас. Затем используйте структуру данных в памяти, вместо того, чтобы работать с самим файлом XML.

Тем не менее, даже в 64-битных системах у вас не будет большого контроля над тем, какие части вашей программы фактически находятся в ОЗУ, в кеше или выгружены на диск, по крайней мере, в большинстве случаев, поскольку ОС и MMU справляется с этим сами.