Можно ли кэшировать сопоставленные регионы, возвращенные из MapViewOfFile? - PullRequest
0 голосов
/ 03 марта 2011

Добрый день. Общеизвестным фактом является то, что при работе с большими файлами, которые нельзя сопоставить с одним представлением в Win32, создайте код, который тщательно отображает и отображает области файлов по мере необходимости.URL пастбина:

Я создал и протестировал класс cMemoryMappedFile, который работает с большими файлами, которые нельзя сопоставить с одним представлением в Win32.Я проверил класс и обнаружил, что хотя он функционирует нормально, для произвольного доступа требуется много времени (то есть 3 секунды).Это связано с тем, что класс должен отображать и отображать файловую область для каждого произвольного доступа.Мне было интересно, можно ли было кэшировать отображенные области, возвращенные из MapViewFile, для ускорения произвольного доступа.

Вчера я заметил, что UnMapViewOfFile делает недействительным ранее отображенную область, возвращенную из MapViewOfFile.У кого-нибудь есть идеи о том, как ускорить произвольный доступ с помощью кэширования или других методов?

В настоящее время область просмотра составляет 128 КБ.Я считаю, что если я увеличу область просмотра, это уменьшит количество вызовов UnMapViewOfFile и MapViewOfFile.Однако мне было интересно, если можно было бы использовать другие методы.Пожалуйста, посмотрите на метод,
char * cMemoryMappedFile :: GetPointer (int, bool), чтобы увидеть, как область просмотра перемещается с отображением файла.Спасибо.

URL-адрес вставки для класса
>.Я добавляю сюда исходный код на случай, если никто не сможет получить доступ к URL.

// cMemoryMappedFile.Cpp
#include "cException.h"
#include "cMemoryMappedFile.h"

#define BUFFER_SIZE 10

#define MEM_BLOCK_SIZE 65536 * 2

/**
\class cMemoryMappedFile
\brief Encapsulation of the Windows Memory Management API.

The cMemoryMapped class makes some memory mapping operations easier.
*/

/**
\brief Constructor for cMemoryMappedFile object.

\param FileSize    Size of file.
\param OpenMode    File open mode 
\param AccessModes File access mode 
\param ShareMode   File sharing mode 
\param Flags       File attributes and flags 
\param ShareMode   File sharing mode 
\param Flags       File attributes and flags
\param Security    Security Attributes 
\param Template    Extended attributes tp apply to a newly created file
*/
cMemoryMappedFile::cMemoryMappedFile(long FileSize_, OpenModes OpenMode_,AccessModes AccessMode_,
    ShareModes ShareMode_,long Flags_,void *Security_,FILEHANDLE Template_) {
    FileSize = FileSize_;
char buffer[BUFFER_SIZE]; 
DWORD dwRetVal = 0;
UINT uRetVal   = 0; 
     DWORD dwPtr    = 0;
BOOL isSetEndOfFile = FALSE;
     LARGE_INTEGER Distance_;
DWORD ErrorCode = 0;

char lpTempPathBuffer[MAX_PATH]; 

     PreviousNCopy = 0;
PreviousN     = 0;

//  Gets the temp path env string (no guarantee it's a valid path).
dwRetVal = GetTempPath(MAX_PATH,          // length of the buffer
                       lpTempPathBuffer); // buffer for path 
if (dwRetVal > MAX_PATH || (dwRetVal == 0))
{
   throw cException(ERR_MEMORYMAPPING,"");  
     }

     //  Generates a temporary file name. 
     uRetVal = GetTempFileName(lpTempPathBuffer, // directory for tmp files
                          TEXT("DEMO"),     // temp file name prefix 
                          0,                // create unique name 
                          TempFileName);  // buffer for name 
     if (uRetVal == 0)
     {

      throw cException(ERR_MEMORYMAPPING,lpTempPathBuffer);  
     }
     //  Creates the new file
     hFile = CreateFile((LPTSTR) TempFileName, // file name 
                       AccessMode_,        // open for write 
                       0,                    // do not share 
                       (SECURITY_ATTRIBUTES *) Security_,  // default security 
                       OpenMode_, // CREATE_ALWAYS,       
                       Flags_,// normal file 
                       Template_);                // no template 
     if (hFile == INVALID_HANDLE_VALUE) 
     { 
       throw cException(ERR_MEMORYMAPPING,TempFileName);   
     } 
     Distance_.LowPart = (ULONG)FileSize_;
Distance_.HighPart = 0; // (ULONG)(FileSize_ >> 32);
dwPtr = ::SetFilePointer(hFile,Distance_.LowPart,
    &(Distance_.HighPart), FileBegin);

if (dwPtr == INVALID_SET_FILE_POINTER){
   throw cException(ERR_MEMORYMAPPING,TempFileName);
}
isSetEndOfFile = SetEndOfFile(hFile);
if (!isSetEndOfFile){
   ErrorCode = GetLastError();
   throw cException(ERR_MEMORYMAPPING,TempFileName);
}
hMapping=::CreateFileMapping(hFile,(SECURITY_ATTRIBUTES *)Security_,PAGE_READWRITE,0,0,0);
if (hMapping==NULL)
    throw cException(ERR_MEMORYMAPPING,TempFileName);   

MapPtr = 0;
adjustedptr = 0;
prevadjustedptr = adjustedptr;

    FilePath=new char[strlen(TempFileName)+1];
    strcpy(FilePath,TempFileName);
}



char * cMemoryMappedFile::GetPointer(int n, bool Caching){
unsigned int baseoff; 
if( n < MEM_BLOCK_SIZE / 2)
{
  baseoff = 0;
}
else
{
  baseoff = ((n + MEM_BLOCK_SIZE / 4) & 
    (~(MEM_BLOCK_SIZE / 2 - 1))) - MEM_BLOCK_SIZE / 2;

}
// the correct memory mapped view is already mapped in
     if (adjustedptr != 0 && mappedoffset == baseoff && Caching)
    return adjustedptr;
else if (Caching)
{
  /*    
   retrieve adjustedptr from cache
      */
}
// get a new memory mapped viewport
else{
    if (MapPtr){
                 UnmapViewOfFile(MapPtr);
       PreviousNCopy = PreviousN;
       prevadjustedptr = adjustedptr;
    }
    PreviousN = n;
              mappedlength = min(FileSize - baseoff, MEM_BLOCK_SIZE); 

              // MapViewOfFile should be aligned to 64K boundary

    MapPtr = (char*)::MapViewOfFile( hMapping, 
                       FILE_MAP_WRITE | FILE_MAP_READ, 0, 
        baseoff, mappedlength);
              mappedoffset =    baseoff;
    adjustedptr = MapPtr - mappedoffset; 
    printf("Value: %u n: %u\n",adjustedptr[n],n);

 /*
    cache PreviousNCopy,PreviousN, prevadjustedptr[PreviousNCopy]
 */

}
 return adjustedptr; 
}

1 Ответ

1 голос
/ 03 марта 2011

Вы можете иметь кэш в стиле «свободный список» - когда пользователь вашего класса просит удалить карту из области, которую вы на самом деле не делаете, вы просто добавляете ее в список. Когда они просят сопоставить новый регион, вы, если возможно, повторно используете существующее сопоставление, в противном случае вы создаете новое сопоставление, удаляя наименее недавно использованное сопоставление из кэша, если у вас открыто слишком много сопоставлений или если размер сопоставления кэшированных отображений слишком велико.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...