GNU/Linux >> Tutoriels Linux >  >> Linux

Comment les pipelines limitent-ils l'utilisation de la mémoire ?

Brian Kernighan explique dans cette vidéo l'attrait initial des Bell Labs pour les petits langages/programmes basés sur des limitations de mémoire

Une grosse machine serait de 64 k-octets - K, pas M ou G - et donc cela signifiait qu'un programme individuel ne pouvait pas être très gros, et il y avait donc une tendance naturelle à écrire de petits programmes, puis le mécanisme de pipe, essentiellement entrée la redirection de sortie, permettait de lier un programme à un autre.

Mais je ne comprends pas comment cela pourrait limiter l'utilisation de la mémoire compte tenu du fait que les données doivent être stockées dans la RAM pour être transmises entre les programmes.

De Wikipédia :

Dans la plupart des systèmes de type Unix, tous les processus d'un pipeline sont démarrés en même temps [c'est moi qui souligne] , avec leurs flux correctement connectés et gérés par le planificateur avec tous les autres processus exécutés sur la machine. Un aspect important de ceci, qui distingue les canaux Unix des autres implémentations de canaux, est le concept de mise en mémoire tampon :par exemple, un programme émetteur peut produire 5000 octets par seconde, et un programme récepteur peut ne pouvoir accepter que 100 octets par seconde, mais pas les données sont perdues. Au lieu de cela, la sortie du programme d'envoi est conservée dans la mémoire tampon. Lorsque le programme récepteur est prêt à lire les données, le programme suivant du pipeline lit à partir du tampon. Sous Linux, la taille du tampon est de 65 536 octets (64 Ko). Un filtre tiers open source appelé bfr est disponible pour fournir des tampons plus grands si nécessaire.

Cela me déroute encore plus, car cela va complètement à l'encontre de l'objectif des petits programmes (bien qu'ils soient modulaires jusqu'à une certaine échelle).

La seule chose que je peux considérer comme une solution à ma première question (les limitations de mémoire étant problématiques en fonction de la taille des données) serait que de grands ensembles de données n'étaient tout simplement pas calculés à l'époque et que le véritable problème que les pipelines étaient censés résoudre était le quantité de mémoire requise par les programmes eux-mêmes. Mais étant donné le texte en gras dans la citation de Wikipédia, même cela me déroute :car un programme n'est pas implémenté à la fois.

Tout cela aurait beaucoup de sens si des fichiers temporaires étaient utilisés, mais je crois comprendre que les canaux n'écrivent pas sur le disque (à moins que l'échange ne soit utilisé).

Exemple :

sed 'simplesubstitution' file | sort | uniq > file2

Il est clair pour moi que sed est en train de lire le fichier et de le recracher ligne par ligne. Mais sort , comme l'indique BK dans la vidéo liée, est un point, donc toutes les données doivent être lues en mémoire (ou le font-elles ?), puis elles sont transmises à uniq , qui (à mon avis) serait un programme d'une ligne à la fois. Mais entre le premier et le deuxième tuyau, toutes les données doivent être en mémoire, non ?

Connexe :Ubuntu – Exécuter une commande lorsqu'un CD/DVD/BD est inséré ?

Réponse acceptée :

Les données n'ont pas besoin d'être stockées dans la RAM. Les tuyaux bloquent leurs auteurs si les lecteurs ne sont pas là ou ne peuvent pas suivre; sous Linux (et la plupart des autres implémentations, j'imagine), il y a une certaine mise en mémoire tampon mais ce n'est pas obligatoire. Comme mentionné par mtraceur et JdeBP (voir la réponse de ce dernier), les premières versions d'Unix mettaient en mémoire tampon des canaux vers le disque, et c'est ainsi qu'ils contribuaient à limiter l'utilisation de la mémoire :un pipeline de traitement pouvait être divisé en petits programmes, chacun d'entre eux traitant certaines données. , dans les limites des tampons du disque. Les petits programmes consomment moins de mémoire, et l'utilisation de tubes signifiait que le traitement pouvait être sérialisé :le premier programme s'exécuterait, remplirait son tampon de sortie, serait suspendu, puis le deuxième programme serait programmé, traiterait le tampon, etc. Les systèmes modernes sont des ordres d'une ampleur plus grande que les premiers systèmes Unix, et peut exécuter de nombreux tuyaux en parallèle; mais pour d'énormes quantités de données, vous verriez toujours un effet similaire (et des variantes de ce type de technique sont utilisées pour le traitement des "big data").

Dans votre exemple,

sed 'simplesubstitution' file | sort | uniq > file2

sed lit les données du file si nécessaire, puis l'écrit aussi longtemps que sort est prêt à le lire ; si sort n'est pas prêt, l'écriture se bloque. Les données finissent bien par vivre en mémoire, mais c'est spécifique à sort , et sort est prêt à faire face à tous les problèmes (il utilisera des fichiers temporaires si la quantité de données à trier est trop importante).

Vous pouvez voir le comportement de blocage en exécutant

strace seq 1000000 -1 1 | (sleep 120; sort -n)

Cela produit une bonne quantité de données et les dirige vers un processus qui n'est pas prêt à lire rien pendant les deux premières minutes. Vous verrez un certain nombre de write les opérations passent, mais très rapidement seq s'arrêtera et attendra que les deux minutes se soient écoulées, bloquées par le noyau (la commande write l'appel système attend).


Linux
  1. Utilisation de la mémoire Linux

  2. Comment augmenter la limite de mémoire PHP

  3. Linux - Limiter l'utilisation de la mémoire pour un seul processus Linux ?

  4. Comment limiter l'utilisation de la mémoire des applications ?

  5. Comment l'utilisation de la mémoire est-elle signalée sous Linux ?

Comment vérifier l'utilisation de la mémoire sous Linux

Comment vérifier l'utilisation de la mémoire dans Debian 10

Comment trouver les principaux processus en cours d'exécution par utilisation de la mémoire

Comment interpréter l'utilisation de la mémoire Top/htop ?

Comment trier la commande supérieure en fonction de l'utilisation de la mémoire

Comment profiler l'utilisation de la mémoire ?