Title: Exercise: Eratosthenes Sieve
1Exercise Eratosthenes Sieve
- Eratosthenes sieve
- An algorithm for computing prime numbers
- Starts with a sequence 2,3,4, N, finds all prime
numbers lt N - 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,2
1,22,23,24,25,26 - 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,2
1,22,23,24,25,26 - 3,5,7,9,11,13,15,17,19, 21, 23, 25
- 5,7,11,13,17,19, 23, 25
- 7,11,13, 17, 19, 23, 25
- 11,13,17,19,23,25
2Exercise Eratosthenes Sieve
- Idea Speed-up the computation of the
Eratosthenes sieve on a multi-CPU computer by
doing the work on each line in a separate
process. - Process Start (core)
- for(i2 iltn i)
- write(i) // write(1, i, sizeof(int))
- Process Filter (core)
- read(p) // read(0, p, sizeof(int))
- OutputPrime(p)
- while (read(val) gt0)
- if (val p ! 0)
- write(val)
- Launched from shell
- Start 25 Filter Filter Filter Filter
3Exercise Eratosthenes Sieve
- Problems
- How many filter processes to start?
- Very tedious to launch it this way
- Solution Create filter processes automatically
- Question Who creates the filter processes?
- Answer
- Start process forks the first filter process
- i-th filter process forks (i1)th filter process
- No need to have separate program files, the
filter process can be programmed as a procedure
4Exercise Eratosthenes Sieve
- Process Start (core)
- pid fork()
- if (pid 0)
- filter()
- else
- for(i2 iltn i)
- write(i) // write(1, i, sizeof(int))
-
- void filter()
- read(p) // read(0, p, sizeof(int))
- OutputPrime(p)
- pid fork()
- if (pid 0)
- filter()
- else
- while (read(val) gt0)
- if (val p ! 0)
- write(val)
5Exercise Eratosthenes Sieve
- What is the problem now?
- Everybody reads from stdin and writes to stdout
- Solution
- Connect the processes using pipes
- Process Start (core)
- pipe(pipes)
- pid fork()
- if (pid 0)
- close(pipes1)
- filter(pipes0)
- else
- close(pipes0)
- for(i2 iltn i)
- write(pipes1, i) // write(1, i,
sizeof(int)) - close(pipes1)
6Exercise Eratosthenes Sieve
- void filter(int fd)
- int pipes2, pid, p, val
- read(fd, p) // read(0, p, sizeof(int))
- OutputPrime(p)
- pipe(pipes)
- pid fork()
- if (pid 0)
- close(pipes1)
- filter(pipes0)
- else
- close(pipes0)
- while (read(fd, val) gt0)
- if (val p ! 0)
- write(pipes1, val)
- close(pipes1)
-
7Exercise Eratosthenes Sieve
- Does it work now?
- no, each filter will launch a new filter
- need to know when to terminate
- when the input of the filter contains single
value its prime number p - when p2 gtn, all the remaining numbers are primes
as well
8Exercise Eratosthenes Sieve
- void filter(int fd)
- int pipes2, pid, p, val
- read(fd, p) // read(0, p, sizeof(int))
- OutputPrime(p)
- if (ppgtn)
- while(read(fd, p))
- OutputPrime(p)
- else
- pipe(pipes)
- pid fork()
- if (pid 0)
- close(pipes1)
- filter(pipes0)
- else
- close(pipes0)
- while (read(fd, val) gt0)
- if (val p ! 0)
- write(pipes1, val)
9Exercise Eratosthenes Sieve
- Does it work now?
- Yes!
- But, can we make Start and Filter standalone
processes communicating through stdin/stdout? - Yes, but we need to learn how to
duplicate/redirect file pointers - System call dup2(int newfp, int oldfp) wil
replace the oldfp with the newfp - Lets see how it works
10Exercise Eratosthenes Sieve
- Process Start (core)
- itoa(n, nString, 10) // convert integer n into
string nString - pid fork()
- if (pid 0)
- close(pipes1)
- dup2(pipes0,0) // pipes0 will be now my
stdin - Execl(filter, filter, nString, NULL)
- else
- close(pipes0)
- dup2(pipes1, 1) // pipes1 will be now my
stdout - for(i2 iltn i)
- write(1, i) // write(1, i, sizeof(int))
11Exercise Eratosthenes Sieve
- filter.c
- int main(int argc, int argv)
- int pipes2, pid, p, val, n
- n atoi(argv1)
- read(0, p) // read(0, p, sizeof(int))
- OutputPrime(p)
- if (ppgtn)
- while(read(0, p))
- OutputPrime(p)
- else
- else
- pipe(pipes)
- pid fork()
- if (pid 0)
- close(pipes1)
- dup2(pipes0, 0)
- execl(filter, filter, argv1)
- else
- close(pipes0)
- dup2(pipes1, 1)
- while (read(fd, val) gt0)
- if (val p ! 0)
- write(pipes1, val)
- close(pipes1)
-
-
12Exercise Eratosthenes Sieve
- Are we done now?
- Yes,
- for a while
- What about multithreaded Eratosthenes?
- Wait till we learn about threads.
13Chapter 4 Threads
14Threads vs Processes
- Process
- A unit/thread of execution, together with code,
data and other resources to support the
execution. - Idea
- Make distinction between the resources and the
execution threads - Could the same resources support several threads
of execution? - Code, data, .., - yes
- CPU registers, stack - no
15Single vs Multithreaded Processes
16Chapter 4 Threads
- Overview
- Multithreading Models
- Threading Issues
- Pthreads
- Windows XP Threads
- Linux Threads
- Java Threads
17Why Threads?
- Responsiveness
- One thread handles user interaction
- Another thread does the background work (i.e.
load web page) - Utilization of multiprocessor architectures
- One process/thread can utilize only one CPU
- Well, but all this applies to one thread per
process as well, just use processes - Efficiency and convenience
- Resource sharing (shared memory, open files, )
- Creating a thread, context switch between
threads, can be much cheaper then for full
processes - Why?
18Thread Library
- Provides the programmer an API for creating and
managing threads - User thread
- The unit of execution managed by the thread
library - This is what is presented to the programmer
- Kernel thread
- The unit of execution scheduled and managed by
the kernel - Thread libraries
- POSIX Pthreads
- Java threads
- Win32 threads
- Essentially all modern OSs support kernel threads
19User Space Thread Library
- All code and data structures for thread
management in user space - No system calls involved, no OS support needed
- Many(all) user threads mapped to single kernel
thread
20Many to One Mapping
- Properties
- Cheap/fast, but runs as one process to the OS
scheduler - What happens if one thread blocks on an I/O?
- All other threads block as well
- How to make use of multiple CPUs?
- Not possible
- Examples
- Solaris Green Threads
- GNU Portable Threads
21Kernel Space Thread Library
- Code and data structures in kernel space
- Need support by the OS
- Calling a thread library typically results in
system call - Each user thread is mapped to a kernel thread
22One to One Mapping
- Properties
- Usually, limited number of threads
- Thread management relatively costly
- But provides full benefits of multithreading
- Examples
- Windows NT/XP/2000
- Linux
- Solaris 9 and later
23Many-to-Many Model
- Allows many user level threads to be mapped to
many kernel threads - The thread library cooperates with the OS to
dynamically map user threads to kernel threads - Intermediate costs and most of the benefits of
multithreading - Examples
- Solaris prior to version 9
- Windows NT/2000 with the ThreadFiber package
24Two-level Model
- Similar to MM, except that it allows a user
thread to be bound to kernel thread - Examples
- IRIX
- HP-UX
- Tru64 UNIX
- Solaris 8 and earlier
25Single vs Multithreaded Processes
26Thread Library
- Provides the programmer an API for creating and
managing threads - User thread
- The unit of execution managed by the thread
library - This is what is presented to the programmer
- Kernel thread
- The unit of execution scheduled and managed by
the kernel - Thread libraries
- POSIX Pthreads
- Java threads
- Win32 threads
- Essentially all modern OSs support kernel threads
27User to Kernel Thread Mapping
28Threading Issues
- Ha! It is nice to have threads, but what does
that mean when we think through all consequences? - Issues
- Semantics of fork() and exec() system calls
- Thread cancellation
- Signal handling
- Thread pools
- Thread specific data
- Scheduler activations
29Threading Issues
- Ha! It is nice to have threads, but what does
that mean when we think through all consequences? - Issues
- Semantics of fork() and exec() system calls
- Thread cancellation
- Signal handling
- Thread pools
- Thread specific data
- Scheduler activations
30Semantics of fork() and exec()
- Does fork() duplicate only the calling thread or
all threads? - Often two versions provided
- Which one to use?
- What does exec() do?
- Well, it replaces the address space, so all
threads must go
31Thread Cancellation
- Terminating a thread before it has finished
- Two general approaches
- Asynchronous cancellation terminates the target
thread immediately - Might leave the shared data in corrupt state
- Some resources may not be freed
- Deferred cancellation
- Set a flag which the target thread periodically
checks to see if it should be cancelled - Allows graceful termination
32Signal Handling
- Signals are used in UNIX systems to notify a
process that a particular event has occurred - Essentially software interrupt
- A signal handler is used to process signals
- Signal is generated by particular event
- Signal is delivered to a process
- Signal is handled
- Options
- Deliver the signal to the thread to which the
signal applies - Deliver the signal to every thread in the process
- Deliver the signal to certain threads in the
process - Assign a specific thread to receive all signals
for the process
33Thread Pools
- A server process might service requests by
creating a thread for each request that needs
servicing - But thread creation costs are wasted time
- No control over the number of threads, possibly
overwhelming the system - Solution
- Create a number of threads in a pool where they
await work - Advantages
- The overhead for creating threads is paid only at
the beginning - Allows the number of threads in the
application(s) to be bound to the size of the pool
34Thread Specific Data
- Allows each thread to have its own copy of data
- Useful when you do not have control over the
thread creation process (i.e., when using a
thread pool)
35Scheduler Activations
- Both MM and Two-level models require
communication from the kernel to inform the
thread library when a user thread is about to
block, and when it again becomes ready for
execution - When such event occurs, the kernel makes an
upcall to the thread library - The thread librarys upcall handler handles the
event (i.e. save the user threads state and mark
it as blocked)
36Chapter 4 Threads
- Overview
- Multithreading Models
- Threading Issues
- Specific thread libraries
- Pthreads
- Win32
- Java threads
- Thread implementations
- Windows XP
- Linux
- Java
37Pthreads
- A POSIX standard (IEEE 1003.1c) API for thread
creation and synchronization - API specifies behavior of the thread library,
implementation is up to the developer of the
library - Common in UNIX operating systems (Solaris, Linux,
Mac OS X) - Typical functions
- pthread_create (thread, attr, start_routine, arg)
- pthread_exit (status)
- pthread_join (threadid, status)
- pthread_attr_init (attr)
38Thread Programming Exercise
Goal Write multithreaded matrix multiplication
algorithm, in order to make use of several
CPUs. Single threaded algorithm for multiplying
n x n matrices A and B for(i0 iltn
i) for(j0 jltn j) Ci,j 0 for(k0
kltn k) Ci,j Ai,k Bk,j Just to
make our life easier Assume you have 6 CPUs and
n is multiple of 6. How to start? Any ideas?
39Multithreaded Matrix Multiplication
- Idea
- create 6 threads
- have each thread compute 1/6 of the matrix C
- wait until everybody finished
- the matrix can be used now
40Lets go!
pthread_t tid6 pthread_attr_t
attr int i pthread_init_attr(attr) for(i0
ilt6 i) / create the working threads
/ pthread_create( tidi, attr, worker,
i) for(i0 ilt6 i) / now wait until
everybody finishes / pthread_join(tidi,
NULL) / the matrix C can be used now /
41Lets go!
void worker(void param) int i,j,k int id
((int ) param) / take param to be pointer to
integer / int low idn/6 int high
(id1)n/6 for(ilow ilthigh i) for(j0
jltn j) Ci,j 0 for(k0 kltn k) Ci,j
Ai,kBk,j pthread_exit(0)
42Lets go!
- Would it work?
- do we need to pass A,B,C and n in the
parameters? - no, they are in the shared memory, we are fine
- did we pass IDs properly?
- not really, all threads get the same pointer
for(i0 ilt6 i) / create the working
threads / idi i pthread_create( tidi,
attr, worker, idi)
- Would it work now?
- should,
43Win32 Thread API
- // thread creation
- ThreadHandle CreateThread(
- NULL, // default security attributes
- 0, // default stack size
- Summation, // function to execute
- Param, // parameter to thread function
- 0, // default creation flags
- ThreadId) // returns the thread ID
- Simple programming example
44Java Threads
- Java threads are created by calling a start()
method of a class that - extends Thread class, or
- implements the Runnable interface
- public interface Runnable
-
- public abstract void run()
-
- Java threads are inherent and important part of
the Java language, with rich API available
45Extending the Thread Class
- class Worker1 extends Thread
-
- public void run()
- System.out.println("I Am a Worker Thread")
-
-
- public class First
-
- public static void main(String args)
- Worker1 runner new Worker1()
- runner.start()
- System.out.println("I Am The Main Thread")
-
46Implementing the Runnable Interface
- class Worker2 implements Runnable
-
- public void run()
- System.out.println("I Am a Worker Thread
") -
-
- public class Second
-
- public static void main(String args)
- Runnable runner new Worker2()
- Thread thrd new Thread(runner)
- thrd.start()
- System.out.println("I Am The Main Thread")
-
47Joining Threads
class JoinableWorker implements Runnable
public void run()
System.out.println("Worker working")
public class JoinExample public static
void main(String args) Thread task
new Thread(new JoinableWorker())
task.start() try task.join()
catch (InterruptedException ie)
System.out.println("Worker
done")
48Thread Cancellation
Thread thrd new Thread (new InterruptibleThread(
)) thrd.start() . . . // now interrupt
it thrd.interrupt()
49Thread Cancellation
public class InterruptibleThread implements
Runnable public void run() while
(true) / do some work
for awhile / if
(Thread.currentThread().isInterrupted())
System.out.println("I'm interrupted!")
break // clean
up and terminate
50Thread Specific Data
class Service private static ThreadLocal
errorCode new ThreadLocal() public static
void transaction() try /
some operation where an error may occur
/ catch
(Exception e) errorCode.set(e)
/ get the error code for this
transaction / public static Object
getErrorCode() return errorCode.get()
51Thread Specific Data
class Worker implements Runnable private
static Service provider public void run()
provider.transaction()
System.out.println(provider.getErrorCode())
Somewhere in the code Worker worker1
new Worker() Worker worker2 new
Worker() worker1.start() worker2.start() Ass
ume there were different errors in the
transactions of both workers, but both
transactions finished before any of the prints in
the run() methods started. Would the workers
print the same errors or not?
52Chapter 4 Threads
- Overview
- Multithreading Models
- Threading Issues
- Specific thread libraries
- Pthreads
- Win32
- Java threads
- Thread implementations
- Windows XP
- Linux
- Java
53Windows XP Threads
- Implements the one-to-one mapping
- Each thread contains
- A thread id
- Register set
- Separate user and kernel stacks
- Private data storage area
- The register set, stacks, and private storage
area are known as the context of the threads - The primary data structures of a thread include
- ETHREAD (executive thread block)
- KTHREAD (kernel thread block)
- TEB (thread environment block)
54Windows XP Threads
55Linux Threads
- Linux refers to them as tasks rather than threads
- Thread creation is done through clone() system
call - The clone() system call allows to specify which
resources are shared between the child and the
parent - Full sharing ? threads
- Little sharing ? like fork()
56Java Threads
Java threads are managed by the JVM
57Chapter 4 Threads
- Overview
- Multithreading Models
- Threading Issues
- Specific thread libraries
- Pthreads
- Win32
- Java threads
- Thread implementations
- Windows XP
- Linux
- Java
- More threads examples and exercises
58Understanding threads
Take a look at this program. What would be its
output? Why?
59End of Chapter 4