Этот раздел описывает расширение адресной оболочки Windows (Address Windowing Extention, AWE). Это расширение Windows 2000 предоставляет возможность пользовательским приложениям адресовать более чем 32 бита адресного пространства.
Windows NT и Windows 2000 предоставляют своим приложениям сплошное 32-х битовое адресное пространство, которое описывает 4 Гб виртуальной памяти. Это адресное пространство обычно разбито таким образом, что только 2 Гб непосредственно доступны для нужд приложения. Другие 2 Гб доступны только закрытому коду, принадлежащему операционной системе. Добавим, что начиная с Windows NT 4 SP 3 и Windows NT Server Enterprise Edition/Windows 2000 Advanced Server на базе процессора x86 на нужды приложения выделяется 3 Гб, а закрытому коду - 1 Гб.
AWE является набором расширений, которые предоставляют пользователю возможность пользователю напрямую выделять и фиксировать страницы в оперативной памяти. В этом случае приложения могут быстро оперировать с физичекой памятью, превышающей 4 Гб. Некоторые приложения, связанные с интесивной обработкой данных, такие как систмы управления базами данных, а также нучные и инженерные приложения, нуждаются в доступе к очень огромным кешам данных. В этом случае, размер кеша ограничивается 2 Гб, доступными приложениями, что иногда являеться жестким ограничением. В этих случаях, приложения могут использовать под кеш небольшие объемы данных.
AWE решает эту проблему путем разрешения приложению непосредственно адресовать гигантскую память, в то время как оно может использовать и обычную 32-х битную адресацию. AWE предоставляет для приложений возможность иметь под кеш более чем 4 Гб (при условии, что существует соответствующая физическая память).
Использование AWE связано с некоторыми ограничениями на использование такой памяти, главным образом эти ограничения связаны с предоставлением критичного по скорости распределением, перераспределением и освободением памяти.
* Виртуальное адресное пространство, выделенное средствами AWE, нельзя разделить с другими процессами (и, поэтому, оно не является наследуемым). Невозможно также две различные страницы виртуального адресного пространства спроецировать на одну страницу оперативной памяти. Эти ограничения позволяют сделать быстрой операции перепроецирования и очистки памяти при ее освобождении.
* Физическая память, когорая может быть выделена в AWE регионе, ограничена количеством физической памяти, которая присутсвует на компьютере. Так как эта память является фиксированной, то она блокируется до тех пор, пока приложение ее не освободит (либо до тех пор, пока приложение существует). Физические страницы памяти, выделенные для данного процесса, могут быть спроектированы в любой AWE регион, связанный с этим процессом. Приложение, которое использует AWE, должно быть очень аккуратным, поскольку может забрать на свои нужды столько памяти, что оставшиеся приложения будут иметь интенсивный обмен с файлом подкачки, либо будет предотвращена попытка создания новых процессов и потоков по причине нехватки рессурсов. Используйте функцию {GlobalMemoryStatusEx} для того, чтобы отследить использование физической памяти.
* Виртуальное адресное простаранство, выделенное средствами AWE, всегда доступно для чтения/записи, поэтому к ней неприменимы вызовы функции {VirtualProtect} (поскольку не существует памяти, доступной только для чтения, памяти без доступа, защиты страниц и прочих спецификаторов).
* Диапазон адресов AWE не может быть использован в качестве буфера для графических или видео вызовов.
* Регион памяти AWE не может быть разбит на части, которые затем можно было бы удалить. Весь регион может быть удален только как единое целое, когда это понадобиться. Для этого вы должны указать флаг MEM_RELEASE (но не MEM_DECOMMIT) при вызове {VirtualFree}.
* Приложения, которые используют AWE, не могут выполняться в режиме эмуляции. Поэтому те приложения, на архитектуре x86, которые используют AWE, должны быть перекомпилированы на других процессорах, тогда как другие большинство других приложений может быть запущено на других платформах в режиме эмуляции.
Решение адресовать физическую память следует в большей степени из получаемых при этом выгод. Вот некоторые выгоды использования AWE:
* Небольшое число функций, использующихся для операий с AWE памятью.
* AWE поддерживается на всех платформах, на которых реализована Windows 2000, включая 64-х битную версию Windows 2000.
* AWE предоставляет очень быстрое перераспределение хранимых данных. Перераспределение осуществляется путем использования таблиц виртуальной памяти без перемещеня данных в физической памяти.
* Гранулярность размера AWE страницы соответствует типу процессора (для архитектуры x86 это 4 Кб) которые более полезны для приложений, чем большие страницы (например, 2 Мб, 4 Мб на x86).
Для того чтобы получить привелегию фиксирования страниц в памяти, администратор должен добавить значение атрибута "Lock Page in Memory" в правах пользователя. Установить этот параметр можно выбрав "Панель управления ⇒ Администрирование ⇒ Локальная политика безопасности ⇒ Локальная политика ⇒ Назначение прав пользователя ⇒ Закрепление страниц в памяти" (Control panel ⇒ Administrative tools ⇒ Local security policy ⇒ Local policy ⇒ User right assigment ⇒ Lock pages in memory). Для более детальной информации по этому вопросу смотрите раздел "Права пользователей" в справочной системе по Windows 2000.
Следующие функции реализуют API расширения адресной оболочки Windows (AWE API):
VirtualAlloc - Резервирует диапазон виртуального адресного пространства для использования под AWE (атрибут MEM_PHYSICAL).
AllocateUserPhysicalPages - Выделяет физическую память для использования с AWE.
MapUserPhysicalPages - Проецирует (или сводит на нет) виртуальное пространство AWE на произвольный набор физических страниц, полученных при помощи вызова AllocateUserPhysicalPages.
MapUserPhysicalPagesScatter - Проецирует (или сводит на нет) виртуальное пространство AWE на произвольный набор физических страниц, полученных при помощи вызова AllocateUserPhysicalPages, позволяющей организовать сложное проецирование.
FreeUserPhysicalPages - Освобождает физическую память, которая была выделена под AWE.
MapUserPhysicalPages
Функция MapUserPhysicalPages проецирует выделенную ранее область физической памяти в указанное адрусное пространство AWE-региона виртуальной памяти. Для того, чтобы произвести "групповое" проецирование или разпроецирование для нескольких регионов, вы должны воспользоваться функцией MapUserPhysicalPagesScatter.
Code: |
{ Вариант 1 } function MapUserPhysicalPages( lpAddress: Pointer // начальный адрес области памяти NumberOfPages: UINT; // размер физической памяти в страницах var UserPfnArray: UINT // первый элемент массива фреймов страниц ): Boolean; overload;
{ Вариант 2 } function MapUserPhysicalPages( lpAddress: Pointer // начальный адрес области памяти NumberOfPages: UINT; // размер физической памяти в страницах UserPfnArray: Pointer // указатель на массив фреймов страниц ): Boolean; overload; |
Параметры
lpAddress
Указатель на начальный адрес области памяти, на который будет спроецирована физическая память. Это значение должно находиться внутри диапазона виртуального адресного пространства приложения, выделенного при помощи функции VirtualAlloc с атрубутом, указывающим принадлежность выделяемого фрагмента памяти к AWE-региону.
NumberOfPages
Задает размер в страницах физической памяти (и виртуального адресного пространства). Виртуальное адресное пространство непрерывно и начинается с адреса, указанного в параметре lpAddress. Кадры физической памяти задаются параметром UserPfnArray. Общее число страниц не может превышть то количество страниц, которое было выделено при вызове AllocateUserPhysicalPages.
UserPfnArray
Задает начальный элемент массива фреймов страниц (вариант 1). Эти фрейймы должны быть спроецированы в область памяти, на которую указывает параметр lpAddress. Указанный массив должен содержать по меньшей мере NumberOfPages элементов типа UINT.
Важно! Не пытайтесь модифицировать содержимое этого буфера. Он содержит данные, принадлежащие операционной системе, повреждение которых можт повлечь за собой катастрофические последствия. В этом буфере не содержиться никакой информации, необходимой вашему приложению.
Указание значение nil этому параметру (вариант 2), позволяет провести распроецирование указанного диапазона адресов. При этом указанные страницы не освобождаются в физической памяти, для этого нужно выполнять специальный вызов FreeUserPhysicalPages.
Возвращаемое значение
В случае удачного завершения фкнция возвращает True.
В случае ошибки (когда не было выпоолнено ни частичного, ни полного проецирования) функция вернет False. Для получения расширенной информации об ошибке следует сделать вызов GetLastError.
Описание
Любое количество страниц в физической памяти никак не затрагивает память, выделенную при помощи функции VirtualAlloc. Новая проекция физической памяти на виртуальное адресное пространство процесса автоматически перезаписывает все старые проекции.
Вы не можете спроецровать на виртуальное адресное пространство процесса страницы, которые не были выделены при помощи метода AllocateUserPhysicalPages.
Если со страницы физической памяти было снято проецирование на виртуальное адресно пространство процесса, то это не приводит к освобождению страницы физической памяти. Чтобы освободить страницу в физической памяти, необходимо выполнить вызов FreeUserPhysicalPages.
Страницы физической памяти могут располагаться где угодно. Вы не можете делать каких либо предположений относительно расположения страниц в оперативной памяти. Если со страницы физической памяти было снято проецирование на виртуальное адресно пространство процесса, то это не приводит к освобождению страницы физической памяти. Чтобы освободить страницу в физической памяти, необходимо выполнить вызов FreeUserPhysicalPages.
Для того, чтобы только разпроецировать страницы в физической памяти, необходимо передать в параметре UserPfnArray значение nil.
В многопроцессорных системах данная функция сохраняет согласованность буферов на аппаратном уровне. По выходе из функции гарантируется, что все потоки и процессы будут видеть корректное проецирование страниц.
AllocateUserPhysicalPages
Функция AllocateUserPhysicalPages выделяет страницы физической памяти, которые могут быть впоследствии спроецированы или переспроецированы в любой регион {расширения адресной оболочки Windows} (AWE-регион) указанного процесса.
function AllocateUserPhysicalPages(
hProcess: THandle, // дескриптор процесса
var NumberOfPages: Cardinal, // число страниц
var UserPfnArray: Pointer // адрес хранилища
): Boolean; stdcall;
Параметры
hProcess [in]
Дескриптор процесса. Функция выделяет память в виртуальном адресном пространстве этого процесса. Пользователь, запускающий вызывающее приложение, должен иметь привелегию фиксирования страниц памяти (Lock Pages in Memory) для данного процесса. Если это не выполнено, вызов функции завершится неудачно.
NumberOfPages [in/out]
Указывает размер (в страницах) физической памяти, которая будет выделена. Используйте функцию GetSysInfo для того, чтобы определить размер страницы на вашем компьютере. В этом параметре также возвращается число страниц, которые были действительно выделены. Это число может быть меньше запрашиваемого.
UserPfnArray [out]
Задает виртуальный адрес, по которому будут сохранены номера фреймов страниц выделенной памяти. Размер памяти, выделенной по данному указателю, должен по меньшей мере вместить NumberOfPages элементов типа Cardinal.
Важно! Не пытайтесь модифицировать содержимое этого буфера. Он содержит данные, принадлежащие операционной системе, повреждение которых можт повлечь за собой катастрофические последствия. В этом буфере не содержиться никакой информации, необходимой вашему приложению.
Возвращаемое значение
В случае успешного завершения функция возвращает True. В результате были выделены несколько страниц физической памяти. Это число может быть меньше запрашиваемого, поэтому вы должны всегда проверять значение NumberOfPages для того, чтобы узнать, какое именно количество страниц было выделено. Фреймы всех выделенных страниц последовательно помещаются в память на которую указывает параметр UserPfnArray.
В случае ошибки функция вернет False. Для получения расширенной информации об ошибке следует сделать вызов GetLastError.
Описание
Функция AllocateUserPhysicalPages используется для выделения физической памяти. Память, выделяемая этой функцией, должна физически присутствовать в системе. Выделенная однажды, она фиксирует свое расположение в памяти и более не управляется менеджером памяти Windows 2000.
Физическая страница памяти не может быть спроецирована по более чем одному виртуальному адресу.
Физическая страница может находиться по любому физическому адресу. Вы не должны делать никаких предположений относительно смежности физических страниц.
Используйте функцию GetSystemInfo для того, чтобы определить размер страницы на вашем компьютере.
MapUserPhysicalPagesScatter
Функция MapUserPhysicalPagesScatter проецирует выделенную ранее область физической памяти в указанное адрtсное пространство AWE-региона виртуальной памяти. В отличие от функции MapUserPhysicalPages, данная функция производит "групповое" проецирование или разпроецирование для нескольких регионов.
{ Вариант 1 }
function MapUserPhysicalPagesScatter(
var lpAddresses: Pointer; // начальный адрес области памяти
NumberOfPages: UINT; // размер физической памяти в страницах
var UserPfnArray: UINT // первый элемент массива фреймов страниц
): Boolean; overload;
{ Вариант 2 }
function MapUserPhysicalPagesScatter(
var lpAddresses: Pointer; // начальный адрес области памяти
NumberOfPages: UINT; // размер физической памяти в страницах
UserPfnArray: Pointer // указатель на массив фреймов страниц
): Boolean; overload;
Параметры
lpAddresses [in]
Задает начальный элемент массива адресов, в которые будет спроецирована физическая память. Значение каждого адреса должно находиться внутри диапазона виртуального адресного пространства приложения, выделенного при помощи функции {VirtualAlloc} с атрибутом, указывающим принадлежность выделяемого фрагмента памяти к AWE-региону. Значение NumberOfPages показывает количество элементов массива. Заметим, что значения указателей могут принадлежать нескольким различным AWE-регионам.
NumberOfPages [in]
Задает размер в страницах физической памяти (и виртуального адресного пространства). Адреса страниц в виртуальном адресном пространстве сождержаться в массиве, начальный элемент которого lpAddresses. Кадры физической памяти задаются параметром UserPfnArray. Общее число страниц не может превышть то количество страниц, которое было выделено при вызове {AllocateUserPhysicalPages}.
UserPfnArray [in]
Задает начальный элемент массива фреймов страниц (вариант 1). Эти фрейймы должны быть спроецированы в область памяти, на которую указывает параметр lpAddress. Указанный массив должен содержать по меньшей мере NumberOfPages элементов типа UINT.
Важно! Не пытайтесь модифицировать содержимое этого буфера. Он содержит данные, принадлежащие операционной системе, повреждение которых можт повлечь за собой катастрофические последствия. В этом буфере не содержиться никакой информации, необходимой вашему приложению.
Указание значение nil этому параметру (вариант 2), позволяет провести распроецирование указанного диапазона адресов. При этом указанные страницы не освобождаются в физической памяти, для этого нужно выполнять специальный вызов FreeUserPhysicalPages.
Возвращаемое значение
В случае удачного завершения фкнция возвращает True.
В случае ошибки (когда не было выпоолнено ни частичного, ни полного проецирования) функция вернет False. Для получения расширенной информации об ошибке следует сделать вызов GetLastError.
Описание
Любое количество страниц в физической памяти никак не затрагивает память, выделенную при помощи функции VirtualAlloc. Новая проекция физической памяти на виртуальное адресное пространство процесса автоматически перезаписывает все старые проекции.
Вы не можете спроецровать на виртуальное адресное пространство процесса страницы, которые не были выделены при помощи метода AllocateUserPhysicalPages.
Если со страницы физической памяти было снято проецирование на виртуальное адресно пространство процесса, то это не приводит к освобождению страницы физической памяти. Чтобы освободить страницу в физической памяти, необходимо выполнить вызов FreeUserPhysicalPages.
Страницы физической памяти могут располагаться где угодно. Вы не можете делать каких либо предположений относительно расположения страниц в оперативной памяти. Если со страницы физической памяти было снято проецирование на виртуальное адресно пространство процесса, то это не приводит к освобождению страницы физической памяти. Чтобы освободить страницу в физической памяти, необходимо выполнить вызов FreeUserPhysicalPages.
В многопроцессорных системах данная функция сохраняет согласованность буферов на аппаратном уровне. По выходе из функции гарантируется, что все потоки и процессы будут видеть корректное проецирование страниц.
FreeUserPhysicalPages
Функция FreeUserPhysicalPages освобождает физические страницы памяти, которые были ранее выделены при помощи вызова {AllocateUserPhysicalPages}. Если текущие страницы были спроецированы в AWE-регион, то при вызове автоматически произойдет очишение проецирования. Заметим, что указанный вызов никак не затронет виртуальное адресное пространство, занимающее AWE-регион.
function FreeUserPhysicalPages(
hProcess: THandle, // дескриптор процесса
var NumberOfPages: Cardinal, // количество страниц для освобождения
var UserPfnArray: DWORD // виртуальный адрес фреймов освобождаемых страниц
): Boolean; stdcall;
Параметры
hProcess [in]
Дескриптор процесса. Функция освобождает память в виртуальном адресном пространстве этого процесса.
NumberOfPages [in/out]
Указывает размер физической памяти в страницах, которая будет освобождена. При возвращении с случае ошибки возвращает количество страниц в памяти, которые действительно были освобождены.
UserPfnArray [in]
Задает виртуальное адресное пространство, которое содержит фреймы страниц, которые должны быть освобождены.
Возвращаемое значение
При удачном завершении функция возвращает True.
В случае возникновения ошибки функция вернет False. В этом случае параметр NumberOfPages показывает, сколько страниц было освобождено в действительности. Для получения расширенной информации об ошибке выполните вызов GetLastError.
Описание
В случае нескольких процессоров эта функция поддерживает согласованное выполнение на уровне аппаратного переводного буфера. При выходе из этой функции, для всех потоков и процессов гарантируется корректное проецирование.
Требования
Windows NT/2000: Требуется Windows 2000 или более поздняя версия
Windows 95/98: Не поддерживается
Бибиотека: Kernel32.dll
Подключаемый модуль: Не описана
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!