Главная страница
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.49 MB
Время: 0.031 c
11-1068754184
puky
2003-11-13 23:09
2004.05.16
KOLCDWriter ? где он?


1-1083588888
Ivolg
2004-05-03 16:54
2004.05.16
RxLibiray


8-1078273036
Jaine
2004-03-03 03:17
2004.05.16
Смена иконки (Glyph) на кнопке типа BitBtn or Speedbutton


14-1082704783
*Pavel
2004-04-23 11:19
2004.05.16
Есть ли выход из интернета ?


1-1083213421
M@X
2004-04-29 08:37
2004.05.16
Перевод с СИ