Kahvliühenduse arendamine Java™ SE standardvabastuses

Original: http://www.coopsoft.com/ar/ForkJoinArticle.html

Kahvel-Liitu igapäevaste, Mitme tuumaga Java™ rakenduste Jaoks

Töökoormuse katkestamine või jagamine mitmeks ülesandeks paralleelseks töötlemiseks ja tulemuste ühendamiseks on tehnika, mida kasutatakse arvukates teaduslikes ja arvukates kruntimisrakendustes. Paljud teised rakendused võiksid kasutada kahvliharude töötlemist, kuid teadusliku lähenemisviisi kasutamine ei pruugi olla nende huvides.

Käesolevas artiklis on esitatud „piinlik paralleelne” kahvliühendus, mis sobib hästi igapäevaste, mitmetuumaliste rakenduste jaoks nii Java™ SE, ME kui ka Android™ (3000 sõna)

Edward Harned

Vanem arendaja, Cooperative Software Systems, Inc.
Veebruar 2010 [uuendatud juuli, 2017]


Mis on haakeseadis?

Mõtle kahvlile teedel, kus iga tee üheskoos tagasi jõuab.

haakeseadis katkestab rakenduse paralleelseks töötlemiseks mitmeks osaks ja ühendab tulemused lõpus.

Joonis 1: Haakeseadis struktuur

Fork-Join Structure

Oletame, et meil on üks tuhat numbrit. Me peame tegema kõik need numbrid ja lisama kokku.

Loend 1: massiivi töötlemine


 for (int i = 0; i < 1000; i++) {
total += doProcedure(array[i]);
}

Kui protseduur lõpeb ühe sekundiga (seina-kellaaeg), kulub selle ülesande täitmiseks tuhande sekundi (üle 16½ minuti).

Haakeseadis võiks

  • eraldage (haarake) suure massiivi kümneks elemendiks, millest igaüks on
  • töötleb iga massiivi eraldi protsessoril ja
  • liituda tulemused, kui olete lõpetanud.

See võtab aega sada sekundit (veidi üle 1½ minuti), üks kümnendik algsest ajast. Mida rohkem CPU-d on saadaval, seda kiirem on tulemus.

Vaata ongi näha, Mida teaduslik Arvutustehnika hõlmab – samaaegselt töötleb humongous andmemahtu nii palju CPU-sid tsitaatides Saadaval. Vaata abstraktsioon sarnaneb tihedalt jaga ja Conqueri standardse teadusmudeliga.

Podijeliti-a-osvojiti je přírodní paradigma paralelnih algoritama. Nakon podjele probleem u dvije ili više manjih problema, način rješava gondli-problema u paralelno. Tipično, gondli-Problemi rješavaju rekurzivno i tako sljedeći podjela korak daje još više gondli-problema za rješavanje paralelno.

Joonis 2: Jaga ja valluta

Divide and Conquer

Probleemid haakeseadis’i Teadusliku Mudeli kasutamisel igapäevaseks kasutamiseks

Ülesannete Loomine Ei ole probleem; nad kohta ainult objektid. Probleem Suur hulk teemasid, mis töötlevad ülesandeid, tsitaatides vaja ülesanded vajavad:

Ühendused
Juurdepääs serveri teenuseid (DBMS, sõnumside ja paljud teised) nõuab ühendus serveri teenust. Üldiselt kaugteenistuste kasutada lõime hakkama ühendus ja mis nõuab mälu, konteksti lülitamine, sünkroniseerimine ja koordineerimine. Mida rohkem ühendust teenusega, seda rohkem ressursse teenuse vajab, ja vähem ühendusi saadaval muid ülesandeid JVM. See mõjutab iga kasutaja.

Lukud
Lukud on tapja suure jõudlusega. Surnud/elavad lukud, prioriteet inversioon, nälga, convoying ja üldkulusid (mis tõuseb hüppeliselt pikkusega nimekiri ootab ülesanded) on vaid mõned probleemid, kasutades lukud.

Semaforien
Mida rohkem teemasid, mis soovivad loa samaaegselt, seda rohkem teemasid, mis peab ootama loa olemasolust. See toob meid tagasi kõik probleemid kasutades lukud.

Cache sidususe
Kui mitu protsessorit juurdepääsu/uuenda sama muutuja sees vahemälu line (plokk kopeeritud andmetega põhimälu sisaldavad paljudes valdkondades), mälu ühik võib kehtetuks vahemälu joon. See mitte ainult aeglustab taotluse, see võib mõjutada muu rakendus samuti.

Ulatuslikud mälu
Mida rohkem objekte või suurem objekte, seda rohkem mälu. Aktiivsemad teemasid käitlemise ülesandeid, siis rohkem mälu kasutamine. Loomulikult järeldub, et suur mälu ülesandeid vaja drosseli.

Vajadus mängida kena
Oled taotlus ei pruugi olla ainus rakendus töötab arvutis. Kui üks taotlus Kodu- ressursse, igaüks tunneb valu. Mängib kena teistega läheb tagasi see, mida me kõik õppinud lapsepõlves. Sama kehtib siis, kui arendada tarkvara, mis ei tööta rakendusena.

Mitmekordse arendamise teema on hoida väiteid, samade ressursside eest konkureerivaid ülesandeid minimaalselt.

Kui dünaamilise lagunemine paradigma jaga ja vallutada sobib teie vajadustele, siis loe see artikkel umbes suure jõudlusega  DSE versioon Tymeac. Vastasel funktsionaalsete harunemiseks Framework ehk paremini teie vajadustele.

Funktsionaalne harunemiseks raamistik

Java™ SE/ME mitme tuumaga rakendused ning Android™ -rakendused, mis ei kasuta Jaga ja valluta-mudelit, ei töötle suuri arvulisi massiive või neil ei ole arvutust vajavat intensiivset struktuuri, mis vajab rakenduste paralleelseks kasutamiseks funktsionaalset kahvli raamistikku . Täpsemalt peavad nad tööd tegema oma funktsionaalseteks komponentideks, mitte massiivi identseks alamülesanneteks.

Joonis 3: Funktsionaalne kahvli raam

Functional Forking Framework

Funktsionaalsel kahvliharul on kaks olulist atribuuti. See peab:

  • Piirang.
  • Ole lihtne kasutada või piinlikult paralleelne.

Piirang

Hoides mitmeid aktiivseid, konkureerivad niidid absoluutse miinimumini on ülimalt tähtis. Lihtsaim viis piirata lõime väide on kasutada künniseid iga niit bassein teenindamiseks järjekorda ülesandeid. Vaata seda artiklit  High Performance prioriteet järjekorrad Java SE  näidet, kuidas kasutades Oodake nimekirjad võivad säilitada väliskeermestamiseks ressursse.

Ressursside taaskasutust mitte omandada uusi koopiaid ressursse on võitja kõigi ümber. Me peame arvestama mitte ainult ülesanne koodi, kuid ressursi haldamise koodi samuti.

Võtame näiteks ülesanne vajavad juurdepääsu andmebaasi, mis nõuab [java.sql.] Avalduse. Kasutades järjekorda taotluste ülesanne koodi saab jagada sama avaldus paljude juurdepääsude pigem siis omandada uusi avaldus iga-ühendus. Jagamine avaldus on suur kokkuhoid õhuliinide ja piirid väide jooksul haldamise koodi.

Mis on piinlikult paralleelne?

Piinlikult paralleelsed algoritmid on need, mis suudavad samaaegselt lahendada palju sarnaseid, kuid iseseisvaid ülesandeid, vähese vajadusega koordineerida ülesandeid. Sellistel probleemidel on nii lihtne paralleelsus, et on peaaegu “piinlik” rääkida sellest, kui lihtne on paljude töötlejate tõhus toimimine.

Piinlikult paralleelne lahendus võib kergesti haarata mitmetesse täiesti sõltumatutesse osadesse, millest igaüks täidab eraldi protsessoril.

Joonis 4: Piinlik paralleel

Embarrassingly Parallel

Näiteks:
Ettevõte võib vajada automatiseeritud hinnapakkumise süsteemi. Tsitaadi väljaarendamiseks vajab süsteem elemendi baashinda (hinna andmebaas), kliendi soodustust kaupade ja laevanduse jaoks (kliendiandmebaas) ja põhilisi saatekulusid (saatja andmebaas).

Traditsiooniliselt pääseb programm iga andmebaasi seeriasse, oodates, kuni iga juurdepääs lõpetatakse, enne kui lähete järgmisele juurdepääsule.

Paralleelses süsteemis ootab programm Forks() kolme järjekorda, millest igaüks teenindab lõime pool, ootab, kuni viimane juurdepääs lõpeb ja Joins() tulemustega kokku.

Joonis 5: Hinnapakkumine

Ülaltoodud hinnapakkumine on sünkroonse taotluse näide, kus helistaja ootab valmimist. Ainult väike samm edasi asünkroonse või iseseisva taotluse toetamiseks, kui helistaja ei oota lõpetamist.

On palju, palju olukordi, kus tööde komponentide ühendamine on soovitav:

  • Võta mängu rakendus, kus me võime sündmuse kaheks osaks. Siin on eeliseks põnevus; mida rohkem sündmuste segmente toimub samaaegselt, seda huvitavam on mäng.
  • Võta rakendust mitme animatsiooniga, kus me võime iga animatsiooni oma enda protsessoril töötada.
  • Võta pilditöötlusoperatsioon, kus iga pildi pikslite värv peab olema vastupidine. Raamistik võib kujutise andmeid hõlpsasti jagada mitmele ülesandele, mis võivad üksteisest sõltumatult töötada.
  • Võta finantseerimisasutus, kus portfelli ümberhindamine hõlmab komponente, mis suhtlevad erinevate turgudega üle maailma.
  • Võta tervishoiu rakendus, kus erinevad testid on diagnoosi komponendid.

Püütakse näha, millist rakendust ei saa kasutada paralleelselt funktsionaalse kahvli raamiga.

Kuidas see raamistik Java™ rakenduses näeks?

Taotluse haakimise funktsionaalseteks komponentideks on vaja:

Teavitage iga päringu toimimise komponente (järjekorrad) (funktsioon.) Lihtne klass, mis sisaldab stringfunktsiooni nime ja nendega seotud järjekordade nimekirja, on Java™ põhiprogramm.

Loend 2: funktsiooniklass

Klass


 public class Function {

      private String    name; // Function name
      private Queue[] que;   // Queues for this Function
}

Asetage päring (sisaldab sisendobjekte) igasse järjekorda, mis tagastab objekti massiivi helistajale või ignoreerib tagastatud objekte.

Loend 3: Pane järjekorda


 public Object[] fork(Queue[] que, Object request) {

      Object[] return_obj = new Object[] {null, null, null};

      for (int i = 0; i < que.length; i++) {
putInQueue(que[i], return_obj [i], request);
}

       return return_obj;
}

Oodake lõpetamist/aegumist või ärge oodake.

Loend 4: Oota/eiOota


 public boolean join(Object[] obj) {

    /* when all elements are non-null, return true
* wait for a while
* after an interval, return false
*/

}

Tagastage tulemused helistajale või ignoreerige objekte

Joonis 6: Tagasi helistajale

Return Object[]

Selle raamistiku loomiseks:

  1. Vajadus säilitada tegelik ülesande kood, mis töötab
  2. Vajadus järjehoidjate ja funktsioonide loendi järele
  3. Vajadus säilitada „käivitamine” klass, mis laadib järjekorrad ja funktsioonid mällu

(1) Kood, mida töö peaks välja nägema:

Loend 5: Töö kood


 public static Object main(Object obj) {}

Peamine() meetod, mis aktsepteerib objekti (helistaja helina) ja tagastab objekti (töö tulemuse).

(2) Võiksime hoida järjekorda ja funktsioone objektidena lihtsa loendiklassi piires.

(3) Käivitamine võib lihtsalt panna loendiklassid mällu uue (loendiklassiga) ja käivitada iga järjekorda niidid.

Kuidas lihtne kõne võiks vaadata:

Loend 6: Lihtne kõne


Framework
 fw = new Framework();

    // For each call:
Function
 func = fw.getFunction(name);
Object[] back =
 func.fork(request};

See raamistik on lihtne kasutada, piinlikult lihtne.

Kokkuvõte

Siiani oleme näinud, kuidas taotluse funktsionaalseteks komponentideks ühendamine võib toimida ühe rakenduse sisseehitatud osana (sama JVM-i piires.) Selleks, et olla praktiline, peame raamistiku ka teistest JVM-idest kättesaadavaks tegema. Lihtsalt peab see toetama paljusid kasutajakõnesid samaaegselt serverina.

Selle muutmine serveriks

Milliseid muudatusi peame tegema selle lihtsa raamistiku loomiseks serveriks?

  1. Me peame helistaja tööst eraldama.
  2. Peame andma vea taastamise.
  3. Me peame raamistikku toetama kauge objektina.
  4. Me peame tagama turvalisuse.
  5. Me peame pakkuma serveri juhtimiseks haldustoiminguid.

Eraldamine
Esimene muudatus on taotluste vahendamise (see on eespool nimetatud kahvli() meetodi) eraldamine tegelikust töötlemisest. Me peame eraldama, kuid jälgima iga päringu unikaalses objektis.

Loend 7: Objekti taotlemine

  private long              unique_id; // unique identification of this request
  private Object           input; // input reference, if any
  private boolean         type; // type of request true=sync false=async
  private Object[]         output // the output objects from the tasks
  private AtomicInteger next_output; // subscript to add an element to above
  private Queue[]         que_names; // list of all the queues in this function
  private Queue            agent; // future queue, if used
  private AtomicInteger nbr_remaining; // queues remaining to be processed
  private int                wait_time; // max wait time for sync request 

Mis on väli “agent?”

Agent
Sünkroonne päring tagastab objekti massiivi töötlemisest helistajale. Mida peaks raamistik asünkroonse päringu alusel tagastatud objekti massiivi abil tegema? Raamistik võib valikuliselt panna objekti massiivi (sisendina) uude järjekorda töötlemiseks agendi ülesandega. Sel moel võib agendi ülesanne võtta meetmeid vastavalt eelneva töötlemise lõpetamise olekule.

Näiteks:
Funktsioon on luua hinnapakkumine ja saata see kasutajale asünkroonse päringuna.

1. Helistaja kasutab asünkroonse kahvli() meetodit.
2. Raamistik suunab taotluse oma vastavatesse ridadesse.
3. Kui viimane järjekord lõpeb, edastab raamistik tagastatud objekti massiivi agendi ülesandele, paigutades päringu “agentiks” määratud järjekorda.
4. Agendi ülesanne saadab e-kirja, millega ei tagastata midagi.

Vea taastamine
Teine muudatus on vigade taastamine, professionaalsuse märk.

Mis võib minna valesti? “Midagi, mis võib minna valesti läheb valesti.” Murphy seadus.

Loobuma
Meil võib olla kahvli viga. Piiratud järjekord võib olla täis või järjekord võib olla keelatud (rohkem sellest allpool.) Vea taastamine peaks tagastama kõik edukalt paigutatud järjekorrad ja teavitama sellest helistajat. Näiteks:

  • Meil on funktsioonis kolm järjekorda (A, B, C).
  • Järjekorrad A ja B saavad taotluse edukalt vastu.
  • Järjekord C ei saa päringut vastu võtta, sest järjekord on täis.
    Nüüd me läheme tagasi, püüdes tõmmata päringu kõikidest edukalt valitud ridadest, et saaksime vigaste päringute töötlemise aja salvestada.

Erand/viga
Meil võib olla tegelik tegumikood, mis teeb tööd. Kui see ebaõnnestus, siis tõenäoliselt see uuesti ebaõnnestub. Seetõttu on soovitatav järjekord keelata, kuni arendaja probleemi lahendab. Kui tegumikood on puhas, ei taha me serverit alla võtta. Me tahame serverile teatada, et meil on uus tegumikoodi koopia, mis on puhas ja me tahame, et järjekord oleks lubatud.

Kiirusekaotus
Me võime ülalnimetatud sündmused toimuda asünkroonses taotluses, mida nimetatakse varisemiseks (sünkroonsed taotlused aeguvad ja võivad süsteemist puhastada). Kuna funktsioonid ei saa lõpule viia enne, kui kõik järjekorrad lõpevad, peame peatatud päringud paigutama seiskunud nimekirja. Kui järjekord on jälle kasutuskõlblik, saame töötlemise uuesti peatada peatatud nimekirjast.

Teema viga
Me võime lõnga blokeerida igaveseks väliseks ressursiks või

Expunging on teema omaette ja eeldab niidi ohjeldamine. See artikkel tutvustab teema: Haldamine Teemad Java SE

minna lõputu silmuseni. Mõlemal juhul võib niiditöö sündmuste ajastamisega sündmuste ajal ära tunda selle olukorra ja võib selle asemel asendada niidiga uue niidiga.

Tühistamine
Võiksime, et helistaja sooviks varem esitatud taotluse tühistada. Tühistamine on sarnane väljalülitusveaga, kuid see kehtib nii sünkroonse kui ka asünkroonse päringu puhul. Kuigi päringu tühistamine on kõige soovitavam, ei ole mitme komponendi nõudmisel tühistamise käsitlemise loogika südame nõrk.

Järelevalve
Ajastamine on kasutu, välja arvatud juhul, kui deemonniit jälgib ajastatud sündmusi, otsides tegelikke või võimalikke probleeme.

Teavitamine
Ükski raamistik ei suuda iga olukorda lahendada; mõnikord on vajalik inimeste sekkumine. Me peaksime administraatoritele teatama, saates sõnumi mis tahes vahenditega, mida organisatsioon kasutab (kiirsõnumid, e-post või mis tahes kodune meetod).

Kaugobjekt
Kolmas muudatus toetab raamistikku kui kaugobjekti, kus ressursside säästmiseks on valikuline aktiveerimine/deaktiveerimine.

Kaugmeetod
Põhiline
Kohandatud pesa tehas
IIOP
Kaasaskantav objektiadapter
Jini
Protsessidevaheline kommunikatsioon

Teie keskkond võib koosneda pilvest, kus on erinevad protsessorid paljudes erinevates kohtades. Raamistiku paindlik muutmine on mõistlik.

Turvalisus
Neljas muudatus lisab turvalisust.

Java™ turvatehnoloogia on osa SE/ME platvormidest, see nõuab serveri eesmist lõpetamist turvaklassidega paindlikkuse tagamiseks.

Administraatori funktsioonid
Viies muudatus on administraatori funktsioonide lisamine.

Logimine on igav ja peamiselt kasutu, kuni midagi läheb valesti.

Statistika on tulemuslikkuse analüüsi ja häälestamise aluseks.

Peame pakkuma liideseid sisemiste struktuuridega, et kasutajad saaksid jälgida ja kontrollida funktsionaalsust. See ei ole hea, kui keegi ei tea, mida ta teeb. Kui inimesed teavad, mida ta teeb, siis nad ilmselt tahavad seda muuta.

haakeseadis’i raamistiku kirjutamine, mida on lihtne kasutada ja kohalike kõnede jaoks tõhus, on keeruline. Sama tegemine võrguühenduse puhul on suurettevõte.

Kui kaua kulub sellise serveri ehitamine?

Umbes 5-6 sekundit. Lihtsalt kaua, et üks fail lahti võtta.

Õnneks on olemas üldotstarbelised kahvliühendusega raamid, mis toetavad eespool mainitud omadusi igapäevaste, mitmetuumaliste Java™ SE, ME ja Android™ rakenduste jaoks. Ja kuna raamistik võib töötada RMI serverina (standard/aktiveeritav, IIOP ja POA), on see saadaval Java™ EE rakendustes.

Java™ SE / ME / Android™ platvormide jaoks on SourceForge.net avatud lähtekoodiga tarkvaraprojekte
seal saate alla laadida ka viimased väljaanded.

Järeldus

Arvutimahukate kogukondade jaoks välja töötatud haakeseadis’i raamistiku kasutamine ei pruugi igapäevaseks kasutamiseks sobida.

Suurem osa Java™ multisüdamikutaotlustest vajab tööd oma funktsionaalseteks komponentideks professionaalse klassi raamistikuga, mis on lihtne kasutada, tõhus ja avatud lähtekoodiga.

Viited

Allalaadimised:

Lae alla uusim SE väljaanne  Tymeac siin. Kõik vajalikud dokumendid, skripte, klasside ja allikas.

Lae alla uusim ME väljaanne  Tymeac siin. Kõik vajalikud dokumendid ja allikas.

Lae alla uusim AND väljaanne  Tymeac siin. Kõik dokumendid ja kogu Eclipse projekte.

Lae alla uusim DSE väljaanne  Tymeac siin. Jaga ja valluta versiooni.

Artiklid:

Suure jõudlusega jaga ja vallutada versioon Tymeac  –  Java Fork-Liitu Vallutaja

Suure jõudlusega Android™ versioon Tymeac  –  Juhtimine teemad Android

Kasutades Oodake nimekirjad Tõhusus – Suur jõudlus prioriteet järjekorrad Java SE

Java™ SE Teema Container  –  Juhtimine Teemad Java SE

Muu:

Kahvel liituda järjekorda wiki  –  http://en.wikipedia.org/wiki/haakeseadis_queue

Murphy seadus  –  http://en.wikipedia.org/wiki/Murphy%27s_law

CPU cache wiki  –  http://en.wikipedia.org/wiki/CPU_cache

Cache sidusus wiki  –  http://en.wikipedia.org/wiki/Cache_coherence

Piinlikult paralleelselt wiki  –  http://en.wikipedia.org/wiki/Embarrassingly_parallel

Autori kohta

Edward Harned on tarkvara arendaja üle kolmekümne aasta tööstuse kogemus. Ta esimene juhitud projektidest kui töötaja peamised tööstusharud ja seejärel töötas sõltumatu konsultant. Täna, Ed on vanem arendaja on  Cooperative Software Systems, Inc., Kus viimase kaheteistkümne aasta jooksul on ta kasutada Java™ programmeerimine tuua kahvel liituda lahendusi laias valikus ülesandeid.

© 2010 – 2017  E.P. Harned  All rights reserved