Paralelné procesy
Greph rozdeľuje textové skenovanie a skenovanie AST medzi skupinu procesov, keď je objem práce dostatočne veľký, aby vyvážil réžiu. Skupina je založená na pcntl_fork() a ak ext-pcntl nie je dostupné, použije vykonávanie v rámci procesu (Windows, niektoré prostredia PaaS, obmedzené hostingové prostredia).
Povolenie paralelného skenovania
Nastavte -j N na CLI alebo jobs: N v príslušnom objekte 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),
);
Kedy sa spustí paralelné spracovanie
Greph nespúšťa paralelné spracovanie bezpodmienečne. Vytváranie N procesov a prenos ich výsledkov cez rúry prináša réžiu, ktorá pri malom počte súborov prevýši samotné vyhľadávanie. Rozhranie preto vypočíta prahovú hodnotu podľa počtu úloh, režimu vyhľadávania a tvaru vzoru. Do skupiny procesov sa odovzdajú iba zoznamy súborov nad touto hranicou.
Aktuálne heuristiky (v Greph\Greph::shouldUseTextWorkers a súvisiacom kóde):
- Spustenia s jednou úlohou (
-j 1) sa vždy vykonávajú v rámci procesu. - Predvolené textové skenovanie vyžaduje približne
jobs * 2_000súborov, aby sa aktivovala skupina procesov. - Režimy počet, súbory so zhodami a súbory bez zhôd znižujú prah na približne
jobs * 750, pretože práca na jeden súbor je menšia. - Krátke vzory pevných reťazcov v tvare identifikátora zvyšujú prah na približne
jobs * 4_000, pretože rýchla cesta pre doslovné reťazce je už taká lacná, že vytváranie procesov sa zvyčajne nevyplatí. - Vyhľadávanie a prepisovanie AST používajú prah
jobs * 750.
Tieto čísla sú heuristiky, nie záruky. Sú vyladené podľa testovacieho korpusu WordPress a môžu sa zmeniť.
Ako funguje skupina procesov
Greph\Parallel\WorkSplitter rozdelí zoznam súborov na N častí. Greph\Parallel\WorkerPool vytvorí pre každú časť samostatný proces, ktorý spustí rovnakú uzávierku nad svojím úsekom, a Greph\Parallel\ResultCollector načíta serializované výsledky cez samostatnú dvojicu Unix socketov pre každý proces. Nadriadený proces počká na všetky procesy a potom zlúči a znova zoradí výsledky, aby poradie výstupu zostalo stabilné bez ohľadu na rozdelenie práce.
V textovom režime skupina procesov používa vlastný kodek prenosu (Greph\Text\TextResultCodec), aby zmenšila veľkosť serializovaných údajov. Režim AST používa štandardný serialize() od PHP.
Keď pcntl nie je dostupné
Ak pcntl_fork nemožno zavolať (Windows, zostavenia PHP so zvýšeným zabezpečením), skupina bez upozornenia prejde na vykonávanie každej časti v rámci procesu. Výsledok je rovnaký ako pri -j 1. Greph nevyvolá chybu; jednoducho sa spustí v jednom vlákne.
Túto dostupnosť môžete zistiť za behu kontrolou function_exists('pcntl_fork').
Odporúčania na ladenie
- Začnite s hodnotou
-jnastavenou na polovicu počtu fyzických jadier a zvyšujte ju, kým sa výkon neprestane zlepšovať. - Pri vyhľadávaní iba doslovných pevných reťazcov v malých repozitároch býva jeden proces rýchlejší než akákoľvek paralelná konfigurácia.
- Žiadny publikovaný výkonnostný test nemeria paralelné vyhľadávanie ani prepisovanie AST. Pred výberom počtu úloh si zmerajte výkon na vlastnom strome.
- Riadky „Režim skenovania: paralelný text“ v README (
1,2a4procesov na korpuse WordPress) nemerajú skupinu procesov: vyhľadávajú krátky doslovný reťazecfunction, ktorého prahjobs * 4_000súborov je vyšší než veľkosť korpusu, takže všetky riadky sa vykonávajú v rámci jedného procesu (#8).
Obmedzenia
- Aktuálny fond nepodporuje preberanie práce. Ak je jeden blok výrazne náročnejší než ostatné, fond čaká na najpomalšieho pracovníka.
- Výsledky pracovníkov sa ukladajú do vyrovnávacej pamäte, kým všetci nedokončia. Streamovanie výstupu z dlho bežiaceho skenovania (ako
rg --jsonstreamuje udalosti) nie je v paralelnom režime podporované. - Rodičovský proces po zlúčení výsledky znova zoradí, takže fond pracovníkov neznižuje špičkové využitie pamäte v porovnaní so skenovaním v jednom procese.
Tieto obmedzenia sú prijateľné pre pracovné zaťaženia, na ktoré sa Greph zameriava (interaktívne vyhľadávanie v kóde, cykly agentov, úlohy CI nad snímkami). Znovu sa posúdia, ak profilovanie ukáže, že predstavujú úzke miesto pri práci so skutočnými korpusmi.