Processus parallèles
Greph répartit les analyses textuelles et AST entre plusieurs processus de travail lorsque le volume justifie le coût supplémentaire. Le pool s’appuie sur pcntl_fork() et bascule vers une exécution dans le processus courant lorsque ext-pcntl n’est pas disponible (Windows, certains environnements PaaS, hébergement restreint).
Activer les analyses parallèles
Définissez -j N sur CLI ou jobs: N dans l’objet d’options concerné :
./vendor/bin/greph -F -j 8 "function" src
./vendor/bin/greph -p '$obj->$method($$$ARGS)' -j 4 src
./vendor/bin/rg --threads 8 -F "function" src
./vendor/bin/sg run --threads 8 --pattern '$obj->$method($$$ARGS)' src
use Greph\Greph;
use Greph\Text\TextSearchOptions;
Greph::searchText(
'function',
'src',
new TextSearchOptions(fixedString: true, jobs: 8),
);
Quand le traitement parallèle démarre
Greph ne parallélise pas systématiquement. Le lancement de N processus et l’échange de leurs résultats par des tubes entraînent un surcoût qui, pour de petites listes de fichiers, dépasse le coût de la recherche elle-même. La façade calcule plutôt un seuil en fonction du nombre de tâches, du mode de recherche et de la forme du motif. Seules les listes de fichiers qui dépassent ce seuil sont réparties dans le pool de processus.
Heuristiques actuelles (dans Greph\Greph::shouldUseTextWorkers et les outils associés) :
- Les exécutions à une seule tâche (
-j 1) s’effectuent toujours dans le processus courant. - Les analyses textuelles par défaut nécessitent environ
jobs * 2_000fichiers avant l’activation du pool. - Les modes de comptage, de fichiers avec correspondances et de fichiers sans correspondance abaissent le seuil à environ
jobs * 750, car le traitement par fichier est moins coûteux. - Les motifs à chaîne fixe courts ayant la forme d’un identifiant relèvent le seuil à environ
jobs * 4_000, car le chemin rapide littéral est déjà si peu coûteux que la création de processus est rarement rentable. - La recherche et la réécriture AST utilisent le seuil
jobs * 750.
Ces nombres sont des heuristiques, pas des garanties. Ils sont ajustés en fonction du corpus de test WordPress et peuvent être revus.
Fonctionnement du pool
Greph\Parallel\WorkSplitter répartit la liste de fichiers en N lots. Greph\Parallel\WorkerPool crée un processus de travail par lot. Chaque processus exécute la même fermeture sur sa portion, puis Greph\Parallel\ResultCollector récupère les résultats sérialisés par une paire de sockets Unix par processus. Le processus parent attend la fin de tous les processus, puis fusionne et retrie les résultats combinés afin que leur ordre reste stable, quelle que soit la répartition du travail.
En mode texte, le pool utilise un codec personnalisé sur le fil (Greph\Text\TextResultCodec) pour compacter les données sérialisées. Le mode AST utilise le serialize() standard de PHP.
Lorsque pcntl est indisponible
Si pcntl_fork ne peut pas être appelé (Windows, compilations PHP renforcées), le pool exécute chaque lot dans le processus courant. Le résultat est identique à celui de -j 1. Greph ne génère aucune erreur ; il s’exécute simplement sur un seul thread.
Vous pouvez le détecter à l’exécution en vérifiant function_exists('pcntl_fork').
Conseils de réglage
- Commencez par définir
-jà la moitié du nombre de cœurs physiques, puis augmentez la valeur jusqu’à ce que les gains cessent. - Pour les recherches à chaîne fixe littérale uniquement dans de petits dépôts, un seul processus est généralement plus rapide que toute configuration parallèle.
- Aucun test de performance publié ne mesure la recherche ou la réécriture AST en parallèle. Faites des mesures sur votre propre arborescence avant de choisir le nombre de tâches.
- Les lignes « Mode d’analyse : texte parallèle » du README (avec
1,2et4processus de travail dans le corpus WordPress) ne mesurent pas le pool : elles recherchent le littéral courtfunction, dont le seuil dejobs * 4_000fichiers dépasse la taille du corpus. Chaque ligne s’exécute donc dans le processus courant (#8).
Limites
- Le pool actuel ne prend pas en charge le vol de travail. Si un lot est beaucoup plus lourd que les autres, le pool attend le processus le plus lent.
- Les résultats sont mis en mémoire tampon jusqu’à la fin de tous les processus de travail. Le mode parallèle ne prend pas en charge la sortie en continu d’une analyse de longue durée, comme le flux d’événements de
rg --json. - Le processus parent retrie les résultats après leur fusion. Le pool n’abaisse donc pas le pic d’utilisation de la mémoire par rapport à une analyse dans un seul processus.
Ces limites conviennent aux charges de travail visées par Greph (recherche de code interactive, boucles d’agents, tâches d’intégration continue sur des instantanés). Elles seront réexaminées si le profilage révèle un goulot d’étranglement dans des corpus réels.