ordenar GNU - compactar programa-compactando apenas primeiro temporário

4

Estou classificando arquivos grandes (> 100Go) e, para reduzir o tempo gasto em gravações em disco, estou tentando usar o parâmetro --compress-program do tipo classificação do GNU. (Relacionado: Como classificar arquivos grandes? )

No entanto, parece em certos casos que somente o primeiro temporário é compactado. Eu gostaria de saber por que e o que eu poderia fazer para compactar todos os temporários.

Estou usando:

  • sort (GNU coreutils) 8.25
  • lzop 1.03 / LZO library 2.09

Etapas para reproduzir o problema:

Você precisará de algo como ~ 15Go de espaço livre, ~ 10Go de memória RAM, algum tempo

Primeiro, crie um arquivo 10Go com o seguinte código C:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    unsigned long n;
    unsigned char i;
    srand(42);
    for(n = 0; n < 1000000000; n++) {
        for(i = 0; i < 3; i++) {
            printf("%03d", rand() % 1000);
        }
        printf("\n");
    }
    fflush(stdout);
    return 0;
}

e executá-lo:

$ gcc -Wall -O3 -o generate generate.c
$ ./generate > test.input  # takes a few minutes
$ head -n 4 test.input
166740881
241012758
021940535
743874143

Em seguida, inicie o processo de classificação:

$ LC_ALL=C sort -T . -S 9G --compress-program=lzop test.input -o test.output

Após algum tempo, suspenda o processo e liste os temporários criados na mesma pasta (devido a -T . ):

$ ls -s sort*
890308 sortc1JZsR
890308 sorte7O878
378136 sortrK37RZ
$ file sort*
sortc1JZsR: ASCII text
sorte7O878: ASCII text
sortrK37RZ: lzop compressed data - version 1.030, LZO1X-1, os: Unix

Parece que apenas sortrK37RZ (o primeiro criado temporariamente) foi compactado.

[Edit] Executar esse mesmo comando sort com -S definido como 7G é bom (ou seja, todos os temporários são compactados), enquanto com 8G o problema está presente.

[Editar] lzop não é chamado para o outro temporário

Eu tentei e usei o script a seguir como um wrapper para lzop :

#!/bin/bash
set -e
echo "$$: start at $(date)" >> log
lzop $@
echo "$$: end at $(date)" >> log

Aqui está o conteúdo do arquivo log , quando vários temporários são gravados no disco:

11109: start at Sun Apr 10 22:56:51 CEST 2016
11109: end at Sun Apr 10 22:57:17 CEST 2016

Então, meu palpite é que o programa compress não é chamado.

    
por r0g 10.04.2016 / 16:46

1 resposta

5

Não reproduzido aqui?

$ shuf -i1-10000000 > t.in
$ sort -S50M -T. t.in --compress-program=lzop  # ^z
$ file sort* | tee >(wc -l) > >(grep -v lzop)
7
$ fg   # ^c
$ sort --version | head -n1
sort (GNU coreutils) 8.25
O que eu estou supondo que o problema é, é devido a falha de bifurcação () do processo de compactação devido ao grande tamanho de mem e, em seguida, caindo de volta para uma gravação padrão. I.E. sort (1) está usando fork () / exec () quando idealmente deveria estar usando posix_spawn () para bifurcar mais eficientemente o processo de compressão. Agora fork () é CoW, mas ainda há sobrecarga na preparação das estruturas contábeis associadas para um processo tão grande. Em futuras versões do sort (1), usaremos posix_spawn () para evitar essa sobrecarga (a glibc acabou de obter uma implementação utilizável do posix_spawn () a partir da versão 2.23).

Nesse meio tempo, sugiro usar um S muito menor. Talvez-S1G e abaixo.

    
por 10.04.2016 / 22:36