Siirry sisältöön

Rinnakkaiset työprosessit

Greph jakaa teksti- ja AST-skannaukset työprosessijonolle, kun työn määrä on riittävän suuri kattamaan lisäkustannukset. Jono perustuu pcntl_fork()-toimintoon ja siirtyy prosessin sisäiseen suoritukseen, kun ext-pcntl ei ole käytettävissä (Windows, eräät PaaS-ympäristöt ja rajoitetut palvelinympäristöt).

Rinnakkaisten skannausten käyttöönotto

Aseta -j N kohteessa CLI tai jobs: N asianmukaisessa asetuskohteessa:

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),
);

Milloin rinnakkaisuus käynnistyy

Greph ei suorita rinnakkaistamista ehdoitta. N prosessin käynnistäminen ja niiden tulosten välittäminen putkien kautta aiheuttavat lisäkustannuksia. Pienillä tiedostolistoilla nämä kustannukset ovat suurempia kuin itse haun. Siksi julkisivukerros laskee kynnysarvon tehtävien määrän, hakutilan ja hakumallin rakenteen perusteella. Vain kynnysarvon ylittävät tiedostolistat jaetaan työprosessijonolle.

Nykyiset heuristiikat (kohteessa Greph\Greph::shouldUseTextWorkers ja siihen liittyvissä tiedostoissa):

  • Yhden työn ajot (-j 1) suoritetaan aina prosessin sisällä.
  • Tavalliset tekstiskannaukset vaativat noin jobs * 2_000 tiedostoa ennen työprosessijonon käyttöönottoa.
  • Osumamäärän, osumia sisältävien tiedostojen ja ilman osumia olevien tiedostojen tilat laskevat kynnyksen noin jobs * 750 tiedostoon, sillä tiedostokohtainen työ on kevyempää.
  • Lyhyiden, tunnisteen muotoisten kiinteän merkkijonon hakumallien kynnys nousee noin jobs * 4_000 tiedostoon, sillä kirjaimellisten merkkijonojen nopea hakupolku on jo niin tehokas, ettei rinnakkaistamisesta yleensä ole hyötyä.
  • AST-haku ja AST:n uudelleenkirjoitus käyttävät kynnystä jobs * 750.

Nämä luvut ovat heuristisia arvioita, eivät lupauksia. Ne perustuvat aineistoon WordPress ja niitä voidaan muuttaa.

Jonon toiminta

Greph\Parallel\WorkSplitter jakaa tiedostolistan N osaan. Greph\Parallel\WorkerPool käynnistää kunkin osan käsittelyyn yhden työprosessin. Kukin prosessi suorittaa saman sulkeuman omalle osalleen, ja Greph\Parallel\ResultCollector lukee sarjoitetut tulokset takaisin kunkin työprosessin Unix-socketparin kautta. Pääprosessi odottaa kaikkien työprosessien valmistumista, yhdistää tulokset ja järjestää ne uudelleen, jotta tulosteiden järjestys pysyy samana työn jakotavasta riippumatta.

Tekstitilassa työprosessijono käyttää mukautettua siirtoformaattia (Greph\Text\TextResultCodec), joka pitää sarjoitetun tietosisällön pienenä. AST-tila käyttää kohteen PHP vakio-serialize()-muotoa.

Kun pcntl ei ole käytettävissä

Jos kohdetta pcntl_fork ei voi kutsua (Windows, kovennetut PHP-koontiversiot), jono siirtyy huomaamatta suorittamaan jokaisen osan prosessin sisällä. Tulos on sama kuin kohteessa -j 1. Greph ei aiheuta virhettä, vaan suorittaa työn yksisäikeisesti.

Voit havaita tämän ajonaikaisesti tarkistamalla kohteen function_exists('pcntl_fork').

Säätöohjeita

  • Aloita asettamalla -j puoleen fyysisten suoritinydintesi määrästä ja nosta arvoa, kunnes suorituskyky ei enää parane.
  • Pienissä tietovarastoissa pelkkään kirjaimellisen kiinteän merkkijonon hakuun yksi prosessi on yleensä nopeampi kuin mikään rinnakkainen kokoonpano.
  • Julkaistuissa suorituskykytesteissä ei mitata rinnakkaista AST-hakua tai uudelleenkirjoitusta. Mittaa suorituskyky omalla hakemistopuullasi ennen työprosessien määrän valitsemista.
  • Kohteen README rivit osiossa ”Scan Mode: Parallel Text” (1, 2 ja 4 työprosessia aineistolla WordPress) eivät mittaa työprosessijonoa: niissä haetaan lyhyttä kirjaimellista mallia function, jonka kynnysarvo jobs * 4_000 tiedostoa ylittää aineiston koon. Siksi jokainen rivi suoritetaan prosessin sisällä (#8).

Rajoitukset

  • Nykyinen jono ei tue töiden dynaamista uudelleenjakoa. Jos yksi osa on muita huomattavasti raskaampi, jono odottaa hitaimman työprosessin valmistumista.
  • Työprosessien tulokset tallennetaan puskuriin, kunnes kaikki prosessit ovat valmistuneet. Pitkään kestävän skannauksen tulosteiden virtauttamista (kuten rg --json virtauttaa tapahtumia) ei tueta rinnakkaistilassa.
  • Pääprosessi järjestää tulokset uudelleen yhdistämisen jälkeen, joten työprosessijono ei vähennä huippumuistin käyttöä yhden prosessin skannaukseen verrattuna.

Nämä rajoitukset sopivat työkuormiin, joihin Greph on tarkoitettu (vuorovaikutteinen koodihaku, agenttien toistuvat työvaiheet ja CI-ajot tilannevedoksille). Niitä tarkastellaan uudelleen, jos profilointi osoittaa niiden olevan pullonkaula todellisilla aineistoilla.