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:
- Chamada do sistema para criar mapeamentos virtuais - muito caros
- O processo acessa a memória pela primeira vez, causando uma falha de página - cara (e pode precisar ser repetida se paginada)
- 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:
- 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)
- 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:
- 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.