Ìíîãîïîòî÷íîå ïðîãðàììèðîâàíèå
Êîððåêòíîñòü, ïàòòåðíû, ïîäõîäû
Åâãåíèé Êèðïè÷¼â
24 ñåíòÿáðÿ 2010 ã.
Öåëü äîêëàäà
Ðàñøèðèòü êðóãîçîð â îáëàñòè ìíîãîïîòî÷íîãî
ïðîãðàììèðîâàíèÿ âîîáùå.
Êîððåêòíîñòü
Êàê ñôîðìóëèðîâàòüD ïîâûñèò...
Êëàññèôèêàöèÿ ìíîãîïîòî÷íûõ ïðîãðàìì
Parallelism vs Concurrency
Parallel Îäíà çàäà÷à áüåòñÿ íà ìíîãî ÷àñòåé
Concurrent Ìíî...
×àñòü 1. Êîððåêòíîñòü.
Ñîäåðæàíèå
Êîððåêòíîñòü
Ïðè÷èíû áàãîâ
Äîêàçàòåëüñòâî êîððåêòíîñòè
Óëó÷øåíèå êîððåêòíîñòè
Ïàòòåðíû è ïîäõîäû
Ïàðàëëåëèçì
Co...
Ïðè÷èíû áàãîâ
Êîðåíü âñåõ çîë  èçìåíÿåìîå âî âðåìåíè ñîñòîÿíèå.
N íèòåé, K ñîñòîÿíèé ⇒ O(KN) ïåðåïëåòåíèé
Ïðîìåæóòî÷íûå ñî...
Ïðè÷èíû áàãîâ
Sequentialy correct + Sequentially correct =
Concurrently correct
Äîêàçóåìàÿ êîððåêòíîñòü
Face it:
Ïðîãðàììà íå áûâàåò ¾ïî÷òè êîððåêòíà¿.
Ïóñòü âåðîÿòíîñòü áàãà 10−8
109 âûçîâîâ çà íåäåëþ ...
Äîêàçóåìàÿ êîððåêòíîñòü
Face it:
Ëèáî ïðîãðàììà äîêàçóåìî êîððåêòíà
Ëèáî îíà, ïî÷òè íàâåðíÿêà, íåêîððåêòíà
Tony Hoare:
The...
Ôîðìàëüíûå ìåòîäû
Ïðèìåíÿòü íå îáÿçàòåëüíî.
Ôîðìàëüíûå ìåòîäû
À çà÷åì òîãäà îíè âîîáùå íóæíû?
×òîáû îïèñûâàòü ñèñòåìó ïîëóôîðìàëüíî
×òîáû ÷óÿòü: ôîðìàëèçóåìà ëè ñèñòå...
Ôîðìàëüíûå ìåòîäû
Ìîé îïûò: äîñòàòî÷íî ïîïûòàòüñÿ ôîðìàëèçîâàòü ñèñòåìó:
Âñïëûâàþò ïðîòèâîðå÷èÿ, íåäîãîâîðêè â òðåáîâàíèÿõ...
Ôîðìàëüíûå ìåòîäû
×òî æå ýòî çà ìåòîäû?
Íàïðèìåð, ëèíåéíàÿ òåìïîðàëüíàÿ ëîãèêà.
×òî òàêîå LTL
Ëèíåéíàÿ òåìïîðàëüíàÿ ëîãèêà  ñïîñîá ðàññóæäàòü î
ïîñëåäîâàòåëüíîñòÿõ ñîáûòèé.
Ïðîãðàììà ìîäåëèðóåòñÿ àâòîìà...
Çà÷åì LTL â ýòîì äîêëàäå
×òîáû ëó÷øå ôîðìóëèðîâàòü ñâîéñòâà ñâîèõ ïðîãðàìì.
×òîáû, â êðàéíåì ñëó÷àå, ñóìåòü èõ äîêàçàòü.
Â...
Ñòðóêòóðà Êðèïêå
Ñòðóêòóðà Êðèïêå ≈ ãðàô ñîñòîÿíèé.
Ìíîæåñòâî ñîñòîÿíèé
Íåêîòîðûå íà÷àëüíûå
Íåêîòîðûå ñîåäèíåíû ïåðåõîäîì
...
Ñòðóêòóðà Êðèïêå
Ìèêðîâîëíîâêà.
Ñòðóêòóðà Êðèïêå
Ïåðåõîäû íå ïîäïèñàíû, ïîòîìó ÷òî:
Íîìåð ñîñòîÿíèÿ ïîëíîñòüþ îïèñûâàåò ñîñòîÿíèå
ïðîãðàììû
Åñëè ïåðåõîä ó...
LTL
Ëèíåéíàÿ òåìïîðàëüíàÿ ëîãèêà (Linear Temporal Logic).
Ðàññóæäàåò î ïîñëåäîâàòåëüíîñòÿõ ñîñòîÿíèé ìèðà âî âðåìåíè.
Åñòü...
Ôîðìóëû LTL
p1, p2, . . . Ïåðåìåííûå
A ∧ B, ¬A. . . Ëîãè÷åñêèå ñâÿçêè
XA Â ñëåäóþùèé ìîìåíò A (neXt)
GA ≡ A Âñåãäà A (Glob...
Áåñêîíå÷íîñòè
Íà÷èíàÿ ñ íåêîòîðîãî ìîìåíòà, íàâñåãäà: FG A ≡ ♦ A
Áåñêîíå÷íî ÷àñòî: GF A ≡ ♦A
Èëëþñòðàöèÿ ôîðìóë LTL
Ñâîéñòâà ìíîãîïîòî÷íûõ ïðîãðàìì
Åñòü ðÿä î÷åíü ÷àñòî âñòðå÷àþùèõñÿ ñâîéñòâ.
Ýòî ïðîñòî òåðìèíîëîãèÿ. Íî òåðìèíîëîãèÿ âàæíà...
Ñâîéñòâà
Æèâîñòü (liveness)
×òîEòî õîðîøåå êîãäàEíèáóäü ïðîèçîéäåòX ♦Alive
Çàäàíèå êîãäàEíèáóäü íà÷íåòñÿ
Áåçîïàñíîñòü (saf...
Ñâîéñòâà
Ñïðàâåäëèâîñòü (fairness)
Òî, ÷òî ìîæåò ïðîèçîéòè  ïðîèçîéäåò
Ñëàáàÿ: ♦ Req → ♦Ack
Ðåñóðñ çàïðîøåí @è îñòàåòñÿ çà...
Ïðèìåðû LTL-ñâîéñòâ
Óñòðîéñòâî íå âûêëþ÷àåòñÿ ñàìî ïî ñåáå
(isOn → (isOn U (turnOPressed ∨ noBattery))
Íå ðåæå ÷åì ðàç â 5...
Model checking
Íàóêà î ïðîâåðêå ñâîéñòâ ïðîãðàìì (íàïðèìåð, LTL) íà îñíîâå
èõ ìîäåëåé (íàïðèìåð, ñòðóêòóð Êðèïêå)  Model c...
Èíñòðóìåíò: SPIN
Ïîâñåìåñòíî èñïîëüçóåìûé ÿçûê + âåðèôèêàòîð LTL-ñâîéñòâ
äëÿ ìíîãîçàäà÷íûõ ñèñòåì.
Ëàóðåàò ACM Software Sy...
AspectJ+LTL
http://www.sable.mcgill.ca/~ebodde/rv/JLO/  tEvyX ïðîâåðÿåò
v„vEñâîéñòâà â ðàíòàéìå @çàáðîøåíAF
http://abc.com...
Model checking:further reading
http://www.inf.unibz.it/~artale/FM/slide3.pdf
Òóòîðèàë ïî v„vF
http:
//citeseerx.ist.psu.ed...
Java Path Finder
Âèðòóàëüíàÿ ìàøèíà, óìåþùàÿ ñèìâîëüíî âûïîëíÿòü Java-êîä
è âåðèôèöèðîâàòü ñâîéñòâà äëÿ âñåõ âîçìîæíûõ çàï...
Ôèëîñîôñêîå èçáàâëåíèå îò áàãîâ
Íàäî óìåíüøèòü O(KN).
Óìåíüøèòü ÷èñëî íàáëþäàåìûõ ñîñòîÿíèé (K)
smmut—˜ility
Èíêàïñóëÿöèÿ ...
Immutability
Íåëüçÿ èçìåíèòü âîîáùå ⇒ íåëüçÿ èçìåíèòü íåïðàâèëüíî, íå â
òîì ïîðÿäêå . . .
Äîëæíà ñîáëþäàòüñÿ ðåêóðñèâíî ïî...
Èíêàïñóëÿöèÿ ñîñòîÿíèÿ
Ïðîãðàììà êîððåêòíà ðîâíî íàñòîëüêî, íàñêîëüêî êîððåêòíû è
ñêîîðäèíèðîâàíû âñå, êòî ìîãóò ïîâëèÿòü ...
Âûñîêîóðîâíåâûå îïåðàöèè
Îïðåäåëåíèå: Âûñîêîóðîâíåâàÿ îïåðàöèÿ  îïåðàöèÿ, íå
íàðóøàþùàÿ öåëîñòíîñòü ñèñòåìû.
AtomicInteger...
Âûñîêîóðîâíåâûå îïåðàöèè
×àñòíûé ñëó÷àé:
Ó îáúåêòà â ìåðó áîëüøîå ñîñòîÿíèå
Õî÷åòñÿ àòîìàðíî ïîìåíÿòü íåñêîëüêî åãî ÷àñòåé...
Ôàêòîðèçàöèÿ
Ïðîãðàììà êîððåêòíà ðîâíî íàñòîëüêî, íàñêîëüêî êîððåêòíû è
ñêîîðäèíèðîâàíû âñå, êòî ìîãóò ïîâëèÿòü íà ñîñòîÿí...
Ôàêòîðèçàöèÿ
class DataLoader {
ClientToken beginLoad(Client client);
void writeData(ClientToken token, Data data);
void c...
Ôàêòîðèçàöèÿ
Ãðÿçíûé êîä:
Òàáëèöà ClientToken/òðàíçàêöèÿ
(ìíîãîïîòî÷íûå êëèåíòû)
synchronized(locks.get(token))
Îáå òàáëèö...
Ôàêòîðèçàöèÿ
Ðàçîðâåì ëèøíþþ çàâèñèìîñòü ìåæäó íåçàâèñèìûìè
çàäà÷àìè.
class DataLoader {
PerClientLoader beginLoad(Client ...
Ôàêòîðèçàöèÿ
Ïðîñòîé è íåçàãðÿçíåííûé êîä
Ñèíõðîíèçàöèÿ ïðîñòûì synchronized
Íèêàêèõ òàáëèö
Íèêàêèõ ïðîáëåì ñ îõðàíîé òàáë...
Îñëàáëåíèå òðåáîâàíèé
Èíîãäà îáåñïå÷èòü æåñòêèå èíâàðèàíòû öåëîñòíîñòè
íåâîçìîæíî.
Îíè ìîãóò íàðóøàòüñÿ èçâíå
Åñòü âíåøíèå...
Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü
Ñóäÿ ïî âñåìó, îäèí èç ìîùíåéøèõ ïðèåìîâ ïðîåêòèðîâàíèÿ
íåêîòîðûõ êëàññîâ ìíîãîçàäà÷íûõ ñèñòå...
Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü
Ïðèìåð ñòðóêòóðû:
Ñèñòåìà ïåðèîäè÷åñêè ïðîñûïàåòñÿ è îñìàòðèâàåòñÿ
Âû÷èñëÿåò, ÷åì ìèð îòëè÷àå...
Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü
Ïëþñû ïîäõîäà
”
ñèñòåìà êàê ñõîäÿùèéñÿ ïðîöåññ“:
Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü
Ïîñëåäñòâèÿ áîë...
Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü
Âûñîêàÿ óñòîé÷èâîñòü
Ñèñòåìà íåóÿçâèìà äëÿ
”
ñìåðòåëüíûõ“ áàãîâ @™orrupted
ñèíãëòîíûD óòå÷êè ...
Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü
Ïðèìåíèìîñòü:
Dataow-like çàäà÷è (äàííûå òåêóò ïî ñèñòåìå ñ ðÿäîì
ýòàïîâ îáðàáîòêè)
Ðåïëèêàöè...
Further reading
http://www.webperformancematters.com/journal/2007/8/
21/asynchronous-architectures-4.html  î
ìàñøòàáèðîâàí...
Àáñòðàãèðîâàíèå
Ìíîãîïîòî÷íóþ ïðîãðàììó íàìíîãî ëåã÷å íàïèñàòü è îòëàäèòü,
åñëè â íåé íåò íè÷åãî, êðîìå ñàìîé ñóòè.
Áàãè â...
Àáñòðàãèðîâàíèå
À êàêèå øòóêè óæå åñòü?
Îá ýòîì  ïîçæå.
Àáñòðàãèðîâàíèå: ïðèìåð
Ïðèâÿçêà ê âíåøíåé ñèñòåìå ñêà÷èâàíèÿ óðëîâ.
Çàäàíèÿ ïèøóòñÿ â ôàéëû
Âíåøíÿÿ ñèñòåìà èõ ïîäõâàòûâà...
Àáñòðàãèðîâàíèå: ïðèìåð
Devil in the details:
Íå çàôëóäèòü ñèñòåìó (áëîêèðîâàòüñÿ, åñëè ìíîãî çàäàíèé
”
â ïîëåòå“)
Ñëåäèòü...
Àáñòðàãèðîâàíèå: ïðèìåð
Áûëî: Íåòåñòèðóåìàÿ êàøà, äåëàþùàÿ âñå ñðàçó.
Àáñòðàãèðîâàíèå: ïðèìåð
Ñòàëî:
Ñåìàôîð äëÿ îãðàíè÷åíèÿ ÷èñëà çàäàíèé
”
â ïîëåòå“
Àáñòðàêòíûé
”
áàò÷åð“
Àáñòðàêòíûé
”
ïîëëå...
Àáñòðàãèðîâàíèå: ïðèìåð
class BatcherT {
Batcher(int periodMs);
Stoppable start();
abstract void flush(T[] ts);
void submi...
Àáñòðàãèðîâàíèå: ïðèìåð
class PollerT {
Poller(int periodMs);
Stoppable start();
abstract @Nullable T poll();
abstract voi...
Àáñòðàãèðîâàíèå: ïðèìåð
class TimeouterT {
Poller(int periodMs);
Stoppable start();
void submit(T t, int timeoutMs);
abstr...
Àáñòðàãèðîâàíèå: ïðèìåð
Èòîã: Èç áèçíåñ-ëîãèêè ïîëíîñòüþ ïðîïàë ìíîãîïîòî÷íûé êîä.
×àñòü 2. Ïàòòåðíû è ïîäõîäû.
Ñîäåðæàíèå
Êîððåêòíîñòü
Ïðè÷èíû áàãîâ
Äîêàçàòåëüñòâî êîððåêòíîñòè
Óëó÷øåíèå êîððåêòíîñòè
Ïàòòåðíû è ïîäõîäû
Ïàðàëëåëèçì
Co...
Ìîäåëè ìíîãîïîòî÷íûõ âû÷èñëåíèé
Ïàðàëëåëèçì:
MapReduce: Îãðîìíûå îáúåìû äàííûõ, ðàñïðåäåëåííàÿ
îáðàáîòêà
Fork/Join: Çàäà÷è...
MapReduce
Ñëèøêîì èçâåñòíî, ÷òîáû íà íåì îñòàíàâëèâàòüñÿ
Ðåàëèçàöèÿ äëÿ Java: Hadoop
Fork/join
Ïîõîæå íà MapReduce.
Fork: ïîäåëèòü íà òàêèå æå çàäà÷è, íî ïîìåíüøå
Âûïîëíèòü ïîäçàäà÷è ïàðàëëåëüíî
Join: Ñëèòü ...
Âåêòîðíûå àëãîðèòìû
Huge-scale SIMD: Ïðèìèòèâíûå îïåðàöèè îïåðèðóþò ñðàçó íàä
áîëüøèìè ìàññèâàìè. Ñàìîå òî äëÿ GPU.
Map: Ï...
Âåêòîðíûå ìîäåëè
Ïðåëåñòè:
Ñâåðòêà ïàðàëëåëèçóåòñÿ: Óñêîðåíèå O(P/log P) íà P
ïðîöåññîðàõ (â log P ðàç õóæå ëèíåéíîãî)
Ïðî...
Ïðåôèêñíûå ñóììû
×òî ìîæíî ñäåëàòü ñâåðòêîé/ïðîáåãîì (ò.å. ïàðàëëåëüíî):
sum,min,max,avg,. . .
Radix sort, Quicksort
Ñëîæå...
Ïðåôèêñíûå ñóììû
Îñîáåííî èíòåðåñíî, êàê ýòî äåëàåòñÿ. Áàçîâûå îïåðàöèè
ïîâåðõ ïðîáåãà:
Ðåêóððåíòíàÿ ïîñëåäîâàòåëüíîñòü 1ã...
Ïðåôèêñíûå ñóììû
Óïàêîâêà ìàññèâà (pack, lter).
Ïðåôèêñíûå ñóììû
Ñîðòèðîâêà ïî 1-áèòíîìó ôëàãó (ðàçáèåíèå, partition).
Radixsort òðèâèàëåí.
Ïðåôèêñíûå ñóììû
Ñåãìåíòèðîâàííûé ïðîáåã (Segmented scan).
Ïîçâîëÿåò ðåàëèçîâàòü ðåêóðñèþ áåç ðåêóðñèè.
Ïðåôèêñíûå ñóììû
 öåëîì  êðàñèâûé, ìîùíûé, ïðîñòîé â ðåàëèçàöèè è
íåîáû÷íûé âåêòîðíûé ÿçûê.
http://sourceforge.net/projec...
Message-passing concurrency
Ôàêòè÷åñêè åäèíñòâåííûé ïîäõîä â ðàñïðåäåëåííûõ ñèñòåìàõ.
Âîîáùå íåò ðàçäåëÿåìîãî ñîñòîÿíèÿ
Àê...
Message-passing concurrency
Íå ïàíàöåÿ: äåäëîêè åñòü (íî äðóãèå)
Òåì íå ìåíåå, íàïèñàòü êîððåêòíóþ ïðîãðàììó  ïðîùå
Åñòü ô...
Message-passing concurrency
Ðåàëèçàöèè:
Êó÷à ÿçûêîâ: MPI
Termite Scheme
Clojure: agents
Î÷åíü èíòåðåñíàÿ è ìîùíàÿ âàðèàöèÿ...
Message-passing concurrency
Kilim:
Ëåãêîâåñíûå íèòè (1ìëí â ïîðÿäêå âåùåé, ñâåðõáûñòðîå
ïåðåêëþ÷åíèå)
Î÷åíü áûñòðûé messag...
Message-passing concurrency
Further reading:
http://kilim.malhar.net/
http://www.cl.cam.ac.uk/research/srg/opera/publicati...
Event loop
Âàðèàöèÿ íà òåìó message passing, íî  íå ìíîãî
âçàèìîäåéñòâóþùèõ àêòîðîâ, à îäèí (èëè íåñêîëüêî
îäèíàêîâûõ) æèð...
Event loop
private BlockingQueueOurEvent events =
new LinkedBlockingQueueOurEvent();
void mainLoop() {
while(true) {
proce...
Software Transactional Memory
Òðàíçàêöèè íà óðîâíå ïàìÿòè; àòîìàðíûå êóñêè êîäà.
Ïîëíîöåííûé commit/rollback, ïîëíàÿ àòîìà...
Software Transactional Memory
Ïñåâäîêîä:
// Insert a node into a doubly-linked list atomically
atomic {
newNode-prev = nod...
Software Transactional Memory
Ïñåâäîêîä (âïåðâûå ïðåäëîæåíî â ðåàëèçàöèè â Haskell):
atomic {
if (queueSize  0) {
remove i...
Software Transactional Memory
Ðåàëèçàöèè:
Haskell: ïîëíîöåííàÿ è áåçîïàñíàÿ ïîääåðæêà
Clojure: ïîëíîöåííàÿ è íåáåçîïàñíàÿ ...
Software Transactional Memory
Further reading:
http://research.microsoft.com/Users/simonpj/papers/stm/
stm.pdf  gompos—˜le...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Íàáèðàåò îáîðîòû áëàãîäàðÿ âåáó (AJAX) è áîëüøèì
ðàñïðåäåëåííûì ñèñòåìàì, ãäå ñèíõðîííûé RPC ...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Ñèíõðîííûé API:
interface API {
Answer compute(Question request) throws Whoops;
}
Àñèíõðîííûé...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Ïðè÷èíû:
Áëîêèðóþùèå âûçîâû íåóäîáíû èëè íå ïîääåðæèâàþòñÿ
eteˆ
q…s @
”
àñèíõðîííî ïîëó÷èòü ð...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Ïðîáëåìû:
Íåëèíåéíûé ïîòîê èñïîëíåíèÿ
Î÷åíü íåóäîáíî îòëàæèâàòü
Ïîøàãîâîå âûïîëíåíèå â îòëàä÷...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
public void requestInit() {
AdminConsoleService.App.getInstance().getLoadGeneratorServersInfo...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Êàê æå áûòü?
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Êàê æå áûòü? Âñïîìèíàåì óðîêè ôóíêöèîíàëüíîãî
ïðîãðàììèðîâàíèÿ.
Èçáàâèòüñÿ îò ñèíòàêñè÷åñêîãî...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Êàê æå áûòü? Âñïîìèíàåì óðîêè ôóíêöèîíàëüíîãî
ïðîãðàììèðîâàíèÿ.
Èçáàâèòüñÿ îò ñèíòàêñè÷åñêîãî...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Êàê æå áûòü? Âñïîìèíàåì óðîêè ôóíêöèîíàëüíîãî
ïðîãðàììèðîâàíèÿ.
Èçáàâèòüñÿ îò ñèíòàêñè÷åñêîãî...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Once again:
interface AsyncT {
void run(CallbackT onOk, CallbackThrowable onError);
}
Ýòè îáú...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Ó÷èìñÿ ó .NET âîîáùå è F# â ÷àñòíîñòè.
let AsyncHttp(url:string) =
async { let req = WebReque...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
class AsyncPrimitives {
AsyncT succeed(T value) {...}
AsyncT failwith(Throwable error) {...}
...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Ìîíàäû ïðîíèêëè â ìåéíñòðèì: ó C# òåïåðü òîæå ó÷èìñÿ
(LINQ).
var requests = new[]
{
WebReques...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Ìîíàäû ïðîíèêëè â ìåéíñòðèì: ó C# òåïåðü òîæå ó÷èìñÿ
(LINQ).
var pages = from request in requ...
Àñèíõðîííîå ïðîãðàììèðîâàíèå
Further reading:
Î÷åíü èíòåðåñíûé ïîäõîä ñ èñïîëüçîâàíèåì yield return:
http://tomasp.net/blo...
Further reading
Ðàçíûå ïàòòåðíû ìíîãîïîòî÷íîãî è ðàñïðåäåëåííîãî
ïðîãðàììèðîâàíèÿ. Î÷åíü ìíîãî è èíòåðåñíî.
http://www.cs....
Ñîäåðæàíèå
Êîððåêòíîñòü
Ïðè÷èíû áàãîâ
Äîêàçàòåëüñòâî êîððåêòíîñòè
Óëó÷øåíèå êîððåêòíîñòè
Ïàòòåðíû è ïîäõîäû
Ïàðàëëåëèçì
Co...
Cutting edge
×òî óìååò Haskell:
Âñå ïîáî÷íûå ýôôåêòû êîíòðîëèðóþòñÿ
Íåò íåêîíòðîëèðóåìûõ ïðîáëåì èç-çà èõ íàëè÷èÿ
Ïîçâîëÿå...
Cutting edge
×òî óìååò Haskell:
Ñàìûå áûñòðûå â ìèðå ëåãêîâåñíûå íèòè è ïðèìèòèâû
ñèíõðîíèçàöèè
I ìåñòî íà v—ngu—ge ƒhooto...
Ëåãêîâåñíûå íèòè
Nothing special, ïðîñòî î÷åíü áûñòðûå è ïî÷òè 0
ñèíòàêñè÷åñêîãî îâåðõåäà.
C++0x futures/promises and more...
Ïàðàëëåëüíûå ñòðàòåãèè
Ëåíèâîñòü ïîçâîëÿåò îòäåëèòü àëãîðèòì è ñïîñîá
ðàñïàðàëëåëèâàíèÿ.
Ðåçóëüòàò àëãîðèòìà  ñòðóêòóðà, ï...
Ïàðàëëåëüíûå ñòðàòåãèè
Íàïðèìåð, ñòðàòåãèÿ
”
ïàðàëëåëüíî ôîðñèðîâàòü âñå ýëåìåíòû
ñïèñêà“:
parList :: Strategy a - Strateg...
Data Parallel Haskell
Âåêòîðèçàòîð (òðàíñëèðóåò äàæå ðåêóðñèâíûå ôóíêöèè â
âåêòîðíûå îïåðàöèè)
Áèáëèîòåêà ïàðàëëåëüíûõ âåê...
Data Parallel Haskell
sort :: [:Float:] - [:Float:]
sort a = if (length a = 1) then a
else sa!0 +++ eq +++ sa!1
where
m = ...
Repa
Regular, shape-polymorphic, parallel arrays in Haskell.
The Haskell code transparently makes use of multicore hardwar...
Òðàíçàêöèîííàÿ ïàìÿòü
transfer :: Account - Account - Int - IO ()
transfer from to amount = atomically do
deposit to amoun...
Òðàíçàêöèîííàÿ ïàìÿòü
check True = return ()
check False = retry
limitedWithdraw :: Account - Int - STM ()
limitedWithdraw...
Erlang
Ñâÿçü ïðîöåññîâ òîëüêî ÷åðåç îáìåí ñîîáùåíèÿìè.
Selective receive (èçáèðàòåëüíàÿ âûáîðêà èç mailbox).
Ìîùíàÿ ôè÷àF
...
F#
Asynchronous workows: óæå ðàññìîòðåëè.
C#
Asynchronous LINQ (ìîæíî ñäåëàòü ñàìîìó: LINQ =
ìîíàäû)
Óæå ðàññìîòðåëè
Parallel LINQ
Parallel LINQ (PLINQ)
IEnumerableT, IParallelEnumerableT
AsParallel
http://msdn.microsoft.com/en-us/magazine/cc163329.aspx
Parallel LINQ (PLINQ)
IEnumerableT data = ...;
var q = from x in data.AsParallel()
where p(x)
orderby k(x)
select f(x);
fo...
Parallel LINQ (PLINQ)
IEnumerableT leftData = ..., rightData = ...;
var q = from x in leftData.AsParallel()
join y in righ...
Clojure
Clojure is to concurrent programming as Java was to OOP
Áèáëèîòåêà ÷èñòî ôóíêöèîíàëüíûõ ñòðóêòóð äàííûõ
4 ìåõàíèçì...
Atoms
Áîëåå èëè ìåíåå îáû÷íûå atomic ïåðåìåííûå.
(swap! atom f)
”
Àòîìàðíî çàìåíèòü x íà f (x), âåðíóòü
ñòàðûé x (compare-...
Vars
Thread-local, dynamically scoped ïåðåìåííûå.
Îáëàñòü âèäèìîñòè îïðåäåëÿåòñÿ íå
ñèíòàêñè÷åñêîé âëîæåííîñòüþ, à ñòåêîì ...
Agents
Àñèíõðîííî èçìåíÿåìûå ïåðåìåííûå.
Êàê àêòîðû, íî ïàññèâíûå (àãåíòàì ñíàðóæè ãîâîðÿò, ÷òî èì ñ
ñîáîé ñäåëàòü).
(agen...
Refs
Òðàíçàêöèîííàÿ ïàìÿòü (STM).
Äîâîëüíî îáû÷íàÿ
Òðàíçàêöèè äîëæíû áûòü áåç ïîáî÷íûõ ýôôåêòîâ
Ëþáîïûòíî: (commute x f): ...
Ñîäåðæàíèå
Êîððåêòíîñòü
Ïðè÷èíû áàãîâ
Äîêàçàòåëüñòâî êîððåêòíîñòè
Óëó÷øåíèå êîððåêòíîñòè
Ïàòòåðíû è ïîäõîäû
Ïàðàëëåëèçì
Co...
×òî áûëî
Êëàññèôèêàöèÿ ìíîãîïîòî÷íûõ ïðîãðàìì
Ôîðìàëüíûå ìåòîäû (LTL) è òóëû (SPIN,JPF,CheckThread)
Êîððåêòíîñòü: èíêàïñóë...
×åãî íå áûëî
Ðàñïðåäåëåíùèíà
gonsensusD P€gD ve—der ele™tionF F F
hr„ et™F
wess—ging p—tterns
Íåáëîêèðóþùèå àëãîðèòìû
„her...
The end
Ñïàñèáî! Âîïðîñû?
Евгений Кирпичёв   Многопоточное программирование
Евгений Кирпичёв   Многопоточное программирование
Upcoming SlideShare
Loading in …5
×

Евгений Кирпичёв Многопоточное программирование

483 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
483
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Евгений Кирпичёв Многопоточное программирование

  1. 1. Ìíîãîïîòî÷íîå ïðîãðàììèðîâàíèå Êîððåêòíîñòü, ïàòòåðíû, ïîäõîäû Åâãåíèé Êèðïè÷¼â 24 ñåíòÿáðÿ 2010 ã.
  2. 2. Öåëü äîêëàäà Ðàñøèðèòü êðóãîçîð â îáëàñòè ìíîãîïîòî÷íîãî ïðîãðàììèðîâàíèÿ âîîáùå. Êîððåêòíîñòü Êàê ñôîðìóëèðîâàòüD ïîâûñèòüD ãàðàíòèðîâàòü Èíñòðóìåíòû Ïàòòåðíû è âåëîñèïåäû Ïîäõîäû è ôèøêè ðàçíûõ ÿçûêîâ
  3. 3. Êëàññèôèêàöèÿ ìíîãîïîòî÷íûõ ïðîãðàìì Parallelism vs Concurrency Parallel Îäíà çàäà÷à áüåòñÿ íà ìíîãî ÷àñòåé Concurrent Ìíîãî ðàçíûõ çàäà÷ (ñëîæíåå) Ñåãîäíÿ â îñíîâíîì î concurrency.
  4. 4. ×àñòü 1. Êîððåêòíîñòü.
  5. 5. Ñîäåðæàíèå Êîððåêòíîñòü Ïðè÷èíû áàãîâ Äîêàçàòåëüñòâî êîððåêòíîñòè Óëó÷øåíèå êîððåêòíîñòè Ïàòòåðíû è ïîäõîäû Ïàðàëëåëèçì Concurrency Cutting edge Haskell Erlang .NET Clojure Çàêëþ÷åíèå
  6. 6. Ïðè÷èíû áàãîâ Êîðåíü âñåõ çîë èçìåíÿåìîå âî âðåìåíè ñîñòîÿíèå. N íèòåé, K ñîñòîÿíèé ⇒ O(KN) ïåðåïëåòåíèé Ïðîìåæóòî÷íûå ñîñòîÿíèÿ âèäèìû Äàæå âûçîâ ìåòîäà ýòî áîëüøå íå ÷åðíûé ÿùèê Åãî òåëî áîëüøå íå àòîìàðíî Êîððåêòíûå ìíîãîïîòî÷íûå ïðîãðàììû íå ìîäóëüíû ƒequenti—ly ™orre™t + ƒequenti—lly ™orre™t = gon™urrently ™orre™t
  7. 7. Ïðè÷èíû áàãîâ Sequentialy correct + Sequentially correct = Concurrently correct
  8. 8. Äîêàçóåìàÿ êîððåêòíîñòü Face it: Ïðîãðàììà íå áûâàåò ¾ïî÷òè êîððåêòíà¿. Ïóñòü âåðîÿòíîñòü áàãà 10−8 109 âûçîâîâ çà íåäåëþ è âåðîÿòíîñòü 1 − e−10 ≈ 1 Ïðè íåïðåðûâíîì òåñòèðîâàíèè îøèáêà òîæå âñïëûâåò òîëüêî ÷åðåç íåäåëþ Ðàáîòàåò èäåàëüíî (äîêàçóåìî) èëè íå ðàáîòàåò âîîáùå
  9. 9. Äîêàçóåìàÿ êîððåêòíîñòü Face it: Ëèáî ïðîãðàììà äîêàçóåìî êîððåêòíà Ëèáî îíà, ïî÷òè íàâåðíÿêà, íåêîððåêòíà Tony Hoare: There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deciencies, and the other way is to make it so complicated that there are no obvious deciencies. The rst method is far more dicult.
  10. 10. Ôîðìàëüíûå ìåòîäû Ïðèìåíÿòü íå îáÿçàòåëüíî.
  11. 11. Ôîðìàëüíûå ìåòîäû À çà÷åì òîãäà îíè âîîáùå íóæíû? ×òîáû îïèñûâàòü ñèñòåìó ïîëóôîðìàëüíî ×òîáû ÷óÿòü: ôîðìàëèçóåìà ëè ñèñòåìà â ïðèíöèïå? Åñëè íåò @ñèñòåìà ñëèøêîì çàïóòàíàA î êîððåêòíîñòè ìîæíî çàáûòüF
  12. 12. Ôîðìàëüíûå ìåòîäû Ìîé îïûò: äîñòàòî÷íî ïîïûòàòüñÿ ôîðìàëèçîâàòü ñèñòåìó: Âñïëûâàþò ïðîòèâîðå÷èÿ, íåäîãîâîðêè â òðåáîâàíèÿõ Âûäåëÿþòñÿ êîìïîíåíòû áåç ÷åòêîé ñïåöèôèêàöèè ÁëàæåíD êòî âåðóåòD ÷òî îíè ” è òàê“ ðàáîòàþò
  13. 13. Ôîðìàëüíûå ìåòîäû ×òî æå ýòî çà ìåòîäû? Íàïðèìåð, ëèíåéíàÿ òåìïîðàëüíàÿ ëîãèêà.
  14. 14. ×òî òàêîå LTL Ëèíåéíàÿ òåìïîðàëüíàÿ ëîãèêà ñïîñîá ðàññóæäàòü î ïîñëåäîâàòåëüíîñòÿõ ñîáûòèé. Ïðîãðàììà ìîäåëèðóåòñÿ àâòîìàòîì ( ” ñòðóêòóðîé Êðèïêå“). Èññëåäóþòñÿ âîçìîæíûå ïîñëåäîâàòåëüíîñòè ñîñòîÿíèé.
  15. 15. Çà÷åì LTL â ýòîì äîêëàäå ×òîáû ëó÷øå ôîðìóëèðîâàòü ñâîéñòâà ñâîèõ ïðîãðàìì. ×òîáû, â êðàéíåì ñëó÷àå, ñóìåòü èõ äîêàçàòü. Âðó÷íóþ Èëè èíñòðóìåíòàìè
  16. 16. Ñòðóêòóðà Êðèïêå Ñòðóêòóðà Êðèïêå ≈ ãðàô ñîñòîÿíèé. Ìíîæåñòâî ñîñòîÿíèé Íåêîòîðûå íà÷àëüíûå Íåêîòîðûå ñîåäèíåíû ïåðåõîäîì Ïåðåõîä áåçóñëîâíûé Ìíîæåñòâî ôàêòîâ  êàæäîì ñîñòîÿíèè âåðíû íåêîòîðûå ôàêòû.
  17. 17. Ñòðóêòóðà Êðèïêå Ìèêðîâîëíîâêà.
  18. 18. Ñòðóêòóðà Êðèïêå Ïåðåõîäû íå ïîäïèñàíû, ïîòîìó ÷òî: Íîìåð ñîñòîÿíèÿ ïîëíîñòüþ îïèñûâàåò ñîñòîÿíèå ïðîãðàììû Åñëè ïåðåõîä óñëîâíûé íàäî ïîäåëèòü ñîñòîÿíèå íà äâà ÒîD â êîòîðîì óñëîâèå âåðíî @ïåðåõîä ìîæåò ïðîèçîéòèA ÒîD â êîòîðîì óñëîâèå íåâåðíî @ïåðåõîä íå ìîæåò ïðîèçîéòèA Ïðîãðàììó ìîæíî ñòðàíñëèðîâàòü â ñòðóêòóðó Êðèïêå Ñòðóêòóðû Êðèïêå ïðåêðàñíî ïîääàþòñÿ âåðèôèêàöèè
  19. 19. LTL Ëèíåéíàÿ òåìïîðàëüíàÿ ëîãèêà (Linear Temporal Logic). Ðàññóæäàåò î ïîñëåäîâàòåëüíîñòÿõ ñîñòîÿíèé ìèðà âî âðåìåíè. Åñòü çàïðîñ ⇒ êîãäà-íèáóäü áóäåò îòâåò Áëîêèðîâêà çàïðîøåíà ⇒ êëèåíò áóäåò îáñëóæåí ñêîëü óãîäíî áîëüøîå ÷èñëî ðàç, ïîêà íå îòïóñòèò åå . . . Ïðåëåñòè: Êðàòêàÿ, ïîíÿòíàÿ, ìîùíàÿ è îäíîçíà÷íàÿ LTL-ñâîéñòâà ëåãêî âåðèôèöèðóþòñÿ äàæå âðó÷íóþ Îòíîñèòåëüíî ñòðóêòóð Êðèïêå Ìíîãî ìîùíûõ èíñòðóìåíòîâ
  20. 20. Ôîðìóëû LTL p1, p2, . . . Ïåðåìåííûå A ∧ B, ¬A. . . Ëîãè÷åñêèå ñâÿçêè XA  ñëåäóþùèé ìîìåíò A (neXt) GA ≡ A Âñåãäà A (Globally) FA ≡ ♦A Êîãäà-íèáóäü A (Future) AUB A, ïî êðàéíåé ìåðå äî íàñòóïëåíèÿ B
  21. 21. Áåñêîíå÷íîñòè Íà÷èíàÿ ñ íåêîòîðîãî ìîìåíòà, íàâñåãäà: FG A ≡ ♦ A Áåñêîíå÷íî ÷àñòî: GF A ≡ ♦A
  22. 22. Èëëþñòðàöèÿ ôîðìóë LTL
  23. 23. Ñâîéñòâà ìíîãîïîòî÷íûõ ïðîãðàìì Åñòü ðÿä î÷åíü ÷àñòî âñòðå÷àþùèõñÿ ñâîéñòâ. Ýòî ïðîñòî òåðìèíîëîãèÿ. Íî òåðìèíîëîãèÿ âàæíà. Êàê îíè íàçûâàþòñÿ? Êàê îíè ôîðìóëèðóþòñÿ â LTL?
  24. 24. Ñâîéñòâà Æèâîñòü (liveness) ×òîEòî õîðîøåå êîãäàEíèáóäü ïðîèçîéäåòX ♦Alive Çàäàíèå êîãäàEíèáóäü íà÷íåòñÿ Áåçîïàñíîñòü (safety) ×òîEòî ïëîõîå íèêîãäà íå ïðîèçîéäåòX ¬Dead Çàäàíèå íèêîãäà íå ïîòåðïèò êðàõ
  25. 25. Ñâîéñòâà Ñïðàâåäëèâîñòü (fairness) Òî, ÷òî ìîæåò ïðîèçîéòè ïðîèçîéäåò Ñëàáàÿ: ♦ Req → ♦Ack Ðåñóðñ çàïðîøåí @è îñòàåòñÿ çàïðîøåííûìA → êîãäàEíèáóäü áóäåò âûäàí Ñèëüíàÿ: ♦Req → ♦Ack Íèòü áåñêîíå÷íî ìíîãî ðàç èñïîëíèìà @èìååò íå ñàìûé íèçêèé ïðèîðèòåò èç íåáëîêèðîâàííûõA → êîãäàEíèáóäü ïîëó÷èò êâàíò Àíòîíèì starvation (ãîëîäàíèå)
  26. 26. Ïðèìåðû LTL-ñâîéñòâ Óñòðîéñòâî íå âûêëþ÷àåòñÿ ñàìî ïî ñåáå (isOn → (isOn U (turnOPressed ∨ noBattery)) Íå ðåæå ÷åì ðàç â 5 òàêòîâ âêëþ÷àåòñÿ êîíòðîëëåð äâèãàòåëÿ ¬F5(activeThread = ENGINE_CONTROLLER)
  27. 27. Model checking Íàóêà î ïðîâåðêå ñâîéñòâ ïðîãðàìì (íàïðèìåð, LTL) íà îñíîâå èõ ìîäåëåé (íàïðèìåð, ñòðóêòóð Êðèïêå) Model checking. Ïðåìèÿ Òüþðèíãà 2007 çà äîñòèæåíèÿ â îáëàñòè model checking, ñäåëàâøèå åãî ïðèìåíèìûì äëÿ ïðîåêòîâ ðåàëüíîãî ðàçìåðà.
  28. 28. Èíñòðóìåíò: SPIN Ïîâñåìåñòíî èñïîëüçóåìûé ÿçûê + âåðèôèêàòîð LTL-ñâîéñòâ äëÿ ìíîãîçàäà÷íûõ ñèñòåì. Ëàóðåàò ACM Software System award (2001) (äðóãèå ëàóðåàòû: Unix, TeX, Java, Apache, TCP/IP, . . . ). Ñè-ïîäîáíûé ñèíòàêñèñ Äëÿ íàðóøåííûõ ñâîéñòâ ãåíåðèðóåòñÿ íàðóøàþùàÿ èõ òðàññà (óðîäëèâûé, íî òåðïèìûé) GUI ß ïðîâåðÿë: Ïðèãîäíî äëÿ ïðèìåíåíèÿ íà ïðàêòèêå. http://spinroot.com/spin/whatispin.html îôèöèàëüíûé ñàéòF
  29. 29. AspectJ+LTL http://www.sable.mcgill.ca/~ebodde/rv/JLO/ tEvyX ïðîâåðÿåò v„vEñâîéñòâà â ðàíòàéìå @çàáðîøåíAF http://abc.comlab.ox.ac.uk/extensions „r—™e™he™kX ïðîäîëæåíèåD îò òåõ æå àâòîðîâX ïðîâåðÿåò ðåãóëÿðíûå âûðàæåíèÿ íàä òðàññàìè ïðîãðàììûF
  30. 30. Model checking:further reading http://www.inf.unibz.it/~artale/FM/slide3.pdf Òóòîðèàë ïî v„vF http: //citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.60.3062 Ñòàòüÿ ïðî tEvy http://spinroot.com/spin/Doc/course/mc-tutorial.pdf wodel ghe™kingX e tutori—l overview @ìíîãî ññûëîêA Êàðïîâ ÞF ÃF wodel ™he™king @ïðîäàåòñÿ â ìàãàçèíàõAF http://savenkov.lvk.cs.msu.su/mc.html Èíòåðåñíûé êóðñ â ÌÃÓ @‡s€AF
  31. 31. Java Path Finder Âèðòóàëüíàÿ ìàøèíà, óìåþùàÿ ñèìâîëüíî âûïîëíÿòü Java-êîä è âåðèôèöèðîâàòü ñâîéñòâà äëÿ âñåõ âîçìîæíûõ çàïóñêîâ ñ ó÷åòîì ìíîãîïîòî÷íîñòè. Ñäåëàíî â NASA. http://javapathfinder.sourceforge.net/ http://sourceforge.net/projects/visualjpf/ q…s http://www.visserhome.com/willem/presentations/ ase06jpftut.ppt ïîäîáèå òóòîðèàëà ÓòâåðæäàåòñÿD ÷òî ñïðàâëÿåòñÿ ñ ïðîåêòàìè äî IHuvygF Íàõîäèë áàãè â xeƒeEîâñêîì ñîôòå @â ìàðñîõîäåD íàïðèìåðA Îñíîâàí íà ƒ€sx Åñòü —ntEt—sk è ïëàãèí ê e™lipseY ðàñøèðÿåì ß íàïèñàë ìàëåíüêèé ïðèìåð ñ äåäëîêîìF ÑðàáîòàëîF
  32. 32. Ôèëîñîôñêîå èçáàâëåíèå îò áàãîâ Íàäî óìåíüøèòü O(KN). Óìåíüøèòü ÷èñëî íàáëþäàåìûõ ñîñòîÿíèé (K) smmut—˜ility Èíêàïñóëÿöèÿ ñîñòîÿíèÿ Âûñîêîóðîâíåâûå îïåðàöèè Ôàêòîðèçàöèÿ Ñèíõðîíèçàöèÿ Íàâÿçàòü òðàññàì ýêâèâàëåíòíîñòü Èäåìïîòåíòíûå îïåðàöèè foo();foo(); ∼ foo(); Êîììóòàòèâíûå @íåçàâèñèìûåA îïåðàöèè foo();bar(); ∼ bar();foo();  ò.÷. èíêàïñóëÿöèÿ è íåçàâèñèìûå îáúåêòû Ñ÷èòàòü áîëüøåå ÷èñëî òðàññ êîððåêòíûìè (îñëàáèòü òðåáîâàíèÿ)
  33. 33. Immutability Íåëüçÿ èçìåíèòü âîîáùå ⇒ íåëüçÿ èçìåíèòü íåïðàâèëüíî, íå â òîì ïîðÿäêå . . . Äîëæíà ñîáëþäàòüñÿ ðåêóðñèâíî ïî ïîëÿì îáúåêòà è ïî öåïî÷êå íàñëåäîâàíèÿ â îáå ñòîðîíû.
  34. 34. Èíêàïñóëÿöèÿ ñîñòîÿíèÿ Ïðîãðàììà êîððåêòíà ðîâíî íàñòîëüêî, íàñêîëüêî êîððåêòíû è ñêîîðäèíèðîâàíû âñå, êòî ìîãóò ïîâëèÿòü íà ñîñòîÿíèå îáúåêòà. Ìîðàëü: ×åì ìåíüøå ñïîñîáîâ ïîâëèÿòü íà ñîñòîÿíèå, òåì ëó÷øå. Ìàëî êîìó äàâàòü ê íåìó äîñòóï Ìàëî êîãî íàäî áóäåò êîîðäèíèðîâàòü Äàâàòü äîñòóï â òåðìèíàõ ìàëîãî ÷èñëà âûñîêîóðîâíåâûõ îïåðàöèé Ìàëî êîìáèíàöèé îïåðàöèé íàäî ðàññìàòðèâàòü Ìåíüøå íàðóøàåòñÿ öåëîñòíîñòü ìåæäó îïåðàöèÿìè
  35. 35. Âûñîêîóðîâíåâûå îïåðàöèè Îïðåäåëåíèå: Âûñîêîóðîâíåâàÿ îïåðàöèÿ îïåðàöèÿ, íå íàðóøàþùàÿ öåëîñòíîñòü ñèñòåìû. AtomicInteger.getAndIncrement ConcurrentMap.putIfAbsent Bank.transfer Äîñòàòî÷íî ïðàâèëüíî ðåàëèçîâàòü ñàìó îïåðàöèþ. Ïðîåêòèðóéòå API â òàêîì ñòèëå, åñëè ýòî âîçìîæíî.
  36. 36. Âûñîêîóðîâíåâûå îïåðàöèè ×àñòíûé ñëó÷àé: Ó îáúåêòà â ìåðó áîëüøîå ñîñòîÿíèå Õî÷åòñÿ àòîìàðíî ïîìåíÿòü íåñêîëüêî åãî ÷àñòåé Çàïèõíèòå ñîñòîÿíèå â îáúåêò è ïîìåíÿéòå àòîìàðíî ññûëêó íà ýòîò îáúåêò AtomicReference ×èñòî ôóíêöèîíàëüíûå ñòðóêòóðû äàííûõ âñåãäà ïîòîêîáåçîïàñíû http://tobega.blogspot.com/2008/03/ java-thread-safe-state-design-pattern.html ÑìFòæF yk—s—kiD €urely fun™tion—l d—t— stru™turesF
  37. 37. Ôàêòîðèçàöèÿ Ïðîãðàììà êîððåêòíà ðîâíî íàñòîëüêî, íàñêîëüêî êîððåêòíû è ñêîîðäèíèðîâàíû âñå, êòî ìîãóò ïîâëèÿòü íà ñîñòîÿíèå îáúåêòà. Ìîðàëü: Íåçàâèñèìûå àñïåêòû ñîñòîÿíèÿ âûíîñèòü â íåçàâèñèìûå îáúåêòû. Ñëîæíîñòü ïàäàåò ñ (K1 + K2)N äî KN 1 + KN 2 (áðåä, íî ñóòü ïðèìåðíî òàêàÿ).
  38. 38. Ôàêòîðèçàöèÿ class DataLoader { ClientToken beginLoad(Client client); void writeData(ClientToken token, Data data); void commit(ClientToken token); void rollback(ClientToken token); }
  39. 39. Ôàêòîðèçàöèÿ Ãðÿçíûé êîä: Òàáëèöà ClientToken/òðàíçàêöèÿ (ìíîãîïîòî÷íûå êëèåíòû) synchronized(locks.get(token)) Îáå òàáëèöû íàäî òîæå îõðàíÿòü
  40. 40. Ôàêòîðèçàöèÿ Ðàçîðâåì ëèøíþþ çàâèñèìîñòü ìåæäó íåçàâèñèìûìè çàäà÷àìè. class DataLoader { PerClientLoader beginLoad(Client client); } class PerClientLoader { void writeData(Data data); void commit(); void rollback(); }
  41. 41. Ôàêòîðèçàöèÿ Ïðîñòîé è íåçàãðÿçíåííûé êîä Ñèíõðîíèçàöèÿ ïðîñòûì synchronized Íèêàêèõ òàáëèö Íèêàêèõ ïðîáëåì ñ îõðàíîé òàáëèö îò ìíîãîïîòî÷íîãî äîñòóïà
  42. 42. Îñëàáëåíèå òðåáîâàíèé Èíîãäà îáåñïå÷èòü æåñòêèå èíâàðèàíòû öåëîñòíîñòè íåâîçìîæíî. Îíè ìîãóò íàðóøàòüñÿ èçâíå Åñòü âíåøíèå ïðîöåññûD íàðóøàþùèå öåëîñòíîñòü Îíè íàì íå ïîäêîíòðîëüíû ÍàïðèìåðX ñèíõðîíèçàöèÿ ôàéëîâD èçìåíÿåìûõ âíåøíèìè ïðîöåññàìè Èõ ñëèøêîì äîðîãî ïîääåðæèâàòü ÍàïðèìåðD áîëüøàÿ ðàñïðåäåëåííàÿ ñèñòåìà Ñèíõðîííîå ïðîòàëêèâàíèå èçìåíåíèÿ íà âñå ðåïëèêè ñëèøêîì äîëãî Ñ ó÷åòîì ïàäåíèé óçëîâ âñå åùå õóæå Ëåíü ïèñàòü ñëîæíûé êîä :)
  43. 43. Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü Ñóäÿ ïî âñåìó, îäèí èç ìîùíåéøèõ ïðèåìîâ ïðîåêòèðîâàíèÿ íåêîòîðûõ êëàññîâ ìíîãîçàäà÷íûõ ñèñòåì. Îíà æå ¾eventual consistency¿. Ñóòü: ” Ñîñòîÿíèå ñèñòåìû âñåãäà öåëîñòíî“ î÷åíü òðóäíî è íå âñåãäà íóæíî. ” Ñîñòîÿíèå ñèñòåìû âñå öåëîñòíåå è öåëîñòíåå“ ëåãêî îáåñïå÷èòü, ÷àñòî äîñòàòî÷íî. Äåëàåì ñèñòåìó ëèøü ñòðåìÿùåéñÿ ê ñîñòîÿíèþ öåëîñòíîñòè.
  44. 44. Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü Ïðèìåð ñòðóêòóðû: Ñèñòåìà ïåðèîäè÷åñêè ïðîñûïàåòñÿ è îñìàòðèâàåòñÿ Âû÷èñëÿåò, ÷åì ìèð îòëè÷àåòñÿ îò ” èäåàëà“ ÊàêèåEòî äàííûå ñ ÷åìEòî íå ñîãëàñîâàíû ÊàêèåEòî ãîòîâûå ê îáðàáîòêå äàííûå åùå íå îáðàáàòûâàþòñÿ ÊàêèåEòî äàííûå îáðàáàòûâàþòñÿ óæå ñëèøêîì äîëãîY íàâåðíîåD îáðàáîò÷èê óìåð F F F Âûïîëíÿåò äåéñòâèÿ.
  45. 45. Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü Ïëþñû ïîäõîäà ” ñèñòåìà êàê ñõîäÿùèéñÿ ïðîöåññ“: Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü Ïîñëåäñòâèÿ áîëüøèíñòâà ïðîáëåì ðàíî èëè ïîçäíî èñ÷åçíóòF Âûñîêàÿ ìîäóëüíîñòü Ñèñòåìà ðàñïàäàåòñÿ íà íàáîð ÷èñòî ëèíåéíûõ àâòîìàòîâE ” îáðàáîò÷èêîâ“F Î÷åíü ïðîñòàÿ îòëàäêà è òåñòèðîâàíèå Åñëè ÷òîEòî íå òàê ñèñòåìà ïðîñòî ïðèíÿëà íåïðàâèëüíîå ðåøåíèå â îäíîì èç ñîñòîÿíèéF ÌîæåòD ñàìî ðàññîñåòñÿD ìîæíî íå ôèêñèòü
  46. 46. Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü Âûñîêàÿ óñòîé÷èâîñòü Ñèñòåìà íåóÿçâèìà äëÿ ” ñìåðòåëüíûõ“ áàãîâ @™orrupted ñèíãëòîíûD óòå÷êè ðåñóðñîâAF Ñäåëàòü ñîñòîÿíèå persistentD ïåðåçàïóñêàòü ïðîöåññF Ãîòîâíîñòü ê ðàñïðåäåëåííîé ðàáîòå Ñäåëàòü ñîñòîÿíèå ãëîáàëüíî âèäèìûì è îáåñïå÷èòü ïðîñòåéøóþ áëîêèðîâêóF
  47. 47. Îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü Ïðèìåíèìîñòü: Dataow-like çàäà÷è (äàííûå òåêóò ïî ñèñòåìå ñ ðÿäîì ýòàïîâ îáðàáîòêè) Ðåïëèêàöèÿ è ñèíõðîíèçàöèÿ Àðáèòðàæ ðåñóðñîâ è load balancing . . .
  48. 48. Further reading http://www.webperformancematters.com/journal/2007/8/ 21/asynchronous-architectures-4.html î ìàñøòàáèðîâàíèè â em—zonF Î÷åíü ïîëåçíûå ñîâåòûF http://www.infoq.com/interviews/ dan-pritchett-ebay-architecture î ìàñøòàáèðîâàíèè â ef—y http://roc.cs.berkeley.edu/ Èññëåäîâàòåëüñêèé ïðîåêò ‚e™overyEyriented gomputing Áîðîòüñÿ ñ ïîñëåäñòâèÿìè îøèáîêD ïîñêîëüêó èñêîðåíèòü âñå ïðè÷èíû íåâîçìîæíî Íåñêîëüêî îñíîâíûõ ïðèíöèïîâ @èçîëÿöèÿD èçáûòî÷íîñòüD undoD ñàìîäèàãíîñòèêàD ïåðåçàïóñêàåìîñòüA Î÷åíü ðàçóìíîD åñëè ïîäóìàòüF
  49. 49. Àáñòðàãèðîâàíèå Ìíîãîïîòî÷íóþ ïðîãðàììó íàìíîãî ëåã÷å íàïèñàòü è îòëàäèòü, åñëè â íåé íåò íè÷åãî, êðîìå ñàìîé ñóòè. Áàãè âûëåçàþò íà ïîâåðõíîñòü, íåò ñîáëàçíà ñêàçàòü  íàøåé çàäà÷å òàêàÿ ñèòóàöèÿ íåâîçìîæíà. Àëãîðèòìû ëåã÷å îòëàæèâàòü ïî îòäåëüíîñòè. Íå áëîêèðîâêà èíäåêñà íà ÷òåíèå èëè çàïèñü, à ïðîñòî áëîêèðîâêà íà ÷òåíèå èëè çàïèñü Íå î÷åðåäü e-mail'îâ, à îòêàçîóñòîé÷èâàÿ î÷åðåäü çàäà÷ Íå ïàðàëëåëüíûé ïîäñ÷åò ñëîâ, à MapReduce Íå ïàðàëëåëüíàÿ ôèëüòðàöèÿ ìàññèâà, à ParallelArray Ìîæåò îêàçàòüñÿ, ÷òî òàêàÿ øòóêà óæå åñòü.
  50. 50. Àáñòðàãèðîâàíèå À êàêèå øòóêè óæå åñòü? Îá ýòîì ïîçæå.
  51. 51. Àáñòðàãèðîâàíèå: ïðèìåð Ïðèâÿçêà ê âíåøíåé ñèñòåìå ñêà÷èâàíèÿ óðëîâ. Çàäàíèÿ ïèøóòñÿ â ôàéëû Âíåøíÿÿ ñèñòåìà èõ ïîäõâàòûâàåò Îòâåòû òîæå ïèøóòñÿ â ôàéëû Íàäî ïðåäîñòàâèòü àñèíõðîííûé API void loadPage(url, onOk, onError)
  52. 52. Àáñòðàãèðîâàíèå: ïðèìåð Devil in the details: Íå çàôëóäèòü ñèñòåìó (áëîêèðîâàòüñÿ, åñëè ìíîãî çàäàíèé ” â ïîëåòå“) Ñëåäèòü çà òàéìàóòàìè (äîëãî íå îòâå÷àåò → onError) Íå äîïóñêàòü ãîíîê ìåæäó îòâåòàìè è òàéìàóòàìè Áåðå÷ü íèòêó ñëåæåíèÿ çà îòâåòàìè (âûçûâàòü onOk,onError â îòäåëüíûõ íèòÿõ) Îáðàáàòûâàòü ðåäèðåêòû
  53. 53. Àáñòðàãèðîâàíèå: ïðèìåð Áûëî: Íåòåñòèðóåìàÿ êàøà, äåëàþùàÿ âñå ñðàçó.
  54. 54. Àáñòðàãèðîâàíèå: ïðèìåð Ñòàëî: Ñåìàôîð äëÿ îãðàíè÷åíèÿ ÷èñëà çàäàíèé ” â ïîëåòå“ Àáñòðàêòíûé ” áàò÷åð“ Àáñòðàêòíûé ” ïîëëåð“ Àáñòðàêòíûé ” òàéìàóòåð“ Âñ¼ ýëåìåíòàðíî òåñòèðóåòñÿ (íàøëèñü áàãè) Âñ¼ ïîëåçíî è ïîâòîðíî èñïîëüçóåìî
  55. 55. Àáñòðàãèðîâàíèå: ïðèìåð class BatcherT { Batcher(int periodMs); Stoppable start(); abstract void flush(T[] ts); void submit(T t); }
  56. 56. Àáñòðàãèðîâàíèå: ïðèìåð class PollerT { Poller(int periodMs); Stoppable start(); abstract @Nullable T poll(); abstract void process(@NotNull T t); }
  57. 57. Àáñòðàãèðîâàíèå: ïðèìåð class TimeouterT { Poller(int periodMs); Stoppable start(); void submit(T t, int timeoutMs); abstract void onTimedOut(T t); }
  58. 58. Àáñòðàãèðîâàíèå: ïðèìåð Èòîã: Èç áèçíåñ-ëîãèêè ïîëíîñòüþ ïðîïàë ìíîãîïîòî÷íûé êîä.
  59. 59. ×àñòü 2. Ïàòòåðíû è ïîäõîäû.
  60. 60. Ñîäåðæàíèå Êîððåêòíîñòü Ïðè÷èíû áàãîâ Äîêàçàòåëüñòâî êîððåêòíîñòè Óëó÷øåíèå êîððåêòíîñòè Ïàòòåðíû è ïîäõîäû Ïàðàëëåëèçì Concurrency Cutting edge Haskell Erlang .NET Clojure Çàêëþ÷åíèå
  61. 61. Ìîäåëè ìíîãîïîòî÷íûõ âû÷èñëåíèé Ïàðàëëåëèçì: MapReduce: Îãðîìíûå îáúåìû äàííûõ, ðàñïðåäåëåííàÿ îáðàáîòêà Fork/Join: Çàäà÷è ñ ðåêóðñèâíîé ñòðóêòóðîé Âåêòîðíûå ìîäåëè: huge-scale SIMD Êîíâåéåð / data ow . . . Concurrency: Message-passing (actor model) Event loop (message-passing ñ îäíèì / íåñêîëüêèìè îäèíàêîâûìè àêòîðàìè) ÑåðâåðàD áîëüøèíñòâî q…sEáèáëèîòåêD â òF÷F ƒwing Software Transactional Memory Àñèíõðîííîå ïðîãðàììèðîâàíèå
  62. 62. MapReduce Ñëèøêîì èçâåñòíî, ÷òîáû íà íåì îñòàíàâëèâàòüñÿ Ðåàëèçàöèÿ äëÿ Java: Hadoop
  63. 63. Fork/join Ïîõîæå íà MapReduce. Fork: ïîäåëèòü íà òàêèå æå çàäà÷è, íî ïîìåíüøå Âûïîëíèòü ïîäçàäà÷è ïàðàëëåëüíî Join: Ñëèòü ðåçóëüòàòû ïîäçàäà÷ Ïðèìåðû: Øàõìàòû: fork âîçìîæíûå õîäû, join âûáîð ëó÷øåãî Óìíîæåíèå ìàòðèö: fork ðàçáèåíèå ïî ñòðîêàì/ñòîëáöàì, join NOP Èíòåãðèðîâàíèå: fork ðàçáèåíèå îáëàñòè, join ñëîæåíèå
  64. 64. Âåêòîðíûå àëãîðèòìû Huge-scale SIMD: Ïðèìèòèâíûå îïåðàöèè îïåðèðóþò ñðàçó íàä áîëüøèìè ìàññèâàìè. Ñàìîå òî äëÿ GPU. Map: Ïðèìåíåíèå ôóíêöèè ê êàæäîìó ýëåìåíòó / ñêëåéêà N ìàññèâîâ ïî N-àðíîé îïåðàöèè Fold: Àññîöèàòèâíàÿ ñâåðòêà â ìîíîèäå. àññîöèàòèâíà: a (b c) = (a b) c u åäèíèöà : a u = u a = a fold u [x0, x1, . . . , xn] = u x0 x1 . . . xn Scan (Prex sum): Ïðîáåã (Ïðåôèêñíàÿ ñóììà) scan u [x0, x1, . . . , xn] = [u, u x0, u x0 x1, . . . , u . . . xn]
  65. 65. Âåêòîðíûå ìîäåëè Ïðåëåñòè: Ñâåðòêà ïàðàëëåëèçóåòñÿ: Óñêîðåíèå O(P/log P) íà P ïðîöåññîðàõ (â log P ðàç õóæå ëèíåéíîãî) Ïðîáåã òàê æå ïàðàëëåëèçóåòñÿ Óäèâèòåëüíî ìîùíûå è óíèâåðñàëüíûå îïåðàöèè
  66. 66. Ïðåôèêñíûå ñóììû ×òî ìîæíî ñäåëàòü ñâåðòêîé/ïðîáåãîì (ò.å. ïàðàëëåëüíî): sum,min,max,avg,. . . Radix sort, Quicksort Ñëîæåíèå äëèííûõ ÷èñåë Âûïóêëàÿ îáîëî÷êà Ìíîãèå àëãîðèòìû íà ãðàôàõ Ìíîãèå ðåêóððåíòíûå ïîñëåäîâàòåëüíîñòè n-ãî ïîðÿäêà Òðåõäèàãîíàëüíûå ñèñòåìû óðàâíåíèé . . .
  67. 67. Ïðåôèêñíûå ñóììû Îñîáåííî èíòåðåñíî, êàê ýòî äåëàåòñÿ. Áàçîâûå îïåðàöèè ïîâåðõ ïðîáåãà: Ðåêóððåíòíàÿ ïîñëåäîâàòåëüíîñòü 1ãî ïîðÿäêà Óïàêîâêà ìàññèâà Ñîðòèðîâêà ìàññèâà ïî 1-áèòíîìó ôëàãó (ðàçáèåíèå) Ñåãìåíòèðîâàííûé ïðîáåã (ïðîáåã ñî ñáðîñàìè)
  68. 68. Ïðåôèêñíûå ñóììû Óïàêîâêà ìàññèâà (pack, lter).
  69. 69. Ïðåôèêñíûå ñóììû Ñîðòèðîâêà ïî 1-áèòíîìó ôëàãó (ðàçáèåíèå, partition). Radixsort òðèâèàëåí.
  70. 70. Ïðåôèêñíûå ñóììû Ñåãìåíòèðîâàííûé ïðîáåã (Segmented scan). Ïîçâîëÿåò ðåàëèçîâàòü ðåêóðñèþ áåç ðåêóðñèè.
  71. 71. Ïðåôèêñíûå ñóììû  öåëîì êðàñèâûé, ìîùíûé, ïðîñòîé â ðåàëèçàöèè è íåîáû÷íûé âåêòîðíûé ÿçûê. http://sourceforge.net/projects/amino-cbbs/ ðåàëèçàöèÿ íà t—v— @ñîäåðæèò ìíîãî äðóãèõ ãîòîâûõ ïàðàëëåëüíûõ àëãîðèòìîâAF http://www.cs.cmu.edu/~blelloch/papers/Ble93.pdf ñòàòüÿ €re(x sums —nd their —ppli™—tionsX îáçîð òåõíèê è ïðèìåíåíèéF http://www.cs.cmu.edu/~blelloch/papers/Ble90.pdf †e™tor models for d—t—Ep—r—llel ™omputingD öåëàÿ êíèãà ïðî òî æåF Ñòðîæàéøå ðåêîìåíäóþF
  72. 72. Message-passing concurrency Ôàêòè÷åñêè åäèíñòâåííûé ïîäõîä â ðàñïðåäåëåííûõ ñèñòåìàõ. Âîîáùå íåò ðàçäåëÿåìîãî ñîñòîÿíèÿ Àêòîðû îáìåíèâàþòñÿ ñîîáùåíèÿìè Ó êàæäîãî àêòîðà åñòü mailbox (FIFO-î÷åðåäü ñîîáùåíèé) Îòñûëêà ñîîáùåíèé àñèíõðîííàÿ è íåáëîêèðóþùàÿ
  73. 73. Message-passing concurrency Íå ïàíàöåÿ: äåäëîêè åñòü (íî äðóãèå) Òåì íå ìåíåå, íàïèñàòü êîððåêòíóþ ïðîãðàììó ïðîùå Åñòü ôîðìàëüíûå ìîäåëè (CSP) ⇒ ïîääàåòñÿ âåðèôèêàöèè
  74. 74. Message-passing concurrency Ðåàëèçàöèè: Êó÷à ÿçûêîâ: MPI Termite Scheme Clojure: agents Î÷åíü èíòåðåñíàÿ è ìîùíàÿ âàðèàöèÿF he(nitely worth seeingF http://clojure.org/agents glojure is to ™on™urrent progr—mming —s t—v— w—s to yy€ Scala: actors Java: Kilim Haskell: CHP (Communicating Haskell Processes) È, êîíå÷íî, Erlang uiller fe—tureX ƒele™tive re™eive
  75. 75. Message-passing concurrency Kilim: Ëåãêîâåñíûå íèòè (1ìëí â ïîðÿäêå âåùåé, ñâåðõáûñòðîå ïåðåêëþ÷åíèå) Î÷åíü áûñòðûé message passing (óòâåðæäàåòñÿ, ÷òî 3x Erlang) Ïîñòïðîöåññèò áàéò-êîä (CPS transform äëÿ ìåòîäîâ, àííîòèðîâàííûõ @pausable).
  76. 76. Message-passing concurrency Further reading: http://kilim.malhar.net/ http://www.cl.cam.ac.uk/research/srg/opera/publications/ papers/kilim_ecoop08.pdf íàó÷íàÿ ñòàòüÿF Íå äëÿ ðîáêèõD íî ÷èòàòü ìîæíîF Ìíîãî èíòåðåñíûõ èäåéF http://eprints.kfupm.edu.sa/30514/1/30514.pdf îðèãèíàëüíàÿ êíèãà Òîíè Õîàðà ïðî gommuni™—ting ƒequenti—l €ro™esses òåîðåòè÷åñêàÿ îñíîâà mess—geEp—ssing
  77. 77. Event loop Âàðèàöèÿ íà òåìó message passing, íî íå ìíîãî âçàèìîäåéñòâóþùèõ àêòîðîâ, à îäèí (èëè íåñêîëüêî îäèíàêîâûõ) æèðíûé è âñåìîãóùèé. Ñåðâåðû (è accept, è select/poll/... ñþäà îòíîñÿòñÿ) GUI-ôðåéìâîðêè Ïðåëåñòè: Ýòî íå ôðåéìâîðê, íî ïàòòåðí: ëåãêî ðåàëèçîâàòü è èñïîëüçîâàòü äàæå íà ìèêðîóðîâíå Ê íåìó ñâîäèòñÿ êó÷à çàäà÷ Î÷åíü ëåãêî ïèøåòñÿ Áîëüøèíñòâî ìíîãîïîòî÷íûõ ïðîáëåì îòñóòñòâóþò
  78. 78. Event loop private BlockingQueueOurEvent events = new LinkedBlockingQueueOurEvent(); void mainLoop() { while(true) { processEvent(events.poll()); } } public class OurEvent {...}
  79. 79. Software Transactional Memory Òðàíçàêöèè íà óðîâíå ïàìÿòè; àòîìàðíûå êóñêè êîäà. Ïîëíîöåííûé commit/rollback, ïîëíàÿ àòîìàðíîñòü Òðàíçàêöèè ïîâòîðÿåìû retry ïðè êîììèòåD åñëè èçâíå èçìåíåíà ïðî÷òåííàÿ ïåðåìåííàÿ Òðàíçàêöèîííûå ïðîãðàììû êîìáèíèðóåìû!  îòëè÷èå îò sh—red st—te @ïðàâèëüíîCïðàâèëüíî=ïðàâèëüíîA Íå äîëæíî áûòü íèêàêèõ ïîáî÷íûõ ýôôåêòîâ, êðîìå îáðàùåíèé ê òðàíçàêöèîííîé ïàìÿòè
  80. 80. Software Transactional Memory Ïñåâäîêîä: // Insert a node into a doubly-linked list atomically atomic { newNode-prev = node; newNode-next = node-next; node-next-prev = newNode; node-next = newNode; }
  81. 81. Software Transactional Memory Ïñåâäîêîä (âïåðâûå ïðåäëîæåíî â ðåàëèçàöèè â Haskell): atomic { if (queueSize 0) { remove item from queue and use it } else { retry } } retry ïåðåçàïóñêàåò òðàíçàêöèþ â ìîìåíò, êîãäà èçìåíèòñÿ îäíà èç ïðî÷èòàííûõ åþ ïåðåìåííûõ.
  82. 82. Software Transactional Memory Ðåàëèçàöèè: Haskell: ïîëíîöåííàÿ è áåçîïàñíàÿ ïîääåðæêà Clojure: ïîëíîöåííàÿ è íåáåçîïàñíàÿ ïîääåðæêà Java: Deuce, JSTM, . . . Ìíîãî áèáëèîòåê äëÿ C è C++, â ò.÷. äàæå êîìïèëÿòîðû ñ êëþ÷åâûì ñëîâîì atomic Íå çíàþD èñïîëüçóþò ëè èõ
  83. 83. Software Transactional Memory Further reading: http://research.microsoft.com/Users/simonpj/papers/stm/ stm.pdf gompos—˜le wemory „r—ns—™tionsF http: //themonadreader.files.wordpress.com/2010/01/issue15.pdf Æóðíàë won—dF‚e—der sssue ISD ñîäåðæèò ñòàòüþ smplementing ƒ„w in pure r—skellD èíòåðåñíîå îáñóæäåíèå âîïðîñîâ ðåàëèçàöèè ƒ„wF
  84. 84. Àñèíõðîííîå ïðîãðàììèðîâàíèå Íàáèðàåò îáîðîòû áëàãîäàðÿ âåáó (AJAX) è áîëüøèì ðàñïðåäåëåííûì ñèñòåìàì, ãäå ñèíõðîííûé RPC ñëèøêîì äîðîã. Quite a challenge.
  85. 85. Àñèíõðîííîå ïðîãðàììèðîâàíèå Ñèíõðîííûé API: interface API { Answer compute(Question request) throws Whoops; } Àñèíõðîííûé API: interface API { void compute(Question request, {Answer = void} onReady, {Whoops = void} onWhoops) }
  86. 86. Àñèíõðîííîå ïðîãðàììèðîâàíèå Ïðè÷èíû: Áëîêèðóþùèå âûçîâû íåóäîáíû èëè íå ïîääåðæèâàþòñÿ eteˆ q…s @ ” àñèíõðîííî ïîëó÷èòü ðåçóëüòàò äèàëîãà“ è òFïFA Àñèíõðîííûé API äîïóñêàåò áîëåå ýôôåêòèâíóþ ðåàëèçàöèþ Àñèíõðîííûé ââîäEâûâîä Àñèíõðîííûé äîñòóï ê õðàíèëèùàì äàííûõ F F F Àêòèâíàÿ ñòîðîíà @ñåðâåðD ñåòåâîé äðàéâåð ÎÑ F F F A ìîæåò ðåøàòüD êîãäà è â êàêîì ïîðÿäêå îòâå÷àòü íà çàïðîñû
  87. 87. Àñèíõðîííîå ïðîãðàììèðîâàíèå Ïðîáëåìû: Íåëèíåéíûé ïîòîê èñïîëíåíèÿ Î÷åíü íåóäîáíî îòëàæèâàòü Ïîøàãîâîå âûïîëíåíèå â îòëàä÷èêå äåëàåò íå òî Íåò àíàëîãîâ ïðèâû÷íûõ êîíñòðóêöèé óïðàâëåíèÿ (öèêëû, try..finally . . . ) Äàæå ñýìóëèðîâàòü èõ íåëåãêî  áîëüøèíñòâå ßÏ àñèíõðîííûé êîä êðàéíå ãðîìîçäîê
  88. 88. Àñèíõðîííîå ïðîãðàììèðîâàíèå public void requestInit() { AdminConsoleService.App.getInstance().getLoadGeneratorServersInfo( new AcAsyncCallbackListServerInfo() { public void doOnSuccess(final ListServerInfo loadGenerators) { AdminConsoleService.App.getInstance().getApplicationServersInfo( new AcAsyncCallbackListServerInfo() { public void doOnSuccess(ListServerInfo appServers) { init(appServers, loadGenerators); } }); } }); } (c) ru_java.
  89. 89. Àñèíõðîííîå ïðîãðàììèðîâàíèå Êàê æå áûòü?
  90. 90. Àñèíõðîííîå ïðîãðàììèðîâàíèå Êàê æå áûòü? Âñïîìèíàåì óðîêè ôóíêöèîíàëüíîãî ïðîãðàììèðîâàíèÿ. Èçáàâèòüñÿ îò ñèíòàêñè÷åñêîãî ìóñîðà Àñèíõðîííûå çíà÷åíèÿ ïåðâîêëàññíûå îáúåêòû @ñìF äàëååA Íóæåí ÿçûê ñ çàìûêàíèÿìèF ƒorry guysF Ðåàëèçîâàòü ñòðóêòóðû óïðàâëåíèÿ Íå ñîéòè ñ óìà îò ñëîæíîñòè
  91. 91. Àñèíõðîííîå ïðîãðàììèðîâàíèå Êàê æå áûòü? Âñïîìèíàåì óðîêè ôóíêöèîíàëüíîãî ïðîãðàììèðîâàíèÿ. Èçáàâèòüñÿ îò ñèíòàêñè÷åñêîãî ìóñîðà Ðåàëèçîâàòü ñòðóêòóðû óïðàâëåíèÿ  âèäå ôóíêöèé âûñøåãî ïîðÿäêà Öèêëû ÷åðåç ðåêóðñèþ Ýìóëÿöèÿ õâîñòîâûõ âûçîâîâ Âñå ýòî ñòîèò àáñòðàãèðîâàòü â ” êîìáèí¡àòîðíóþ áèáëèîòåêó“ Íå ñîéòè ñ óìà îò ñëîæíîñòè
  92. 92. Àñèíõðîííîå ïðîãðàììèðîâàíèå Êàê æå áûòü? Âñïîìèíàåì óðîêè ôóíêöèîíàëüíîãî ïðîãðàììèðîâàíèÿ. Èçáàâèòüñÿ îò ñèíòàêñè÷åñêîãî ìóñîðà Ðåàëèçîâàòü ñòðóêòóðû óïðàâëåíèÿ Íå ñîéòè ñ óìà îò ñëîæíîñòè Öåëûé êëàññ ïðîáëåìD ñïåöèôè÷íûõ äëÿ ýòîãî ïîäõîäà Áîëüøèíñòâî ñâÿçàíî ñ mut—˜le st—te Íåèññëåäîâàííàÿ îáëàñòüc
  93. 93. Àñèíõðîííîå ïðîãðàììèðîâàíèå Once again: interface AsyncT { void run(CallbackT onOk, CallbackThrowable onError); } Ýòè îáúåêòû êîìáèíèðóåìû.
  94. 94. Àñèíõðîííîå ïðîãðàììèðîâàíèå Ó÷èìñÿ ó .NET âîîáùå è F# â ÷àñòíîñòè. let AsyncHttp(url:string) = async { let req = WebRequest.Create(url) let! rsp = req.GetResponseAsync() use stream = rsp.GetResponseStream() use reader = new System.IO.StreamReader(stream) return reader.ReadToEnd() } Ýòî íàçûâàåòñÿ ” asynchronous workows“. Workow êðàñèâûé ñèíîíèì äëÿ ñëîâà ” Ìîíàäà“ (google://workow, monad). http://blogs.msdn.com/dsyme/archive/2007/10/11/ introducing-f-asynchronous-workflows.aspx
  95. 95. Àñèíõðîííîå ïðîãðàììèðîâàíèå class AsyncPrimitives { AsyncT succeed(T value) {...} AsyncT failwith(Throwable error) {...} AsyncU bind(AsyncT at, FuncT,AsyncU fau) {...} } Ýòîãî äîñòàòî÷íî äëÿ áîëüøèíñòâà ñòðóêòóð óïðàâëåíèÿ 1. Ýòî íàçûâàåòñÿ ” ìîíàäà“. 1 Ïðè ïîääåðæêå îïòèìèçàöèè õâîñòîâûõ âûçîâîâ
  96. 96. Àñèíõðîííîå ïðîãðàììèðîâàíèå Ìîíàäû ïðîíèêëè â ìåéíñòðèì: ó C# òåïåðü òîæå ó÷èìñÿ (LINQ). var requests = new[] { WebRequest.Create(http://www.google.com/), WebRequest.Create(http://www.yahoo.com/), WebRequest.Create(http://channel9.msdn.com/) }; http://www.aboutcode.net/2008/01/14/Async+WebRequest+ Using+LINQ+Syntax.aspx
  97. 97. Àñèíõðîííîå ïðîãðàììèðîâàíèå Ìîíàäû ïðîíèêëè â ìåéíñòðèì: ó C# òåïåðü òîæå ó÷èìñÿ (LINQ). var pages = from request in requests select from response in request.GetResponseAsync() let stream = response.GetResponseStream() from html in stream.ReadToEndAsync() select new { html, response }; http://www.aboutcode.net/2008/01/14/Async+WebRequest+ Using+LINQ+Syntax.aspx ÌîðàëüX Ïîçíàéòå ìîíàäû ñòàíåò ëåã÷å ïèñàòü àñèíõðîííûé êîäF
  98. 98. Àñèíõðîííîå ïðîãðàììèðîâàíèå Further reading: Î÷åíü èíòåðåñíûé ïîäõîä ñ èñïîëüçîâàíèåì yield return: http://tomasp.net/blog/csharp-async.aspxF ‡es hyer îáúÿñíåíèå ìîíàäû gont íà g5X http://blogs.msdn. com/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx ×òî òàêîå êîìáèíàòîðíàÿ áèáëèîòåêàX http://fprog.ru/2009/issue3D ñòàòüÿ ” Ýëåìåíòû ôóíêöèîíàëüíûõ ÿçûêîâ“ Àñèíõðîííûå êîìáèíàòîðû íà t—v—X http://spbhug.folding-maps.org/wiki/EugeneKirpichovD ñëàéäû ïðî t—v— è p€F
  99. 99. Further reading Ðàçíûå ïàòòåðíû ìíîãîïîòî÷íîãî è ðàñïðåäåëåííîãî ïðîãðàììèðîâàíèÿ. Î÷åíü ìíîãî è èíòåðåñíî. http://www.cs.wustl.edu/~schmidt/patterns-ace.html http: //parlab.eecs.berkeley.edu/wiki/patterns/patterns åùå êðó÷å
  100. 100. Ñîäåðæàíèå Êîððåêòíîñòü Ïðè÷èíû áàãîâ Äîêàçàòåëüñòâî êîððåêòíîñòè Óëó÷øåíèå êîððåêòíîñòè Ïàòòåðíû è ïîäõîäû Ïàðàëëåëèçì Concurrency Cutting edge Haskell Erlang .NET Clojure Çàêëþ÷åíèå
  101. 101. Cutting edge ×òî óìååò Haskell: Âñå ïîáî÷íûå ýôôåêòû êîíòðîëèðóþòñÿ Íåò íåêîíòðîëèðóåìûõ ïðîáëåì èç-çà èõ íàëè÷èÿ Ïîçâîëÿåò íåìûñëèìûå â äðóãèõ ÿçûêàõ âåùè
  102. 102. Cutting edge ×òî óìååò Haskell: Ñàìûå áûñòðûå â ìèðå ëåãêîâåñíûå íèòè è ïðèìèòèâû ñèíõðîíèçàöèè I ìåñòî íà v—ngu—ge ƒhootoutD THx áûñòðåå íàòèâíûõ …˜untuD Sõ áûñòðåå irl—ng3 Ïàðàëëåëüíûå ñòðàòåãèè Ïðîñòûå ïàðàëëåëüíûå âû÷èñëåíèÿX íåò àíàëîãîâ â äðóãèõ ÿçûêàõ Data Parallel Haskell Àâòîìàòè÷åñêè ðàñïàðàëëåëèâàåìûå âåêòîðíûå âû÷èñëåíèÿ Òðàíçàêöèîííàÿ ïàìÿòü Ðàáîòà â íàïðàâëåíèè GPU Ìîùíûå áèáëèîòåêè
  103. 103. Ëåãêîâåñíûå íèòè Nothing special, ïðîñòî î÷åíü áûñòðûå è ïî÷òè 0 ñèíòàêñè÷åñêîãî îâåðõåäà. C++0x futures/promises and more â 60 ñòðîê.
  104. 104. Ïàðàëëåëüíûå ñòðàòåãèè Ëåíèâîñòü ïîçâîëÿåò îòäåëèòü àëãîðèòì è ñïîñîá ðàñïàðàëëåëèâàíèÿ. Ðåçóëüòàò àëãîðèòìà ñòðóêòóðà, ïîëíàÿ ” îáåùàíèé“. Îáåùàíèÿ ” èñïîëíÿþòñÿ“ (ôîðñèðóþòñÿ) ñ ïîìîùüþ ñòðàòåãèè. Ñòðàòåãèÿ ýòî îáûêíîâåííàÿ, ïðîñòàÿ ôóíêöèÿ. Èäåÿ ÿäåðíàÿ. Ýòî ìîæíî ðåàëèçîâàòü è íà Java, åñëè
  105. 105. Ïàðàëëåëüíûå ñòðàòåãèè Íàïðèìåð, ñòðàòåãèÿ ” ïàðàëëåëüíî ôîðñèðîâàòü âñå ýëåìåíòû ñïèñêà“: parList :: Strategy a - Strategy [a] parList strat [] = () parList strat (x:xs) = strat x `par` (parList strat xs)
  106. 106. Data Parallel Haskell Âåêòîðèçàòîð (òðàíñëèðóåò äàæå ðåêóðñèâíûå ôóíêöèè â âåêòîðíûå îïåðàöèè) Áèáëèîòåêà ïàðàëëåëüíûõ âåêòîðíûõ îïåðàöèé dotp_double :: [:Double:] - [:Double:] - Double dotp_double xs ys = sumP [:x * y | x - xs | y - ys:] smMul :: [:[:(Int,Float):]:] - [:Float:] - Float smMul sm v = sumP [: svMul sv v | sv - sm :] http://research.microsoft.com/en-us/um/people/simonpj/ papers/ndp/NdpSlides.pdf ñëàéäû
  107. 107. Data Parallel Haskell sort :: [:Float:] - [:Float:] sort a = if (length a = 1) then a else sa!0 +++ eq +++ sa!1 where m = a!0 lt = [: f | f-a, fm :] eq = [: f | f-a, f==m :] gr = [: f | f-a, fm :] sa = [: sort a | a - [:lt,gr:] :] Âåêòîðèçóåòñÿ è ïàðàëëåëèçóåòñÿ.
  108. 108. Repa Regular, shape-polymorphic, parallel arrays in Haskell. The Haskell code transparently makes use of multicore hardware Ñäåëàíî ãðóïïîé Ìàíóýëÿ ×àêðàâàðòè ýòî îäèí èç êðóòåéøèõ èìïëåìåíòîðîâ Õàñêåëëà. http://justtesting.org/ regular-shape-polymorphic-parallel-arrays-in
  109. 109. Òðàíçàêöèîííàÿ ïàìÿòü transfer :: Account - Account - Int - IO () transfer from to amount = atomically do deposit to amount withdraw from amount
  110. 110. Òðàíçàêöèîííàÿ ïàìÿòü check True = return () check False = retry limitedWithdraw :: Account - Int - STM () limitedWithdraw acc amount = do bal - readTVar acc check (amount = 0 || amount = bal) writeTVar acc (bal - amount) ×åòêîå ðàçäåëåíèå ìåæäó: IO êîä ñ ïðîèçâîëüíûìè ïîáî÷íûìè ýôôåêòàìè STM êîä, åäèíñòâåííûé ýôôåêò êîòîðîãî ðàáîòà ñ òðàíçàêöèîííîé ïàìÿòüþ atomically :: STM t - IO t (íàîáîðîò íåëüçÿ)
  111. 111. Erlang Ñâÿçü ïðîöåññîâ òîëüêî ÷åðåç îáìåí ñîîáùåíèÿìè. Selective receive (èçáèðàòåëüíàÿ âûáîðêà èç mailbox). Ìîùíàÿ ôè÷àF Ïðîçðà÷íàÿ ðàñïðåäåëåííîñòü. Î÷åíü ýôôåêòèâíàÿ ðåàëèçàöèÿ íèòåé è message passing. Î÷åíü êðóòàÿ è ïðîäóìàííàÿ èíôðàñòðóêòóðà. Î÷åíü ïðîñòîé ÿçûê. Àêòèâíî ïðèìåíÿåòñÿ â èíäóñòðèè (â ò.÷. Amazon, Facebook, Yahoo, . . . ). http://spbhug.folding-maps.org/wiki/Erlang ñàìîïèàð YA
  112. 112. F# Asynchronous workows: óæå ðàññìîòðåëè.
  113. 113. C# Asynchronous LINQ (ìîæíî ñäåëàòü ñàìîìó: LINQ = ìîíàäû) Óæå ðàññìîòðåëè Parallel LINQ
  114. 114. Parallel LINQ (PLINQ) IEnumerableT, IParallelEnumerableT AsParallel http://msdn.microsoft.com/en-us/magazine/cc163329.aspx
  115. 115. Parallel LINQ (PLINQ) IEnumerableT data = ...; var q = from x in data.AsParallel() where p(x) orderby k(x) select f(x); foreach (var e in q) a(e); Òðàíñëèðóåòñÿ â êîìáèíàöèþ ParallelEnumerable.{Select,Where,OrderBy} è ò.ï.
  116. 116. Parallel LINQ (PLINQ) IEnumerableT leftData = ..., rightData = ...; var q = from x in leftData.AsParallel() join y in rightData on x.a == y.b select f(x, y);
  117. 117. Clojure Clojure is to concurrent programming as Java was to OOP Áèáëèîòåêà ÷èñòî ôóíêöèîíàëüíûõ ñòðóêòóð äàííûõ 4 ìåõàíèçìà concurrency: Atoms, Vars, Agents, Refs Âñå îíè îïåðèðóþò íàä immutable çíà÷åíèÿìè è ÷èñòûìè ôóíêöèÿìè fe™—use this is the w—y to goF
  118. 118. Atoms Áîëåå èëè ìåíåå îáû÷íûå atomic ïåðåìåííûå. (swap! atom f) ” Àòîìàðíî çàìåíèòü x íà f (x), âåðíóòü ñòàðûé x (compare-and-exchange)“ f îáÿçàíà áûòü ÷èñòîé: åå ìîãóò âûçâàòü íåñêîëüêî ðàç http://clojure.org/atoms
  119. 119. Vars Thread-local, dynamically scoped ïåðåìåííûå. Îáëàñòü âèäèìîñòè îïðåäåëÿåòñÿ íå ñèíòàêñè÷åñêîé âëîæåííîñòüþ, à ñòåêîì âûçîâîâ. (def x 0) îáúÿâèòü x ñ ãëîáàëüíûì çíà÷åíèåì ïî óìîë÷àíèþ 0. x ïðî÷èòàòü çíà÷åíèå x. (set! x 5) ïðèñâîèòü x = 5 â ðàìêàõ òåêóùåé íèòè. (binding [x 5] (do-something)) âûïîëíèòü do-something, ïîëàãàÿ x = 5 â ðàìêàõ òåêóùåé íèòè. http://clojure.org/vars
  120. 120. Agents Àñèíõðîííî èçìåíÿåìûå ïåðåìåííûå. Êàê àêòîðû, íî ïàññèâíûå (àãåíòàì ñíàðóæè ãîâîðÿò, ÷òî èì ñ ñîáîé ñäåëàòü). (agent 0) àãåíò ñ íà÷àëüíûì çíà÷åíèåì 0 (deref x) òåêóùåå çíà÷åíèå (send x f) àñèíõðîííî çàìåíèòü x íà f (x) (await x) äîæäàòüñÿ îêîí÷àíèÿ âñåõ äåéñòâèé íàä àãåíòîì (set-validator x f) ïîâåñèòü âàëèäàòîð ñîñòîÿíèÿ (add-watch x f) ïîâåñèòü ñëóøàòåëÿ http://clojure.org/agents
  121. 121. Refs Òðàíçàêöèîííàÿ ïàìÿòü (STM). Äîâîëüíî îáû÷íàÿ Òðàíçàêöèè äîëæíû áûòü áåç ïîáî÷íûõ ýôôåêòîâ Ëþáîïûòíî: (commute x f): çàìåíèòü x íà f (x), ïðåäïîëàãàÿ ÷òî f êîììóòèðóåò ñ îñòàëüíûìè. ÍàïðèìåðD (commute counter inc) ïîäîéäåò Ðàáîòàåò ñëåãêà áûñòðååD ÷åì äðóãèå ôóíêöèèEìóòàòîðû http://clojure.org/refs
  122. 122. Ñîäåðæàíèå Êîððåêòíîñòü Ïðè÷èíû áàãîâ Äîêàçàòåëüñòâî êîððåêòíîñòè Óëó÷øåíèå êîððåêòíîñòè Ïàòòåðíû è ïîäõîäû Ïàðàëëåëèçì Concurrency Cutting edge Haskell Erlang .NET Clojure Çàêëþ÷åíèå
  123. 123. ×òî áûëî Êëàññèôèêàöèÿ ìíîãîïîòî÷íûõ ïðîãðàìì Ôîðìàëüíûå ìåòîäû (LTL) è òóëû (SPIN,JPF,CheckThread) Êîððåêòíîñòü: èíêàïñóëÿöèÿ, âûñîêîóðîâíåâûå îïåðàöèè, ôàêòîðèçàöèÿ, äåäëîêè, àòîìàðíûå è èäåìïîòåíòíûå îïåðàöèè, îòðèöàòåëüíàÿ îáðàòíàÿ ñâÿçü Ìåòîäèêè: fork/join, âåêòîðíûå àëãîðèòìû, message-passing, event-driven, STM, àñèíõðîííîå ïðîãðàììèðîâàíèå Haskell: ëåãêèå íèòè, ïàðàëëåëüíûå ñòðàòåãèè, âåêòîðèçàöèÿ, STM Erlang: ìîùíàÿ èíôðàñòðóêòóðà Clojure: Atoms, Vars, Agents, Refs C#: PLINQ
  124. 124. ×åãî íå áûëî Ðàñïðåäåëåíùèíà gonsensusD P€gD ve—der ele™tionF F F hr„ et™F wess—ging p—tterns Íåáëîêèðóþùèå àëãîðèòìû „here9s more to itF
  125. 125. The end Ñïàñèáî! Âîïðîñû?

×