Можете ли вы выделить один большой кусок памяти (> 4 ГБ) в c или c ++? - PullRequest
42 голосов
/ 08 октября 2008

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

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

Ответы [ 10 ]

26 голосов
/ 08 октября 2008

Краткий ответ: маловероятно

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

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

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

23 голосов
/ 09 октября 2008

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

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

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

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

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

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

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

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

22 голосов
/ 08 октября 2008

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

14 голосов
/ 08 октября 2008

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

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

12 голосов
/ 08 октября 2008

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

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

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

9 голосов
/ 08 октября 2008

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

6 голосов
/ 08 октября 2008

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

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

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

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

3 голосов
/ 02 июня 2009

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

3 голосов
/ 02 июня 2009

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

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

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

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

4 КБ страницы были начальным размером страницы для 386, впоследствии Pentium добавил 4 МБ. В настоящее время максимальный размер записи в таблицу страниц AMD64 (Руководство по оптимизации программного обеспечения для процессоров AMD семейства 10h) составляет 1 ГБ. Это означает, что для вашего случая здесь, скажем, вы только что использовали 4 ГБ, для поиска \ назначения и разрешения памяти вашего процесса потребуется всего 4 уникальных записи в каталоге ядра.

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...