Parallel Patterns Library (PPL) in Visual C++ 2010

880 views

Published on

Presentation on new features of PPL library in Visual C++ 2010.

Presentation made on 2009-12-01.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Parallel Patterns Library (PPL) in Visual C++ 2010

  1. 1. Parallel Patterns Library(PPL)<br />Tomas Dabašinskas, Microsoft Student Partner<br />
  2. 2. Lygiagretus programavimas sudėtingas<br />Padaromas tik labiau patyrusių programuotojų<br />Lygiagretūs šablonai nėra paplitę, gerai žinomi ir lengvai įgyvendinami<br />Krūva galimų problemų:<br />Gijų varžymaisi (races)<br />Mirties taškas (deadlock)<br />Gyvas taškas (livelock)<br />Pamiršti pranešimai (lost event notifications)<br />…<br />
  3. 3. Ko nori programuotojai?<br />
  4. 4. Visual Studio 2010<br />
  5. 5. Parallel Patterns Library (PPL)<br />Veikia kaip ConcurrencyRuntimekomponentas<br />Abstrakcijos lygis tarp programos ir gijų mechanizmo<br />Lengvas panaudojimas<br />Galimybė plėstis (scalability)<br />
  6. 6. Struktūrinis ir nestruktūrinis lygiagretumas<br />Struktūrinis:<br />Lygiagretus kodas pradedamas ir baigiamas viename kontekste<br />Užduotis negali baigtis, kol nesibaigia jos dukterinės užduotys<br />Didesnis našumas<br />Nestruktūrinis:<br />Leidžia užduotį pradėti ir baigti ar jai laukti skirtinguose kontekstuose<br />Lankstesnis<br />
  7. 7. PPL sudėtis<br />Lygiagrečios užduotys (Task Parallelism)<br /> Kelios užduotys lygiagrečiai<br />Lygiagretūs algoritmai (Parallel Algorithms)<br /> Bendriniai algoritmai darbui su duomenų rinkiniais<br />Lygiagrečios talpyklos ir objektai (Parallel containers & objects)<br /> Bendrinės talpyklos/objektai saugiam darbui su jų viduje esančiais elementais<br />
  8. 8. PPL: Užduotys<br />Užduotis (Task)–skaičiavimas, kuris viduje gali būti išskaidytas<br />task_handle klasė<br />Užduočių grupė (Task group) – užduočių, formuojančių loginius skaičiavimus, grupė<br />task_group klasė<br />structured_task_group klasė<br />
  9. 9. Užduočių tipai<br />
  10. 10. Užduotys. Kada/kur naudoti?<br />Rekursiniuose metoduose<br />Norint išskaidyti darbą į atskiras dalis<br />Norėdami aprašysi savo lygiagretų algoritmą, kai neužtenka standartinių PPL algoritmų.<br />Jei galime, naudojame pastaruosius<br />
  11. 11. Let’s CODE!<br />AKA DEMO<br />
  12. 12. PPL: Algoritmai<br />PPL Algoritmai panašūs į STL algoritmus<br />Išnaudoja jau esamą ConcurrencyRuntimefunkctionalumą<br />Algoritmai:<br />parallel_for<br />parallel_for(begin,end,step,[](inti){ …});<br />parallel_for_each<br />parallel_for(v.begin(),v.end(),[](inti){ … });<br />parallel_invoke<br />parallel_invoke([]{…},[]{…},[]{…},…,[]{…});<br />
  13. 13. parallel_for()<br />Kartoja tą pačią užduotį lygiagrečiai<br />Optimaliai išskaido užduotis lygiagrečiam vykdymui<br />Balansuoja tarp išskaidytų dalių priklausomai nuo apkrovų.<br />Užduočių vykdymas neturi numatytos tvarkos<br />Argumentai:<br />Pradinė reikšmė, galinė reikšmė, žingsnis, funkcija<br />Pradinė reikšmė, galinė reikšmė, funkcija<br /> (Žingsnis tokiu atveju pagal nutylėjimą = 1)<br />
  14. 14. for()  parallel_for()<br />Daugelį for ciklų galima pakeisti parallel_for, tačiau:<br />Ciklo indeksas (_Index_type) gali būti tik sveiko tipo<br />Iteracija gali vykti tik į priekį (jei žingsnis (_Step) mažesnis nei 1, gauna klaida)<br />Pabaigos sąlyga turi būti konkreti. Iteracija baigiama, kai iteracijos kintamasis pasiekia reikšmę _Last<br />
  15. 15. parallel_for_each()<br />Lygiagrečiai atlieka veiksmus iteruojamoje talpykloje (tarkim tokioje, kokias suteikia STL)<br />Naudoja tą pačią užduočių skaidymo logiką kaip ir parallel_for<br />Užduočių vykdymas taip pat neturi numatytos tvarkos<br />Veikia tiek su einančiais į priekį (forward) iteratoriais, tiek su atsitiktinio priėjimo (randomaccess) iteratoriais. Su pastaraisiais greičiau.<br />
  16. 16. parallel_invoke()<br />Vykdo užduočių rinkinį paraleliai.<br />Nebaigia darbo tol, kol darbo nebaigia visos lygiagrečiai vykdomos užduotys<br />Priima nuo 2 iki 10 parametrų – funkcijų, kurias vykdys. Kiekviena perduodama funkcija neturi turėti parametrų.<br />Užduočių vykdymas taip pat neturi numatytos tvarkos<br />Patogus, kai norima vykdyti keletą nepriklausomų užduočių lygiagrečiai<br />
  17. 17. parallel_invoke() pavyzdys<br />unsignedintcount_primes(intstart,intend)<br />{<br />unsignedintcount=0u;<br />for(intn=start;n<end;++n)<br />{<br />if(is_prime(n))<br />++count;<br />}<br />returncount;<br />}<br />parallel_invoke(<br />[&]{prime_count1=count_primes(0,10000);},<br />[&]{prime_count2=count_primes(10000,20000);},<br />[&]{prime_count3=count_primes(20000,30000);},<br />[&]{prime_count4=count_primes(30000,40000);}<br />);<br />
  18. 18. Let’s CODE!<br />AKA DEMO<br />
  19. 19. PPL: Talpyklos ir objektai<br />
  20. 20. concurent_vector<br />Naudojimas panašus į STL bibliotekos vector klasės<br />Papildymas, paėmimas, iteracija veikia lygiagrečiai<br />Elementus pridėti galima tik į galą (nėra insert() metodo)<br />Galima pašalinti visus elementus su clear() metodu. Šalinti vieno elemento negalima.<br />Nesaugo savo elementų atmintyje iš eilės, tad negalima atlikti kai kurių masyvam būdingų operacijų<br />Galima keisti dydį su grow_by() ir grow_to_at_least() (atitikmuo resize())<br />
  21. 21. concurent_queue<br />Naudojimas panašus į STL bibliotekos queue() klasės<br />Leidžia pasiekti pirmą (dequeue) ir paskutinį (enqueue) elementus.<br />Nėra front() ir pop() metodų. Vietoj jų – try_pop()<br />Nėraback() metodo, tad negalima kreiptis į eilės galą<br />Metodu empty() galima patikrinti ar eilė tuščia.<br />Iteracija ir bei dydžio gavimas nėra pritaikyti lygiagrečiam veikimu<br />
  22. 22. combinable<br />Suteikia daug kartų naudojamą saugyklą gijoje, iš kurių rezultatai sujungiami į bendrą<br />Naudingas, kai reikia kažkokiu resursu dalintis keliose gijose/užduotyse<br />Nebereikia naudoti papildomų priemonių (tarkim mutex)<br />combinable<int>sum;<br />parallel_for_each(a.begin(),a.end(),[&](inti){<br />sum.local()+=(is_prime(i)?i:0);<br />});<br />prime_sum=sum.combine(plus<int>());<br />
  23. 23. PPL: Lygiagretaus darbo atšaukimas (sustabdymas)<br />tg1<br />t1<br />t2<br />t3<br />tg2<br />Užduotis<br />Užduočių grupė<br />t4<br />t5<br />
  24. 24. Lygiagrečių užduočių stabdymas<br />Du būdai sustabdyti:<br />task_group::cancel() ir structured_task_group::cancel()<br />Atšaukia užduočių grupę ir visas dukterines užduočių grupes (iš viršaus į apačią)<br />Efektyvesnis<br />Išimties (exception) išmetimas užduoties darbo funkcijoje.<br />Atšaukinėja kiekvieną užduočių grupę atskirai (iš apačios į viršų)<br />
  25. 25. Lygiagrečių algoritmų stabdymas<br />Kadangi PPL lygiagretūs algoritmai veikia lygiagrečių užduočių pagrindu, jiems sustabdyti (atšaukti) galime naudoti tuos pačios būdus.<br />structured_task_grouptg;<br />task_group_statusstatus=tg.run_and_wait([&]{<br />parallel_for(0,100,[&](inti){<br />// Atšaukiam užduotį, kai pasiekiam 50<br />if(i==50) {<br />tg.cancel();<br />}else{<br />// Normalus darbas<br />}<br />});<br />});<br />
  26. 26. (NE)stabdom<br />Lygiagretaus darbo stabdymas (atšaukimas) tinkamas naudoti, kai kiekviena susijusios grupės užduotis darbą gali baigti savo laiku<br />Yra atvejų, kai lygiagrečios užduočių grupės sustabdymas nėra geras sprendimas:<br />Užduotis, kuri atblokuoja kitą aktyvią užduotį, nėra startavusi  Ši užduotis nestartuoja, jei grupė atšaukiama  Galimas mirties taškas (deadlock)<br />
  27. 27. Parallel Debugger<br />
  28. 28. Parallel Debugger<br />Parallel Tasks<br />Parallel Stacks<br />
  29. 29. Let’s CODE!<br />AKA DEMO<br />
  30. 30. Ačiū už dėmesį<br />Tomas Dabašinskas<br />tomas@studentpartners.com<br />http://www.winblog.lt<br />

×