mmap e transferências de DMA lentas

1

Eu tenho um processo que lê dados de um dispositivo de hardware usando DMA transfere a uma velocidade de ~ 4 * 50MB / s e ao mesmo tempo os dados são processados, compactados e gravados em um arquivo mapeado de memória de 4TB.

Cada transferência de DMA deve (e faz, em média) demorar menos de 20 ms. No entanto, algumas vezes a cada 5 minutos, as transferências de DMA podem levar até 300 ms, o que é um grande problema.

Acreditamos que isso pode estar relacionado ao kernel liberando páginas mapeadas com memória suja para o disco. Como se pararmos de gravar na memória mapeada, as durações das transferências de DMA estarão bem. No entanto, estamos confusos sobre como / por que isso pode afetar as transferências de DMA e se existe uma maneira de evitar isso?

O dispositivo de hardware tem alguma memória para armazenar dados em buffer, mas quando as transferências de DMA são tão lentas, estamos perdendo dados.

Atualmente, estamos testando o Arch Linux com um kernel de 4.1.10 lts, mas também testamos o Ubuntu 14.04 com resultados muito piores. Hardware é uma workstation HP z820, 32GB de RAM e dual Xeon E5-2637 @ 3.50Ghz ( link ).

Nós também testamos uma versão para Windows do nosso software que não sofre com esse problema específico, mas tem muitos outros problemas.

    
por ronag 26.10.2015 / 10:04

3 respostas

2

O Linux tem algumas opções realtime , embora não seja um kernel em tempo real como tal. Isso permite que um processo exija que ele seja agendado antes de processos não em tempo real, assim que estiver pronto, e segure a cpu pelo tempo que for necessário.

Por padrão, os processos recebem a política de agendamento SCHED_OTHER. Você pode configure isso para SCHED_FIFO em tempo real para um determinado pid de execução com chrt -f -p prio pid , ou prefixar o comando com chrt -f prio ao iniciá-lo. O código% A prioridade é independente dos processos normais e é usada apenas quando os processos em tempo real competem por recursos. prio mostra essas prioridades como valores negativos (por exemplo, -21 para o prio 20 em tempo real).

ps também pode ajudar a programar seu processo com enfileiramento io preferencial em tempo real.

    
por 28.10.2015 / 13:31
1

O seu dispositivo opera continuamente por alguns minutos ou há pausas regulares nas transferências?

Se houver pausas, você poderá forçar o kernel a buffers vazios e cache durante estes, então esta atividade não interferiria com as transferências de DMA. Alternativamente, você pode configurar seu kernel para ter BDFLUSHR interval de 1 segundo, para que o kernel tenha menos dados para gravar toda vez que ele decidir esvaziar os buffers.

Se você precisa garantir uma operação contínua, precisará de RAM com mais canais, para que a CPU e seu dispositivo possam acessar a memória simultaneamente (como se sabe, você já tem um controlador de memória de 4 canais). Certifique-se de configurar sua RAM em modo não definido , se essa opção estiver disponível. Certifique-se de ter instalado módulos DRAM similares em 4 slots correspondentes aos canais de memória, para que o controlador de memória possa, de fato, operar no modo de 4 canais.

    
por 26.10.2015 / 10:38
0

Eu acho que você não modificou as configurações de páginas sujas do kernel. Para o seu caso de uso, eu tentaria algo assim:

/proc/sys/vm/dirty_background_bytes:50000000
/proc/sys/vm/dirty_bytes:4000000000
/proc/sys/vm/dirty_expire_centisecs:100
/proc/sys/vm/dirty_writeback_centisecs:20

(Veja link para detalhes.)

O problema é basicamente que os limites de kernel padrão são problemáticos se o sistema tiver muita memória RAM e um dispositivo de armazenamento lento o suficiente e você estiver procurando a pior latência do pior caso. Na prática, o buffer do subsistema de E / S do sistema é preenchido e ele precisa forçar os processos de gravação a adormecer até que dados suficientes tenham sido gravados para bloquear dispositivos ("liberando páginas sujas").

    
por 16.05.2017 / 15:45

Tags