Como o mapeamento de memória de um arquivo aumenta significativamente o desempenho em relação às chamadas de sistema de E / S padrão?

3

Conceitos do sistema operacional diz

Consider a sequential read of a file on disk using the standard system calls open(), read(), and write(). Each file access requires a system call and disk access.

Alternatively, we can use the virtual memory techniques discussed so far to treat file I/O as routine memory accesses. This approach, known as memory mapping a file, allows a part of the virtual address space to be logically associated with the file. As we shall see, this can lead to significant performance increases. Memory mapping a file is accomplished by mapping a disk block to a page (or pages) in memory. Initial access to the file proceeds through ordinary demand paging, resulting in a page fault. However, a page-sized portion of the file is read from the file system into a physical page (some systems may opt to read in more than a page-sized chunk of memory at a time). Subsequent reads and writes to the file are handled as routine memory accesses. Manipulating files through memory rather than incurring the overhead of using the read() and write() system calls simplifies and speeds up file access and usage.

Você poderia analisar o desempenho do arquivo mapeado na memória?

Se eu estiver correto, o arquivo de mapeamento de memória funciona da seguinte maneira. É necessária uma chamada de sistema para criar um mapeamento de memória. Então, quando ele acessa a memória mapeada, ocorrem falhas de página. Falhas de página também têm sobrecarga.

Como o mapeamento de memória de um arquivo aumenta significativamente o desempenho em relação às chamadas de sistema de E / S padrão?

Obrigado.

    
por Tim 11.10.2018 / 23:42

2 respostas

6

O mapeamento de memória de um arquivo evita diretamente os buffers de cópia que ocorrem com as chamadas read () e write (). As chamadas para read () e write () incluem um ponteiro para armazenar em buffer no espaço de endereço do processo onde os dados são armazenados. O kernel precisa copiar os dados de / para esses locais. O uso de mmap () mapeia o arquivo para processar o espaço de endereçamento, para que o processo possa endereçar o arquivo diretamente e nenhuma cópia seja necessária.

Também não há sobrecarga na chamada do sistema ao acessar o arquivo mapeado na memória após a chamada inicial.

Se você tiver interesse nos detalhes práticos, há uma questão relacionada no Stack Overflow: mmap () vs. blocos de leitura

    
por 11.10.2018 / 23:52
4

Primeiro, na maioria das operações de IO, as características do hardware de armazenamento subjacente dominam o desempenho. Um array RAID5 mal configurado de vinte e nove discos SATA SLOW 5400 rpm em um sistema lento e sem memória usando S / W RAID com tamanhos de bloco incompatíveis e sistemas de arquivos desalinhados vai lhe dar um desempenho ruim se comparado a um configurado e alinhado corretamente SSD RAID 1 + 0 em um controlador de alto desempenho, apesar de qualquer ajuste de software que você possa tentar.

Mas a única maneira que o mmap() pode ser significativamente mais rápido é se você ler os mesmos dados mais de uma vez e os dados que você lê não são paginados entre as leituras devido à pressão da memória. / p>

Passos do mapa de memória:

  1. Chamada do sistema para criar mapeamentos virtuais - muito caros
  2. O processo acessa a memória pela primeira vez, causando uma falha de página - cara (e pode precisar ser repetida se paginada)
  3. O processo realmente lê a memória

Se o processo apenas executar as etapas 2 e 3 uma vez para cada bit de dados lidos, ou se os dados forem retirados da memória devido à pressão da memória, mmap() será mais lento.

read() etapas:

  1. Chamada do sistema copia dados do disco para o cache da página (pode ou não ocorrer falha na página, os dados podem já estar no cache da página, fazendo com que isso seja ignorado)
  2. Dados copiados do cache de páginas para processar memória (pode ou não funcionar com falha de página)

O mapeamento de memória só vai superar esse desempenho por causa dessa cópia extra do cache de páginas para processar memória. Mas uma mera cópia de uma página de memória (ou menos) tem que ser feita várias vezes para compensar o custo de configurar o mapeamento - provavelmente. Quantas vezes depende do seu sistema. Largura de banda de memória, como todo o seu sistema está sendo usado, tudo. Por exemplo, se o tempo usado pelo gerenciamento de memória do kernel para configurar o mapeamento não tiver sido usado por nenhum outro processo, o custo de criar o mapeamento realmente não é muito alto. Por outro lado, se você tem muito processamento em seu sistema que envolve muita criação / destruição de mapeamento de memória virtual (ou seja, muitos processos de curta duração), o impacto do IO mapeado na memória pode ser significativo.

Depois, há read() usando IO direto:

  1. Chamada do sistema para ler do disco no espaço da memória do processo. (pode ou não causar uma falha de página)

As leituras diretas de E / S são praticamente impossíveis de superar no desempenho. Mas você precisa ajustar seus padrões de E / S ao seu hardware para maximizar o desempenho.

Observe que um processo pode controlar bastante se a leitura de dados causar uma falha de página no buffer que o processo está usando para ler.

Então, o acesso ao arquivo mapeado na memória é mais rápido? Talvez seja, talvez não seja.

Depende do seu padrão de acesso. Junto com seu hardware e tudo mais em seu caminho de IO.

Se você estiver transmitindo um arquivo de vídeo de 30 GB em uma máquina com 4 GB de RAM e nunca voltar e reler nenhum dos dados, o mapeamento de memória provavelmente será o pior maneira de lê-lo.

Por outro lado, se você tiver uma tabela de consulta de 100 MB para alguns dados que acessa bilhões e bilhões de vezes em seu processamento e memória suficiente para que o arquivo nunca seja paginado, o mapeamento de memória esmagará todos os outros métodos de acesso.

Uma enorme vantagem de arquivos mapeados na memória

Arquivos de mapeamento de memória têm uma enorme vantagem sobre outras formas de IO: simplicidade de código. É realmente difícil superar a simplicidade de acessar um arquivo como se estivesse na memória. E, na maioria das vezes, a diferença de desempenho entre o mapeamento de memória de um arquivo e a realização de operações de E / S discretas não é tão grande assim.

    
por 12.10.2018 / 11:46