Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
8-1077809370
Spartak
2004-02-26 18:29
2004.05.16
Смена картинок


11-1068996521
DeF
2003-11-16 18:28
2004.05.16
Дочерние окна


14-1083042907
Drozdov A
2004-04-27 09:15
2004.05.16
CorelDraw 11


14-1082704706
paul_k
2004-04-23 11:18
2004.05.16
Есть вакансия в Москве


14-1082696455
V.exeR
2004-04-23 09:00
2004.05.16
"Улица ремесел"





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский