Paralelní pracovní procesy
Greph rozděluje textové skenování a skenování AST mezi pracovní procesy, pokud je práce dost rozsáhlá, aby vyvážila režii. Fond je založen na pcntl_fork() a při nedostupnosti ext-pcntl (Windows, některá prostředí PaaS, omezený hosting) přechází na zpracování v rámci procesu.
Zapnutí paralelního skenování
Nastavte -j N v CLI nebo jobs: N v příslušném objektu možností:
./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),
);
Kdy se aktivuje paralelní zpracování
Greph neparalelizuje bezpodmínečně. Spouštění N procesů a předávání jejich výsledků přes roury přináší režii, která u malých seznamů souborů převýší náklady samotného vyhledávání. Fasáda proto vypočítá práh podle počtu úloh, režimu vyhledávání a tvaru vzoru. Do fondu pracovních procesů se předávají pouze seznamy souborů překračující tento práh.
Aktuální heuristiky (v Greph\Greph::shouldUseTextWorkers a souvisejících částech):
- Běhy s jedinou úlohou (
-j 1) se vždy zpracovávají v rámci procesu. - Výchozí textové skenování vyžaduje přibližně
jobs * 2_000souborů, než se fond aktivuje. - Režimy počítání, souborů se shodami a souborů bez shod snižují práh přibližně na
jobs * 750, protože zpracování jednotlivých souborů je levnější. - U krátkých vzorů pevného řetězce připomínajících identifikátory se práh zvyšuje přibližně na
jobs * 4_000, protože rychlá cesta pro doslovné řetězce je už tak velmi levná a spouštění dalších procesů se málokdy vyplatí. - Vyhledávání a přepis AST používají práh
jobs * 750.
Jde o heuristické hodnoty, nikoli záruky. Jsou vyladěné podle výkonnostního korpusu WordPress a mohou se změnit.
Jak fond funguje
Greph\Parallel\WorkSplitter rozdělí seznam souborů do N částí. Greph\Parallel\WorkerPool spustí pro každou část jeden pracovní proces; každý pracovní proces provede stejnou funkci nad svou částí a Greph\Parallel\ResultCollector přečte serializované výsledky přes dvojici socketů Unix pro každý proces. Nadřazený proces vyčká na všechny pracovní procesy a poté sloučí a znovu seřadí výsledky, aby jejich pořadí zůstalo stabilní bez ohledu na rozdělení práce.
V textovém režimu fond pracovních procesů používá vlastní přenosový kodek (Greph\Text\TextResultCodec), aby udržel serializovaný obsah malý. Režim AST používá standardní serialize() knihovny PHP.
Když pcntl není k dispozici
Pokud pcntl_fork nelze volat (Windows, sestavení PHP se zvýšeným zabezpečením), fond transparentně přejde ke zpracování každé části v rámci procesu. Výsledek je stejný jako u -j 1. Greph nevyvolá chybu; pouze běží v jednom vlákně.
To lze za běhu zjistit kontrolou function_exists('pcntl_fork').
Doporučení pro ladění
- Začněte s nastavením
-jna polovinu počtu fyzických jader a zvyšujte ho, dokud nepřestanete pozorovat zlepšení. - U vyhledávání pouze doslovných pevných řetězců v malých repozitářích je zpracování v jediném procesu obvykle rychlejší než jakákoli paralelní konfigurace.
- Žádný publikovaný výkonnostní test neměří paralelní vyhledávání ani přepis AST. Než zvolíte počet úloh, proveďte měření na vlastním stromu.
- Řádky „Režim skenování: paralelní text“ v README (
1,2a4pracovních procesů nad korpusem WordPress) fond neměří: vyhledávají krátký doslovný řetězecfunction, jehož práhjobs * 4_000souborů převyšuje velikost korpusu, takže každý řádek běží v rámci jediného procesu (#8).
Omezení
- Aktuální fond nepodporuje kradení práce. Pokud je jedna část výrazně náročnější než ostatní, fond čeká na nejpomalejší pracovní proces.
- Výsledky pracovních procesů se ukládají do vyrovnávací paměti, dokud všechny neskončí. Paralelní režim nepodporuje průběžný výstup dlouhotrvajícího skenování (způsob, jakým
rg --jsonstreamuje události). - Nadřazený proces po sloučení výsledky znovu seřadí, takže fond pracovních procesů nesnižuje špičkovou spotřebu paměti oproti skenování v jediném procesu.
Tato omezení jsou přijatelná pro úlohy, na které se Greph zaměřuje (interaktivní vyhledávání v kódu, smyčky agentů, úlohy CI nad snímky). Pokud profilování odhalí úzké místo při práci s reálnými korpusy, omezení znovu posoudíme.