Presentation on theme: "מבוא מורחב למדעי המחשב תרגול 14. Serial Programming Expressions are evaluated in a well-known order One expression at a time Life are easy (though slow)"— Presentation transcript:
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 Typically depends on an internal OS mechanism which we can assume (almost) nothing about
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 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? 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? Because life are parallel! Say that you’ve built a desktop application Receives a query from the user, processes it and returns an answer
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 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 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?
Printing the result (define (ExtractAndPrint q) (let ((result (pop-queue! q))) (display result)) (ExtractAndPrint q) )
Putting it all together (define (myWebApplication) (let ((q-requests (make-queue)) (q-results (make-queue))) (parallel-execute (ReadAndSave q-requests) (ExtractAndProcess q-requests q-results) (ExtractAndPrint q-results ))))
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 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 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 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) )