Acelerando suas Transferências USB

Método permite aumentar o limite das transferências USB, melhorando a velocidade de gravação e leitura de pendrives ou HDs externos no Linux.


| Se você apoia nosso site, desative o AdBlock quando visitá-lo, inclusive em Mobile!
Os anúncios são poucos e não invasivos. Se quiser contribuir com nosso trabalho, clique em qualquer banner de sua preferência, exceto dos Parceiros. 
Mais detalhes clicando aqui.


Introdução

Quase todos os sistemas Linux possuem esse “problema” do gargalo na transferência de arquivos via USB. O problema é maior quando se compara com transferências USB pelo Windows, que é bem mais rápido.

Antes de prosseguir com a solução, preciso apontar algumas informações:

  • Motivo 1. O armazenamento em cache de arquivos pode fazer com que as gravações pareçam mais lentas ou mais rápidas. O problema que eu vejo na GUI é que a barra de progresso vai para 90% quase instantaneamente, completa para 100% um pouco mais devagar e depois fica pendurada por 10 minutos.

Uma coisa que você precisa entender é o armazenamento em cache de arquivos. Linux (e Windows) usarão RAM “vazia” para armazenar operações de leitura/gravação e torná-las mais rápidas em acessos subsequentes.

Armazenar em cache as operações de cópia para diminuir a velocidade dos dispositivos resulta no comportamento que você vê – a “conclusão rápida” está realmente gravando no cache e, em seguida, diminui e pára porque o fluxo real dos dados no cache (sincronização) para o dispositivo está demorando muito. Se você interromper nesse ponto, os dados serão corrompidos, já que a sincronização nunca foi concluída.

Essa cópia no Windows pode parecer mais rápida (incluindo as velocidades de MB/s relatadas) porque às vezes o Windows não esperará pela sincronização e declarará o trabalho concluído assim que os dados forem gravados no cache.

  • Motivo 2. Escrever muitos arquivos, especialmente os pequenos, é lento

Devido à maneira como a memória flash e os sistemas de arquivos funcionam, o rendimento (velocidade) mais rápido é obtido ao gravar arquivos muito grandes. Escrever muitos arquivos pequenos ou até mesmo misturar dados contendo vários arquivos pequenos pode atrasar muito o processo. Isso afeta os discos rígidos também, mas em menor grau.

  • Motivo 3. As velocidades de gravação de um pendrive e de um SSD conectados á porta USB não podem ser comparadas

Um pendrive USB geralmente consiste em chips de memória flash que são gravados em série (sequencialmente) e não possuem cache próprio.

Um SSD, por outro lado, contém um controlador que grava paralelamente os chips de memória flash, aumentando o rendimento por um fator de 2 ou mais sobre o pendrive. Se o seu SSD de 32 GB tiver 4 chips de 8 GB, ele ainda será 4 vezes mais rápido que o dispositivo USB em qualquer operação de gravação.

O SSD também contém o cache de RAM (como discos rígidos), para que ele possa armazenar rapidamente os dados que chegam no cache e informar ao SO que está pronto, enquanto ainda precisa gravar esses dados na memória flash.

Então, com um arquivo grande, seu GB de 32 GB com a estrutura de 4x que assumimos seria 4x mais rápido; com muitos arquivos pequenos, seria 10x ou mais mais rápido, porque poderia armazená-los de forma inteligente em seu cache.

Problema

Então vamos hipoteticamente imaginar que tudo está equivalente entre Windows e Linux numa transferência bruta de arquivos pequenos e grandes. O Windows continuará em vantagem!
E aqui aponto mais 2 problemas:

  1. O Fat32 é um formato padrão de pendrives porém proprietário da Microsoft.
    Por mais otimizado que os drivers dele estejam hoje em dia para Linux, ele está longe de ser tão perfeito quanto o Windows, principalmente em desempenho.
  2. A culpa é do Kernel Linux, e sua maneira de lidar com os dados de forma assíncrona.
  • Perai, culpa do Kernel?

Um primeiro conceito que deve ficar claro é: o Linux trabalha por padrão com buffered I/O.

De forma simplificada, isso significa que as operações de escrita simplesmente copiam os dados para a memória RAM, e depois, em background, o kernel vai fazendo a escrita em si (flush) no dispositivo destino. Dado isto, entra o segundo conceito: dirty memory, que é justamente essa informação que está temporariamente na memória RAM, esperando ser escrita em um dispositivo de armazenamento.

Acontece que, quando copiamos muitos dados para uma mídia lenta como um pendrive, há um problema de bufferbloat, em que a fila de I/O requests fica gigantesca. Isso acarreta toda a lentidão, já que outras operações de I/O são também afetadas, além de outros efeitos colaterais.

Dentre as alternativas propostas para minimizar este problema, as mais simples envolvem ajustar os parâmetros relacionados à dirty memory do subsistema de Virtual Memory do kernel. O objetivo é deixar a fila menor, definindo um threshold mais agressivo para o flush da dirty memory para o dispositivo (a quem tiver curioso, o daemon que controla isso é o “pdflush”.).

  • Então preciso compilar algo e fazer coisas complicadas?

Não. Na verdade o procedimento envolve apenas adicionar 4 linhas a um arquivo .conf e reiniciar o PC.

Configurando

Antes de experimentar os ajustes em questão, convém monitorar o seu sistema durante uma simulação, a fim de confirmar o problema. O sintoma mais óbvio é a lentidão, mas se você quiser ir mais a fundo, pode monitorar a quantidade de dirty memory com o seguinte comando:

# watch -n1 grep -e Dirty: /proc/meminfo

Enquanto monitora, copie um arquivo grande, de alguns gigabytes, para um pendrive (não vale aquele pendrive USB 3.0 de última geração, hein?). Observe a dirty memory aumentar assustadoramente, para alguns GBs, até que o pdflush entra em ação e começa a escrever os dados no dispositivo.

Percebeu que, aparentemente, a cópia rapidamente foi concluída, mas na prática ela estava longe de terminar? Daí a importância de não remover o pendrive sem ejetar antes: podem haver muitos dados pendentes de escrita em background, e a operação de ejeção só vai concluir após eles estarem devidamente gravados.

A quem usa Linux, recomendo o comando Sync, ele sincroniza os discos e te dá um feedback de quando a escrita em segundo plano foi concluída.

$ sync

Os parâmetros importantes aqui são “vm.dirty_background_bytes”, “vm.dirty_background_ratio”, “vm.dirty_bytes” e “vm.dirty_ratio”.

Na documentação do kernel você encontra uma explicação detalhada do que cada parâmetro faz, mas pelos nomes já dá para ter uma ideia.

Atenção: os parâmetros com “bytes” e “ratio” são mutuamente exclusivos, ou seja, ajustando um, o outro automaticamente é desabilitado (ficando com valor 0).
Portanto, só 2 linhas serão válidas e você deverá testar qual par de linhas melhor funciona para você e seu sistema.

Edite seu arquivo /etc/sysctl.conf com seu editor favorito como Root e adicione as seguintes linhas ao final:

vm.dirty_background_bytes = 4194304
vm.dirty_bytes = 4194304

Uma opção também é utilizar estas linhas:

vm.dirty_background_ratio=20
vm.dirty_ratio=50

Como eu afirmei antes, bytes e ratio se anulam… Se eu colocar as 4 linhas, os valores default serão:

vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 20
vm.dirty_bytes = 0
vm.dirty_ratio = 50

Perceba que até 50% da memória RAM total pode ser dirty!
Vamos então ajustar os parâmetros para uma das recomendações, e ver o que acontece, repetindo a simulação:

# sysctl -w vm.dirty_background_bytes=16777216
# sysctl -w vm.dirty_bytes=50331648
# watch -n1 grep -e Dirty: /proc/meminfo

(repetir cópia do arquivo)

Melhorou, né? Sem contar que agora o indicador de progresso da cópia é mais confiável.

Outra opção, que dá resultados similares mas trabalha com percentuais da memória RAM, ao invés de valores absolutos em bytes, é:

# sysctl -w vm.dirty_background_ratio=5
# sysctl -w vm.dirty_ratio=10

Conclusão

Tal situação de “bufferbloat” é mais usual em desktops/notebooks, onde é comum realizar a cópia de arquivos grandes para pendrives lentos, mas é também possível de acontecer, com cenários alternativos, em servidores, sendo importante conhecer o problema, a solução, e o que está por trás dela. Claro que os valores sugeridos no acima são, como disse, recomendações; o ideal para o seu caso pode variar e é sempre importante ajustar, numa tentativa e erro, até achar o ideal.

#UrbanCompassPony

Fontes:
GitHub
AskUbuntu
Reddit
VivaOLinux

10 comentários em “Acelerando suas Transferências USB”

  1. Nathan Drake, na minha experiência com Sistemas Operacionais, para cada alteração de configuração existem prós e contras. Pensando em aumentar o valor absoluto com vm.dirty_background_bytes e vm.dirty_bytes, eu não teria comprometimento do processamento durante o processo de cópia de arquivos grandes, provocando instabilidade no sistema?

    Responder
    • Uma pergunta pertinente. Os valores padrão que vem no Linux objetivam de fato melhor estabilidade e desempenho, já que se formos comparar o Windows, por exemplo, o desempenho cai drasticamente quando faz transferências muito pesadas por muito tempo. Alterar esses valores de fato podem diminuir o desempenho geral do sistema durante uma transferência, mas considerando a otimização que um linux costuma ter nativamente, essa diferença será pequena, se comparado ao que ocorre em outros sistemas.

      Responder
  2. TESTE:1

    TECNICA:

    CONFIGURAÇÃO PADRÃO DO SISTEMA.

    ARQUIVOS:

    TIPO : VÍDEO
    FORMATO: MP4
    TAMANHO: 1.3 GB

    ORIGEM:/home/user/Downloads/vídeo.mp4

    DESTINO(PEN DRIVE):/media/user/9998-BDC4/vídeo.mp4

    TEMPO DE TRANSFERÊNCIA: 09:16:79

    TESTE: 2
    TECNICA:

    vm.dirty_background_bytes = 4194304
    vm.dirty_bytes = 4194304

    ARQUIVOS:

    TIPO : VÍDEO
    FORMATO: MP4
    TAMANHO: 1.3 GB

    ORIGEM:/home/user/Downloads/vídeo.mp4

    DESTINO(PEN DRIVE):/media/user/9998-BDC4/vídeo.mp4

    TEMPO DE TRANSFERÊNCIA: 6:08:03
    GANHO APROXIMADO DE : 03:13

    INTEGRIDADE: OK

    TESTE: 3
    TECNICA:

    vm.dirty_background_ratio=20
    vm.dirty_ratio=50

    ARQUIVOS:

    TIPO : VÍDEO
    FORMATO: MP4
    TAMANHO: 1.3 GB

    ORIGEM:/home/user/Downloads/vídeo.mp4

    DESTINO(PEN DRIVE):/media/user/9998-BDC4/vídeo.mp4

    TEMPO DE TRANSFERÊNCIA : 13:12:01
    PERDA DE APROXIMADAMENTE: 4:00

    INTEGRIDADE: ok

    Responder
  3. Hoje percebi que a essa técnica causa lentidão no chrome. E os vídeos no youtube( não sei dizer em outros sites ou qualquer coisa do tipo) quando executado no firefox trava também.

    Responder
  4. Ola, bom dia a todos.
    Já usei Linux também, debian, ubuntu, mint, apricity, uso o w10 atualmente, sem entrar nos méritos de um ou de outro s.o, no Windows ocorre a mesma merda, tem macetes que não servem de nada para aumento de velocidades de transferência, não passe de no máximo 3 a 7 Mbps, e olha que o fabricante dos pen diziam antes da introdução dos ssds que a velocidades de transferência poderiam chegar ate x Mbps, coisa que eu particularmente nunca vi, se alguém já chegou neste limite, por favor compartilhe conosco.
    Obrigado a todos

    Responder
  5. Acrescentei as duas linhas da primeira opção. Gostei do resultado. Era chato ver aquela barra mentirosa marcando o fim da transferência e depois ficar esperando sem saber quando ia terminar. Valeu e obrigado pela dica.

    Responder

Deixe um comentário