מבוא מורחב למדעי המחשב תרגול 14. Serial Programming Expressions are evaluated in a well-known order One expression at a time Life are easy (though slow)

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

Lisp. Versions of LISP Lisp is an old language with many variants Lisp is alive and well today Most modern versions are based on Common Lisp LispWorks.
Concurrency Important and difficult (Ada slides copied from Ed Schonberg)
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Silberschatz, Galvin and Gagne ©2007 Operating System Concepts with Java – 7 th Edition, Nov 15, 2006 Chapter 6 (a): Synchronization.
מבוא מורחב 1 Lecture #7. מבוא מורחב 2 The rational number abstraction Wishful thinking: (make-rat ) Creates a rational number (numer ) Returns the numerator.
1/25 Concurrency and asynchronous computing How do we deal with evaluation when we have a bunch of processors involved?
Fall 2008Programming Development Techniques 1 Topic 19 Mutable Data Objects Section 3.3.
CS444/CS544 Operating Systems Synchronization 2/16/2006 Prof. Searleman
מבוא מורחב למדעי המחשב תרגול 13 Lazy Evaluation. Lazy Evaluation Implementation Two types of values – Delayed Values – Actual Values Introduce two functions.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 7 1. Outline More list examples Symbols 2.
Avishai Wool lecture Introduction to Systems Programming Lecture 4 Inter-Process / Inter-Thread Communication.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 11. Dotted tail notation (define (proc m1 m2. opt) ) Mandatory Arguments: m1, m2 Mandatory Arguments: m1, m2.
6.001 SICP SICP Sections 5 & 6 – Oct 5, 2001 Quote & symbols Equality Quiz.
Picking and Choosing… …Amb Above the Line. Intro to Nondeterminism So before we programmed to compute an answer to a problem. What if we set up a system.
SICP Data Mutation Primitive and Compound Data Mutators Stack Example non-mutating mutating Queue Example non-mutating mutating.
1 COMP541 Interrupts, DMA, Serial I/O Montek Singh April 24, 2007.
CPS110: Implementing threads/locks on a uni-processor Landon Cox.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts, Amherst Operating Systems CMPSCI 377 Lecture.
Recursion. Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example: A list.
1 Lecture 15: More about assignment and the Environment Model (EM)
General pattern for selecting some elements of a list This negatives example illustrates a general pattern: If you want a function which selects some elements.
Concurrency Recitation – 2/24 Nisarg Raval Slides by Prof. Landon Cox.
CSE 486/586 CSE 486/586 Distributed Systems PA Best Practices Steve Ko Computer Sciences and Engineering University at Buffalo.
Operating System Review September 10, 2012Introduction to Computer Security ©2004 Matt Bishop Slide #1-1.
Object Oriented Analysis & Design SDL Threads. Contents 2  Processes  Thread Concepts  Creating threads  Critical sections  Synchronizing threads.
Instructor: Chris Trenkov Hands-on Course Python for Absolute Beginners (Spring 2015) Class #002 (January 17, 2015)
© Janice Regan, CMPT 300, May CMPT 300 Introduction to Operating Systems Introduction to Concurrency.
Java Threads. What is a Thread? A thread can be loosely defined as a separate stream of execution that takes place simultaneously with and independently.
COMP 111 Threads and concurrency Sept 28, Tufts University Computer Science2 Who is this guy? I am not Prof. Couch Obvious? Sam Guyer New assistant.
11/18/20151 Operating Systems Design (CS 423) Elsa L Gunter 2112 SC, UIUC Based on slides by Roy Campbell, Sam.
מבוא מורחב 1 Lecture #9. מבוא מורחב 2 Symbol: a primitive type constructors: (quote alpha) ==> quote is a special form. One argument: a name. selectors.
CS1101S Lecture 14: Environment Model & Mutable Data 10 October 2012.
1 Lecture #21 Shared Objects and Concurrent Programming This material is not available in the textbook. The online powerpoint presentations contain the.
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Software Systems Advanced Synchronization Emery Berger and Mark Corner University.
Fall 2008Programming Development Techniques 1 Topic 5 Data Abstraction Note: This represents a change in order. We are skipping to chapter 2 without finishing.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
1 Condition Variables CS 241 Prof. Brighten Godfrey March 16, 2012 University of Illinois.
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Computer Systems Principles Synchronization Emery Berger and Mark Corner University.
Introduction to LISP Atoms, Lists Math. LISP n LISt Processing n Function model –Program = function definition –Give arguments –Returns values n Mathematical.
Fall 2008Programming Development Techniques 1 Topic 20 Concurrency Section 3.4.
1 Ivan Marsic Rutgers University LECTURE 19: Concurrent Programming.
1 Data Abstraction. Pairs and Lists. (SICP Sections – 2.2.1)
1 Lecture #24 Shared Objects and Concurrent Programming This material is not available in the textbook. The online powerpoint presentations contain the.
1/32 Data Mutation Primitive and compound data mutators set! for names set-car!, set-cdr! for pairs Stack example non-mutating mutating Queue example non-mutating.
מבוא מורחב למדעי המחשב בשפת Scheme תרגול 6. 2 List Utilities Scheme built-in procedures –(list x y z...) –(list-ref lst index) –(length lst) –(append.
1 Why Threads are a Bad Idea (for most purposes) based on a presentation by John Ousterhout Sun Microsystems Laboratories Threads!
1 5-High-Performance Embedded Systems using Concurrent Process (cont.)
מבוא מורחב שיעור 7 1 Lecture 7 Data Abstraction. Pairs and Lists. (Sections – 2.2.1)
pThread synchronization
Chapter 3 Lists, Stacks, Queues. Abstract Data Types A set of items – Just items, not data types, nothing related to programming code A set of operations.
CS703 - Advanced Operating Systems
Edited by Original material by Eric Grimson
Background on the need for Synchronization
Lecture 14 - Environment Model (cont.) - Mutation - Stacks and Queues
Lecture 15: Tables and OOP
Background and Motivation
Lecture 16: Tables and OOP
Abstraction and Repetition
Lecture 13 - Assignment and the environments model Chapter 3
Data Mutation Primitive and compound data mutators set! for names
Lecture 14 - Environment Model (cont.) - Mutation - Stacks and Queues
topics mutable data structures
Mutators for compound data Stack Queue
6.001 SICP Data Mutation Primitive and Compound Data Mutators
Lecture 14: The environment model (cont
Abstraction and Repetition
CS333 Intro to Operating Systems
Lisp.
Abstraction and Repetition
Presentation transcript:

מבוא מורחב למדעי המחשב תרגול 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 Typically depends on an internal OS mechanism which we can assume (almost) nothing about

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 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

MindReader (define (MindReader) (display “Enter your name”) (let ((name (read))) (ReadMind name)) (MindReader) )

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! (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?

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 cdba front-ptr rear-ptr

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 (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)))) e new-pair queue cdba front-ptr rear-ptr

pop-queue! (define (pop-queue! q) (let ((result (front-queue q))) (begin (delete-queue! q) result))))

Application Workflow

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 (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 (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) )

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 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) (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 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 (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 (define (front-secure-queue q) (if (empty-secure-queue? q) (error "front of empty queue:" q) (begin ((mutex q) ‘begin) (car (front-ptr q) ((mutex q) ‘end))))

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) ((mutex q) ‘end)))) Mind the gap!

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) ((mutex q) ‘end)))) Mind the gap! What about the return value?

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-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! (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)) )))

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? 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