Главная страница
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.04 c
3-1082637652
iat
2004-04-22 16:40
2004.05.16
Как узнать номер столбца в DBGrid е при ДВОЙНОМ клике


4-1080167394
Тёма
2004-03-25 01:29
2004.05.16
Как переименовать сетвой диск?


1-1083355606
konstantinov
2004-05-01 00:06
2004.05.16
Автоматически уничтожаемое окно


1-1083133018
Stas
2004-04-28 10:16
2004.05.16
тип PCHAR и ACCESS


3-1082614708
tim_131
2004-04-22 10:18
2004.05.16
Как пользоваться BookMark-ом