Текущий архив: 2004.05.16;
Скачать: CL | DM;
ВнизГранулярность памяти, FileMapping Найти похожие ветки
← →
dmk © (2004-03-25 00:37) [0]1. Насколько я понял из MSDN, проекция файла в память
должна начинаться с адреса кратному размеру выделения
памяти(_system_info.dwAllocationGranularity) в моем случае
это 65536.
Так вот вопрос: Как получить блок памяти который начинается
с адреса памяти кратного этому размеру?
Или опровергните мои соображения если я не так понял.
В любом случае блок памяти выделенный с помощью функций
WinApi или Delphi начинается с адреса кратного 65536 + 4 байта! При этом функция MapViewOfFileEx ни в какую не хочет пронимать
в виде последнего параметра мой блок памяти и присваивает
ему nil.
2. Приведенная ниже процедура - это пример из книги Рихтера
"Windows для профессианалов". Она просто читает данные из файла и подсчитывает кол-во нулей. Я хотел сделать чтение файлов с
помощью проекции но в свой блок памяти. Возможно ли это сделать
непосредственно из файла минуя промежуточные, выделенные
системой блоки памяти?
3. Почему скорость проецирования получается ниже, нежели
если прочесть файл процедурой BlockRead?
procedure TMainForm.FmButtonClick(Sender: TObject);
var
hName: String;
hFile: THandle;
hSize: DWord;
hOffset: DWord;
hMap: THandle;
AMode: DWord;
lpBytes: Pointer;
sInfo: _System_Info;
dwBlockSize: DWord;
MappedBytes: DWord;
NumZeros: DWord;
sT,eT: DWord;
tB: Pointer;
//i: DWord;
begin
AMode := GENERIC_READ;
If not OpenDialog.Execute then Exit;
hName := OpenDialog.FileName;
GetSystemInfo(sInfo);
dwBlockSize := sInfo.dwAllocationGranularity;
sT := GetTickCount;
hFile := CreateFile(PChar(hName), AMODE,
0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
//...
If hFile = INVALID_HANDLE_VALUE then
begin
ErrorMessage(hName + #13 + #13 + "File open error!");
CloseHandle(hFile);
Exit;
end;
hSize := GetFileSize(hFile, nil);
If hSize < dwBlockSize then dwBlockSize := hSize;
hMap := CreateFileMapping(hFile, nil, PAGE_READONLY, 0, hSize, "Test866");
If (hMap <> 0) and (GetLastError = ERROR_ALREADY_EXISTS) then
begin
CloseHandle(hMap);
hMap := 0;
end;
If hFile <> 0 then CloseHandle(hFile);
MappedBytes := hSize;
hOffset := 0;
NumZeros := 0;
tB := SysGetMem(dwBlockSize);
While MappedBytes <> 0 do
begin
lpBytes := MapViewOfFileEx(hMap, FILE_MAP_READ, 0, hOffset, dwBlockSize, nil);
asm
push ecx
push edx
push ebx
mov edx, DWord ptr [lpBytes]
mov ecx, dwBlockSize
mov ebx, NumZeros
@@np:
mov al, [edx]
test al, al
jnz @@Ex
inc ebx
@@Ex:
inc edx
dec ecx
jnz @@np
mov NumZeros, ebx
pop ebx
pop edx
pop ecx
end;
UnmapViewOfFile(lpBytes);
Inc(hOffset, dwBlockSize);
Dec(MappedBytes, dwBlockSize);
If MappedBytes < dwBlockSize then
dwBlockSize := MappedBytes;
end;//While
If hMap <> 0 then CloseHandle(hMap);
eT := GetTickCount;
SysFreeMem(tB);
DrawTimeValue("Map time: ", sT, eT);
InfoMessage("Num zeros: " + IntToStr(NumZeros));
end;
← →
dmk © (2004-03-25 00:38) [1]Извиняюсь! пронимать - понимать
← →
Игорь Шевченко © (2004-03-25 01:14) [2]
> 3. Почему скорость проецирования получается ниже, нежели
> если прочесть файл процедурой BlockRead?
Кэш для в случае использования BlockRead задействует опережающее чтение.
> Как получить блок памяти который начинается
> с адреса памяти кратного этому размеру?
"No other memory allocation, including use of the VirtualAlloc function to reserve memory, can take place in the region used for mapping"
Просто задать адрес. Руками.
> В любом случае блок памяти выделенный с помощью функций
> WinApi или Delphi начинается с адреса кратного 65536 + 4
> байта!
Запусти простой пример:
unit main;
interface
uses
Forms;
type
TfMain = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
private
FMemory: Pointer;
end;
var
fMain: TfMain;
implementation
uses
Windows, SysUtils, Dialogs;
{$R *.dfm}
procedure TfMain.FormCreate(Sender: TObject);
begin
FMemory := VirtualAlloc(nil, $20000, MEM_RESERVE, PAGE_READWRITE);
if not Assigned(FMemory) then
RaiseLastOSError;
end;
procedure TfMain.FormShow(Sender: TObject);
begin
ShowMessageFmt("The memory reserved at %.8x", [Integer(FMemory)]);
end;
end.
Посмотри, какой адрес он выдаст.
Сравни с тем, как ты получаешь и смотришь адрес.
← →
MBo © (2004-03-25 06:49) [3]1. Насколько я понял, ты неправильно понял ;)
Функции MapViewOfFile должно передаваться смещение в файле, кратное 65536, она возвращает указатель на область памяти, выделенную СИСТЕМОЙ, а самому выделять память не надо.
(и адрес этот выровнен на 64K, но нас это обычно не волнует)
MapViewOfFileEx предназначена для специфических применений, для случаев, когда маппирование по каким-то причинам желательно иметь по заданному тобой адресу. (твой пункт 2.)
про 65536+4 - некоторые функции выделения памяти хранят перед выделенным блоком его размер.
← →
dmk © (2004-03-25 19:16) [4]Долго я ковырялся с MapViewOfFileEx и пришел к выводу, что
использование Борландовских функций более практичнее.
Огромное Спасибо за ответы. =)
Страницы: 1 вся ветка
Текущий архив: 2004.05.16;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.038 c