CS452 F23 Lecture Notes
Lecture 07 - 28 Sep 2023
1. Message Passing (cont’d)
- application-determined
- kernel doesn’t care: just copies bytes from buffer in one process to buffer in another
- What are the messages and replies?
- application can perform message type checking by including a type field in every message
2. Communication Patterns
- single producer/single consumer (SPSC)
- producer push: producer sends, consumer replies with acks
- consumer pull: consumer sends requests, producer Replies with items
- no buffering - faster side is throttled by slower side
- multiple producers/single consumer (MPSC)
- producer push works
- consumer pull does not
- where to send request next? Slow producer can block other producers
- single producer/multiple consumer (SPMC)
- with producer push, slow consumer can block other consumers
- consumer pull works
- producer needs to buffer items until requested by all consumers
- multiple producer/multiple consumer (MPMC)
- can be done with an intermediate that buffers data
- acts as single consumer to producers (use producer push)
- acts as single producer to consumers (use consumer pull)
- intermediate is a server, doesn’t block unless there are no requests
- can be done with an intermediate that buffers data
- Server pattern:
- Server does:
- Receive Request - e.g, request alarm, advance timer
- Process Request
- Send Reply (possibly delayed)
- Server never Sends
- Server never blocks unless there are no Requests
- API allows server to hand processing (and reply) to another process
- Server does:
3. Name Resolution
- how does a Sender know where to Send?
- mapping one namespace to another (often application chosen names -> system chosen names)
- filename -> disk location
- domain name -> IP
- URL -> web resouce
- recursive problem
- ask authority to resolve the mapping, but how to resolve the name of the authority
- need a closure mechanism - something to ground the recursion
- In our setting, we need to resolve service names (chosen by application) to TIds (chosen by the kernel)
- this is the job of the Name Server
- how to know the TId of the Name Server? Fix and hard code it into application and kernel
4. Name Server
- RegisterAs(name) - register’s caller’s TId under name
- WhoIs(name) - returns TId associated with name
- not system calls
- implement as user function that wraps Send to Name Server (at known Id)
5. Measuring Execution Times
basic approach:
start = clock() something() // the thing you are trying to measure the execution time of end = clock()
- For assignment K2, you are measuring the time it takes to do a Send/Receive/Reply sequence
5.1. Measurement Challenges
- variability
- time required for something() might vary each time you run it
- do you want to:
- hide/smooth variability?
- measure and understand it?
- overhead
- clock() takes time
- what you measure is actually the time for something() plus the time for clock()
- is this overhead significant?
- depends on how fast something() is, relative to clock()
- clock() takes time
- precision
- how often does your clock tick?
- are you trying to measure something that’s faster than your clock?
5.2. Useful Measurement Techniques
5.2.1. Measure multiple times
for (i=0;i<N;i++) { clock() something() clock() }
- gives you N measurements instead of 1
- can use this to quantify/understand variability, or smooth it
- e.g, compute variance, look for outliers
- doesn’t help with overhead problem
- doesn’t help with precision problem
- can use this to quantify/understand variability, or smooth it
5.2.2. Measure something larger
start = clock() for (i=0;i<N;i++) { something() } end = clock()
- can smooth variability (via averaging) but does not help you measure/understand it
- helps with overhead - increase N until overhead is insignificant
- helps with precision - increase N until what you’re measuring is much slower than your clock