Эффективный способ обмена байтами в файле с отображением памяти

Мне удалось проанализировать большой двоичный файл (~ 8 ГБ), прочитав блоки данных в память и поменяв местами целые числа с прямым порядком байтов, используя функции, показанные ниже. Однако я пытаюсь повысить производительность, используя Увеличьте отображение файлов в памяти, но я не могу использовать функции 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));
}

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


person Emer    schedule 03.07.2011    source источник


Ответы (1)


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

   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");
person sarnold    schedule 03.07.2011
comment
Я не реализовал функцию флага открытого режима, потому что я использовал версию 1.42, в то время как это было реализовано в 1.44. Спасибо! - person Emer; 03.07.2011
comment
@ Эмер, ага! Это мелкие детали, которые имеют большое значение в мире ... когда я прихожу и смотрю на источник на веб-сайте, совсем не очевидно, что это новая функция. :) - person sarnold; 03.07.2011