Que fait grep lorsqu'il n'exécute pas le CPU?

19

Lors de la recherche de correspondances avec grep, je remarque souvent que la recherche suivante prend beaucoup moins de temps que la première, par exemple 25 s contre 2 s. Évidemment, ce n'est pas en réutilisant les structures de données de sa dernière exécution - celles-ci auraient dû être désallouées. Exécuter une timecommande surgrep , j'ai remarqué un phénomène intéressant:

real    24m36.561s
user    1m20.080s
sys     0m7.230s

Où va le reste du temps? Y a-t-il quelque chose que je puisse faire pour le faire fonctionner à chaque fois rapidement? (par exemple, demander à un autre processus de lire les fichiers avant de les greprechercher.)

Alex
la source

Réponses:

34

Il est assez souvent lié au cache de pages .

La première fois, les données doivent être lues (physiquement) à partir du disque.

La deuxième fois (pour les fichiers pas trop gros), il est probable qu'il se trouve dans le cache de pages.

Donc, vous pouvez d'abord lancer une commande comme cat (1) pour amener le fichier (pas trop gros) dans le cache de page (c'est-à-dire dans la RAM), puis un deuxième grep (1) (ou tout programme lisant le fichier) s'exécutera généralement plus rapidement .

(cependant, les données doivent encore être lues à partir du disque à un moment donné)

Voir aussi (parfois utile dans vos programmes d'application, mais pratiquement rarement) readahead (2) & posix_fadvise (2) et peut-être madvise (2) & sync (2) & fsync (2) etc ....

Lisez aussi LinuxAteMyRAM .

BTW, c'est pourquoi il est recommandé, lors de l'analyse comparative d'un programme, de l'exécuter plusieurs fois. Aussi, c'est pourquoi il pourrait être utile d'acheter plus de RAM (même si vous n'exécutez pas de programmes utilisant tout cela pour leurs données).

Si vous voulez comprendre plus, lisez un livre comme par exemple les systèmes d'exploitation: trois pièces faciles

Basile Starynkevitch
la source
12
Ainsi, la TL;DRréponse est "[bloc en attente] d'E / S".
mgarciaisaia
10
@PaulDraper Pas vraiment :) cat+ grepva encore prendre plus de temps que grepseul.
chepner
3
@chepner Sauf si vous pouvez effectuer un multithread et l'utiliser catcomme une prélecture bon marché pendant que vous faites autre chose, en préparation pour l' grepintérêt.
hBy2Py
2
@MarkKCowan: Jolis chats!    :-) ⁠
G-Man dit 'Reinstate Monica' le
3
@ G-Man: Vous pouvez également remplacer deux des cats avec tacpour le même effet et une plus grande utilisation de la RAM: D Ou tous les chats avec tac
Mark K Cowan
-1

Dans un environnement de stockage en réseau, il peut également y avoir des retards relativement importants lorsque vous accédez pour la première fois à un fichier qui réside sur un "filer" distinct du serveur. Une fois que ce fichier a été accédé sur le serveur, il sera mis en cache localement et l'accès ultérieur aux données sera beaucoup plus rapide.

Voici une expérience calculant simplement une somme de contrôle des données de fichier - pas grep. La première invocation est lente et les suivantes sont rapides.

> du -Dh file_348m
348M    file_348m

> /usr/bin/time md5sum file_348m
738709b181b52ddfcef3413997f91462  file_348m
0.60user 0.15system 0:03.02elapsed 25%CPU (0avgtext+0avgdata 1524maxresident)k
708144inputs+0outputs (0major+80minor)pagefaults 0swaps

> /usr/bin/time md5sum file_348m
738709b181b52ddfcef3413997f91462  file_348m
0.67user 0.06system 0:00.73elapsed 99%CPU (0avgtext+0avgdata 1524maxresident)k
0inputs+0outputs (0major+80minor)pagefaults 0swaps

> /usr/bin/time md5sum file_348m
738709b181b52ddfcef3413997f91462  file_348m
0.65user 0.07system 0:00.73elapsed 99%CPU (0avgtext+0avgdata 1524maxresident)k
0inputs+0outputs (0major+80minor)pagefaults 0swaps

> /usr/bin/time md5sum file_348m
738709b181b52ddfcef3413997f91462  file_348m
0.66user 0.06system 0:00.73elapsed 99%CPU (0avgtext+0avgdata 1524maxresident)k
0inputs+0outputs (0major+80minor)pagefaults 0swaps
Winston Smith
la source
J'apprécierais les commentaires pour downvote (s), car je ne sais pas comment les interpréter. Je crois que ma description de réponse est correcte. Peut-être que l'exemple de commande n'est pas clair? Ou vous n'aimez pas que je n'ai pas évalué la commande grep? (J'ai intentionnellement utilisé une commande plus simple, md5sum, pour essayer d'illustrer mon propos.)
Winston Smith
1
Je pense que la raison en est que votre message n'a pas ajouté de nouvelles informations pertinentes à ce que je demandais. Je savais déjà qu'il y avait un retard, et la première réponse a déjà expliqué pourquoi cela se produisait. Mais oui, je reçois aussi des votes sans explication. Même sur des questions avec de bonnes réponses.
Alex
Merci @Alex d'avoir suggéré une raison. J'essayais de faire la distinction entre le temps de surcharge pour déplacer les données du stockage local vers la mémoire, décrit dans la première réponse, et le temps de surcharge pour déplacer les données du stockage réseau vers le serveur local. Je penserai si je pouvais décrire cela plus clairement ou fournir de meilleurs exemples de commandes.
Winston Smith
Je suppose qu'après avoir lu votre article, je pense que c'est toujours la surcharge de déplacer des données de partout où elles sont stockées vers la mémoire. Qu'il s'agisse du stockage réseau ou du stockage local, peu importe - Unix considère toujours qu'il passe d'un répertoire à la mémoire. ps-- on dirait que mon explication est correcte-- mon commentaire avec la raison a obtenu un vote positif.
Alex
Je vois, j'ajoutais une distinction qui n'est pas importante pour ce que vous cherchiez. D'ACCORD. Au fait, j'ai voté contre votre commentaire, donc cela ne résout pas la question de la raison du vote. :-)
Winston Smith