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

StackOverflow https://stackoverflow.com/questions/181050

  •  05-07-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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 ГБ в памяти.

Это означает, что вам пришлось бы явно использовать ПАЭ удобства на окнах или Эквивалентные возможности в Linux чтобы вручную поменять местами оверлеи.Это не обязательно так сложно, но потребуется некоторое время, чтобы начать работать.

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

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

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

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

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

видишь Маллок для истории и деталей

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

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

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

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

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

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

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

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

Кроме того, БУДЬТЕ ОСОЗНАЮЩИЙ что существуют базовые конструкции x86 или amd64 ABI, известные как таблицы страниц.Это БУДЕТ по сути, делайте то, о чем вы договорились, выделяя меньшие фрагменты для вашего большего запроса, даже если это происходит в памяти ядра, это влияет на систему в целом, эти таблицы конечны.

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

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

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

Содержание

Введение.4

О диспетчере памяти 4

Виртуальное адресное пространство.5

Динамическое выделение виртуального ядра Адресное пространство.5

Подробности для архитектур x86.6

Подробности для 64-разрядных архитектур.7

Переключение стека в режиме ядра в x86 Архитектуры.7

Использование избыточной памяти пула.8

Безопасность:Расположение адресного пространства Рандомизация.9

Влияние ASLR на загрузку изображения Адреса.9

Преимущества ASLR..11

Как создать Динамически Основанный Изображения.11

Пропускная способность ввода-вывода.11

Суперфетч Microsoft.12

Запись в файл подкачки.12

Координация работы диспетчера памяти и Диспетчер кэша 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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top