Preskočiť na obsah

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í:

Shell
./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
PHP
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_000 sú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 -j nastavenou 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, 2 a 4 procesov na korpuse WordPress) nemerajú skupinu procesov: vyhľadávajú krátky doslovný reťazec function, ktorého prah jobs * 4_000 sú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 --json streamuje 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.