Tri - parallèle ne parallélise pas

10

J'essaie de rendre unique un ensemble de lignes extraites d'un fichier avec egrep avec sort -u, puis de les compter. Environ 10% des lignes (les 100 caractères de l'alphabet [ATCG]) sont dupliquées. Il y a deux fichiers, environ 3 concerts chacun, 50% ne sont pas pertinents, donc peut-être 300 millions de lignes.

LC_ALL=C  grep -E  <files> |  sort --parallel=24  -u | wc -m

Entre LC_ALL = C et en utilisant -x pour accélérer la grep, la partie la plus lente est de loin le tri. La lecture des pages de manuel m'a conduit à --parallel = n, mais l'expérimentation n'a montré aucune amélioration. Un peu de fouille avec top a montré que même avec --parallel = 24, le processus de tri ne s'exécute que sur un processeur à la fois.

J'ai 4 puces avec 6 cœurs et 2 threads / core, ce qui donne un total de 48 processeurs logiques. Voir lscpu car / proc / cpuinfo serait trop long.

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                48
On-line CPU(s) list:   0-47
Thread(s) per core:    2
Core(s) per socket:    6
Socket(s):             4
NUMA node(s):          8
Vendor ID:             AuthenticAMD
CPU family:            21
Model:                 1
Stepping:              2
CPU MHz:               1400.000
BogoMIPS:              5199.96

Qu'est-ce que je rate? Même si le processus est lié aux E / S, ne devrais-je pas voir le traitement parallèle de toute façon? Le processus de tri utilise 99% du processeur sur lequel il se trouve à tout moment, donc je devrais pouvoir voir la parallélisation si cela se produit. La mémoire n'est pas un problème, j'ai 256 Go pour jouer et rien n'est utilisé par autre chose.

Quelque chose que j'ai découvert en canalisant grep vers un fichier puis en lisant le fichier avec sort:

 LC_ALL=C  grep -E  <files>  > reads.txt ; sort reads.txt  -u | wc -m

default, file 1m 50s
--parallel=24, file 1m15s
--parallel=48, file 1m6s
--parallel=1, no file 10m53s
--parallel=2, no file 10m42s
--parallel=4 no file 10m56s

others still running

En faisant ces tests, il est assez clair que lorsque le tri d'entrée canalisé n'est pas du tout en parallèle. Lorsqu'il est autorisé à lire un fichier, le tri divise la charge comme indiqué.

Jeremy Kemball
la source
Qu'est sort- ce que sur quelle distribution? La norme sortne connaît pas cette option.
ott--
uname -adonne "3.13.0-46-generic # 79-Ubuntu SMP" et lsb_release -arevendique le nom de code 14.04.2 fidèle, et la version du genre qui fait partie des coreutils gnu, selon man sort.
Jeremy Kemball
Il me semble qu'il y a des parties ici qui doivent être relues: gnu.org/software/coreutils/manual/html_node/…
Hannu
Je ne suis pas sûr de comprendre ce que vous obtenez chez @Hannu, pourriez-vous être plus précis? sort --parallel = 2 ne parallélise pas non plus. Ni 4 ni 8. nproc redonne 48 comme il se doit.
Jeremy Kemball
1
Je dirais ... n'utilisez pas de coreutils pour cela. De manière amusante, nous avions une question très similaire et bien ... toutes les autres méthodes fonctionnent mieux superuser.com/a/485987/10165
Journeyman Geek

Réponses:

24

le tri ne crée pas de thread à moins que cela ne soit nécessaire, et pour les petits fichiers, c'est juste trop de surcharge. Désormais, le tri traite malheureusement un tuyau comme un petit fichier. Si vous souhaitez fournir suffisamment de données à 24 threads, vous devrez spécifier le tri pour utiliser un grand tampon interne (le tri le fait automatiquement lorsqu'il est présenté avec des fichiers volumineux). C'est quelque chose que nous devrions améliorer en amont (au moins dans la documentation). Vous voudrez donc quelque chose comme:

(export LC_ALL=C; grep -E  <files> | sort -S1G --parallel=24 -u | wc -m)

Notez que j'ai défini LC_ALL = C pour tous les processus, car ils bénéficieront tous de ces données).

BTW, vous pouvez surveiller les threads de tri avec quelque chose comme:

watch -n.1 ps -C sort -L -o pcpu
pixelbeat
la source