מבוא מורחב למדעי המחשב
Download
1 / 39

מבוא מורחב למדעי המחשב - PowerPoint PPT Presentation


  • 148 Views
  • Uploaded on

מבוא מורחב למדעי המחשב. תרגול 14. Serial Programming. Expressions are evaluated in a well-known order One expression at a time Life are easy (though slow). Concurrent (Parallel) Computation. Some code parts are “parallel” to each other Order of evaluation is not well-defined

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' מבוא מורחב למדעי המחשב' - garron


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

Serial programming
Serial Programming

  • Expressions are evaluated in a well-known order

  • One expression at a time

  • Life are easy (though slow)


Concurrent parallel computation
Concurrent (Parallel) Computation

  • Some code parts are “parallel” to each other

  • Order of evaluation is not well-defined

  • Typically depends on an internal OS mechanism which we can assume (almost) nothing about



Why parallel programming1
Why parallel programming?

Because it can be faster!

(define (P i)

(let ((counter (+ 1 (* (- i 1) (power 10 9))))

(upto (* i (power 10 9))))

(define (iter)

(if (< counter upto)

(begin

(if (prime? counter) (display counter) #f)

(increment-counter)

(iter))

'done))

(iter)))

(parallel-execute (P 1) (P 2) ... (P 10))


Faster
faster

  • Can be faster even on a single computer (dual-core)

  • Even on a single-core, things can happen in parallel

  • Mainly CPU vs. I\O (disk access, communication…)

  • But we need to parallelize wisely


Always parallelize
Always parallelize?

  • No

  • Parallel programs are harder to write and are more error prone

  • Also, if designed badly, can be even slower than sequential

  • Parallelize when you can gain something, or when you have to


Why parallelize
Why Parallelize?

  • Because life are parallel!

  • Say that you’ve built a desktop application

  • Receives a query from the user, processes it and returns an answer


Mindreader
MindReader

(define (MindReader)

(display “Enter your name”)

(let ((name (read)))

(ReadMind name))

(MindReader)

)


But reading minds takes time
But reading minds takes time…

(define (MindReader)

(display “Enter your name”)

(let ((name (read)))

(begin

(display “Thinking…”)

(ReadMind name)))

(MindReader)

)


Put it on the web
Put it on the web!

(define (MindReader)

(display “Enter your name”)

(let (name (readMessage))

(begin

(display “Thinking…”)

(let ((result (ReadMind name)))

(display result))))

(MindReader)

)


Won t work
Won’t work

  • Say that reading minds takes only 5 seconds

  • If only 20 people asked for it before I did, I should wait almost 2 minutes

  • And I don’t even get a message

  • And probably my message is thrown away

  • Parallel Programming to the rescue!

  • But how?


Tactics
Tactics

  • MindReader is a black-box, can’t change it

  • But can separate web-interface from reading minds

  • One process will receive messages, the other will read minds, and a third will print results

  • How to communicate?


Queue helper procedures

rear-ptr

front-ptr

queue

a

b

c

d

Queue Helper Procedures

Hidden inside the abstraction

(define (front-ptr q) (cadr q))

(define (rear-ptr q) (cddr q))

(define (set-front-ptr! q item)

(set-car! (cdr q) item))

(define (set-rear-ptr! q item)

(set-cdr! (cdr q) item))


Queue implementation
Queue implementation

(define (make-queue)

(cons 'queue (cons null null)))

(define (queue? q)

(and (pair? q) (eq? 'queue (car q))))

(define (empty-queue? q)

(if (not (queue? q))

(error "object not a queue:" q)

(null? (front-ptr q))))

(define (front-queue q)

(if (empty-queue? q)

(error "front of empty queue:" q)

(car (front-ptr q))))


Queue implementation insert

new-pair

rear-ptr

rear-ptr

front-ptr

queue

e

a

b

c

d

Queue implementation – Insert

(define (insert-queue! q elt)

(let ((new-pair (cons elt nil)))

(cond ((empty-queue? q)

(set-front-ptr! q new-pair)

(set-rear-ptr! q new-pair)

‘ok)

(else

(set-cdr! (rear-ptr q) new-pair)

(set-rear-ptr! q new-pair)

‘ok))))


Pop queue
pop-queue!

(define (pop-queue! q)

(let ((result (front-queue q)))

(begin

(delete-queue! q)

result))))


Application workflow
Application Workflow

ReadAndSave

ExtractAndProcess

ExtractAndPrint

requests

results


New interface function
New interface function

(define (ReadAndSave q)

(display “Enter your name”)

(let ((name (readMessage)))

(begin

(display “Your message was received”)

(insert-queue! q name))) (ReadAndSave q)

)


Processing message
Processing message

(define (ExtractAndProcess q-in q-out)

(let ((name (pop-queue! q-in))

(let ((result (ReadMind name)))

(insert-queue! q-out result)))

(ExtractAndProcess q-in q-out)

)


Printing the result
Printing the result

(define (ExtractAndPrint q)

(let ((result (pop-queue! q)))

(display result))

(ExtractAndPrint q)

)


Putting it all together
Putting it all together

(define (myWebApplication)

(let ((q-requests (make-queue))

(q-results (make-queue)))

(parallel-execute

(ReadAndSave q-requests)

(ExtractAndProcessq-requests

q-results)

(ExtractAndPrintq-results))))


A problem
A Problem

  • One process might try to access the queue while the other is inserting

  • A message might get lost

  • We need Mutual Exclusion


Mutual exclusion
Mutual Exclusion

  • The problem rises in case of a shared object

  • We can’t have two processes writing to it in the same time

  • In the vast majority of cases, read+write is forbidden as well

  • read+read is sometimes ok, depends on the case


Mutex
Mutex

  • A synchronization object

  • A process can request for access

  • It will be granted access only if no one is holding the mutex

  • Otherwise wait


New interface function1
New interface function

(define (ReadAndSave q m)

(display “Enter your name”)

(let ((name (readMessage)))

(begin

(display “Your message was received”)

(m 'begin)

(insert-queue! q name)

(m 'end))

(ReadAndSave q m)

)


New processing message
New processing message

(define (ExtractAndProcess q-in m-in q-out m-out)

(m-in ‘begin)

(let ((name (pop-queue! q-in))

(m-in ‘end)

(let ((result (ReadMind name)))

(begin

(m-out ‘begin)

(insert-queue! q-out result)

(m-out ‘end))))

(ExtractAndProcess q-in m-in q-out m-out)

)


Printing the result1
Printing the result

(define (ExtractAndPrint q m)

(m ‘begin)

(let ((result (pop-queue! q)))

(begin (m ‘end)

(display result)))

(ExtractAndPrint q m)

)


Putting it all together new
Putting it all together (new)

(define (myWebApplication)

(let ((q-requests (make-queue))

(m-requests (make-mutex))

(q-results (make-queue)))

(m-results (make-mutex)))

(parallel-execute

(ReadAndSave q-requests m-requests)

(ExtractAndProcess q-requests m-requests

q-results m-results)

(ExtractAndPrint q-results m-results))))


A better solution
A better solution

  • Put a mutex within the queue object

  • We’ll create a new object: secure-mutex

  • Don’t throw away the old queue, though


Secure queue implementation
Secure-Queue implementation

(define (make-secure-queue)

(cons (make-mutex) (cons ‘secure-queue (cons null null))

(define (mutex q) (car q)

(define (secure-queue? q)

(and (pair? q) (pair? (cdr q)) (eq? ‘secure-queue

(cadr q))))

(define (empty-secure-queue? q)

(if (not (secure-queue? q))

(error "object not a secure queue:" q)

(begin((mutex q) ‘begin)

(let ((res (null? (front-ptr q))))

((mutex q) ‘end)

res)

)))


Front secure queue
front-secure-queue

(define (front-secure-queue q)

(if (empty-secure-queue? q)

(error "front of empty queue:" q)

(begin

((mutex q) ‘begin)

(car (front-ptr q)

((mutexq) ‘end))))


Front secure queue1
front-secure-queue

(define (front-secure-queue q)

(if (empty-secure-queue? q)

(error "front of empty queue:" q)

(begin

((mutex q) ‘begin)

(car (front-ptr q)

((mutexq) ‘end))))

Mind the gap!


Front secure queue2
front-secure-queue

(define (front-secure-queue q)

(if (empty-secure-queue? q)

(error "front of empty queue:" q)

(begin

((mutex q) ‘begin)

(car (front-ptr q)

((mutexq) ‘end))))

Mind the gap!

What about the return value?


Front secure queue3
front-secure-queue

(define (front-secure-queue q)

((mutex q) ‘begin)

(if (empty-secure-queue? q)

(begin

((mutex q) ‘end)

(error "front of empty queue:" q))

(begin

(car (front-ptr q))

((mutex q) ‘end)))))

Not all mutex implementations support multiple acquisition


Front secure queue4
front-secure-queue

(define (front-secure-queue q)

((mutex q) ‘begin)

(if (empty-queue? q)

(begin

((mutex q) ‘end)

(error "front of empty queue:" q))

(begin

(let ((ret (car (front-ptr q)))

((mutex q) ‘end)

ret))))


Insert secure queue
Insert-secure-queue!

(define (insert-secure-queue! q elt)

(let ((new-pair (cons elt nil)))

(cond ((empty-queue? q)

(begin

((mutex q) ‘begin)

(set-front-ptr! q new-pair)

(set-rear-ptr! q new-pair)

((mutex q) ‘end)

‘ok)

(else

(begin

((mutexq) ‘begin)

(set-cdr! (rear-ptr q) new-pair)

(set-rear-ptr! q new-pair)

((mutex q) ‘end)

‘ok))

)))


Insert secure queue1
Insert-secure-queue!

(define (insert-secure-queue! q elt)

(let ((new-pair (cons elt nil)))

(cond ((empty-queue? q)

(begin

((mutex q) ‘begin)

(set-front-ptr! q new-pair)

(set-rear-ptr! q new-pair)

((mutex q) ‘end)

‘ok)

(else

(begin

((mutex q) ‘begin)

(set-cdr! (rear-ptr q) new-pair)

(set-rear-ptr! q new-pair)

((mutex q) ‘end)

‘ok))

)))

Need to lock before calling

queue-empty?


Where to put the mutex
Where to put the mutex?

  • Sometimes difficult to decide

  • Thumb rule – lock as lower as possible, and as little as possible

  • But note that accessing the locks in real life is costly as well


ad