Эффективный способ замены байтов в файле с отображенной памятью - PullRequest
2 голосов
/ 03 июля 2011

Мне удалось проанализировать большой двоичный файл (~ 8 ГБ), прочитав блоки данных в память и обменяв целые числа с прямым порядком байтов с помощью функций, показанных ниже.Однако я пытаюсь повысить производительность с помощью Boost Memory-Mapped файлов , но я не могу использовать функции endian_swap, поскольку файл открывается в режиме только для чтения.Есть ли эффективный способ поменять байты без записи оригинального файла?Если нет, производительность будет зависеть от затрат ввода-вывода?

inline void endian_swap(unsigned short int& x)
{
  x = (x>>8) |
    (x<<8);
}
inline void endian_swap(unsigned int& x)
{
  x = (x>>24) |
    ((x<<8) & 0x00FF0000) |
    ((x>>8) & 0x0000FF00) |
    (x<<24);
}
inline void endian_swap(unsigned long long int& x)
{
  x = (((unsigned long long int)(x) << 56) | \
      (((unsigned long long int)(x) << 40) & 0xff000000000000ULL) | \
      (((unsigned long long int)(x) << 24) & 0xff0000000000ULL) | \
      (((unsigned long long int)(x) << 8)  & 0xff00000000ULL) | \
      (((unsigned long long int)(x) >> 8)  & 0xff000000ULL) | \
      (((unsigned long long int)(x) >> 24) & 0xff0000ULL) | \
      (((unsigned long long int)(x) >> 40) & 0xff00ULL) | \
      ((unsigned long long int)(x)  >> 56));
}

Код был найден в этой статье .Большое спасибо за ваше время

1 Ответ

2 голосов
/ 03 июля 2011

По крайней мере базовая операционная система поддерживает желаемое поведение:

   MAP_PRIVATE
              Create a private copy-on-write mapping.  Updates
              to the mapping are not visible to other processes
              mapping the same file, and are not carried through
              to the underlying file.  It is unspecified whether
              changes made to the file after the mmap() call are
              visible in the mapped region.

Появляется флаг priv, переводящий в MAP_PRIVATE:

void* data = 
    ::BOOST_IOSTREAMS_FD_MMAP( 
        const_cast<char*>(p.hint), 
        size_,
        readonly ? PROT_READ : (PROT_READ | PROT_WRITE),
        priv ? MAP_PRIVATE : MAP_SHARED,
        handle_, 
        p.offset );
if (data == MAP_FAILED)
    cleanup_and_throw("failed mapping file");
...