Compactação de arquivos na era dos vários núcleos

Tenho brincado um pouco com a compactação de arquivos novamente, pois geramos alguns arquivos de backup muito grandes diariamente no Stack Overflow.

Estamos usando a versão mais recente de 64 bits do 7zip (4.64) em nosso servidor de banco de dados. Estou não sou um grande fã de mais do que dual core no desktop, mas para servidores é fácil. Quanto mais núcleos de CPU, melhor! Este servidor tem duas CPUs quad-core, um total de 8 núcleos, e fiquei um pouco desanimado ao descobrir que nem o RAR nem o 7zip pareciam fazer muito uso de mais de 2.

Ainda assim, mesmo que use apenas 2 núcleos para compactar, o algoritmo do 7zip é incrivelmente eficaz e tem evoluiu nos últimos anos para ser respeitavelmente rápido. Eu costumava recomendar RAR em vez de Zipmas, dada a maior eficiência do 7zip e o fato de que ele é gratuito e o RAR não, ele é a escolha lógica agora.

Aqui estão alguns testes rápidos que realizei compactação de um único arquivo de backup de banco de dados de 4,76 GB. Isso foi executado em um servidor com duas CPUs quad-core Xeon E5420 de 2,5 GHz.

7zip mais rápido 5 min 14 MB/s 973 MB
7zip rápido 7 min 11 MB/s 926 MB
7zip normal 34 min 2,5 MB/s 752 MB
7zip máximo 41 min 2.0 MB/s 714 MB
7zip ultra 48 min 1,7 MB/s 698 MB

Para os senhores que agora estão se perguntando, se o 7zip se sai tão bem no maximum e no ultra, imagine como se sairia no ultra-plus, não conte com isso. Há um motivo pelo qual a maioria dos programas de compactação tem como padrão determinadas configurações como “normais”. Acima dessas configurações, os resultados tendem a cair em um precipício; além desse ponto ideal, o senhor tende a obter aumentos absurdamente minúsculos na taxa de compactação em troca de aumentos de ordem de magnitude enormes no tempo de compactação.

Agora veja o que acontece quando eu mudo o 7zip para usar o algoritmo de compactação bzip2:

7zip com bzip2 selecionado

Vamos compactar esse mesmo arquivo de 4,76 GB, na mesma máquina:

bzip2 mais rápido 2 min 36 MB/s 1092 MB
bzip2 rápido 2,5 min 29 MB/s 1011 MB
bzip2 normal 3,5 min 22 MB/s 989 MB
bzip2 máximo 7 min 12 MB/s 987 MB
bzip2 ultra 21 min 4 MB/s 986 MB

Por que o bzip2 é capaz de trabalhar tanto mais rápido do que o 7zip? Simples:

Uso da CPU do algoritmo do 7zip

7zip multithreaded cpu usage

Uso da CPU do algoritmo bzip2

bzip2-multithreaded-cpu-usage.png

O Bzip2 usa mais de 2 núcleos de CPU para paralelizar seu trabalho. Não sei ao certo qual é o limite, mas o seletor suspenso na GUI do 7zip permite até 16 quando o algoritmo bzip2 é escolhido. Usei 8 para os testes acima, pois esse é o número de núcleos de CPU que temos no servidor.

Infelizmente, o aumento de velocidade do bzip2 é meio que discutível em altos níveis de compactação. A diferença entre a compressão normal, máxima e ultra é de apenas 0,06%. Ela se adapta muito bem ao tempo, mas quase nada ao espaço. É uma pena, pois é exatamente aí que o senhor gostaria de gastar o aumento de velocidade da paralelização. Conseguir um percentual de melhoria no tamanho ainda pode fazer sentido, dependendo das circunstâncias:

tempo total = tempo de compressão + n * (tamanho do arquivo comprimido / velocidade da rede + tempo de descompressão)

Por exemplo, se o senhor comprimir um arquivo para enviá-lo uma vez pela rede, n é igual a um e o tempo de compactação terá uma grande influência. Se o senhor quiser publicar um arquivo para ser baixado várias vezes, n é grande, portanto, os longos tempos de compressão terão menos peso na decisão final. Por fim, as redes lentas se sairão melhor com um algoritmo lento, mas eficiente, enquanto que para as redes rápidas é necessário um algoritmo veloz, possivelmente menos eficiente.

Por outro lado, a capacidade de comprimir um arquivo de origem de 5 GB para um quinto de seu tamanho em dois minutos é bastante impressionante. Ainda assim, não posso deixar de imaginar o quão rápido seria o algoritmo do 7zip se ele fosse reescrito e paralelizado para aproveitar mais de 2 núcleos de CPU.