21
Threads Tutorial #7 CPSC 261

Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Embed Size (px)

Citation preview

Page 1: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Threads

Tutorial #7CPSC 261

Page 2: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

A thread is a virtual processor

• Each thread is provided the illusion that it owns a core– Copy of the registers– It is running all the time

• In fact, all of the threads share the hardware cores– The operating system rapidly switches the cores

among the threads that want to run, providing this illusion that each thread owns a core

Page 3: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

POSIX standard: pthreads

• Threads are created via pthread_create()• A thread dies when it:– returns from the function given to pthread_create– or calls pthread_exit()

• You can wait for a thread to complete via pthread_join()

Page 4: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Visualizing thread execution

pthread_create()

pthread_join()

main thread

child threads

Page 5: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

PingPong.cvoid *p(void *arg) { long i; for (i = 0; i < LIMIT; ++i) {

counter = counter + 1; } return 0;}void main(...) { pthread_create(&t1, NULL, &p, "ping”); pthread_create(&t2, NULL, &p, "pong”); pthread_join(t1, NULL); pthread_join(t2, NULL);}

Page 6: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Questions you might ask

• What if t2 finishes before t1?– It will just wait as long as necessary for the main

thread to join with it• How many threads can I create?– It depends. On Linux a few 10s of thousands

Page 7: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

The big thing that goes wrong

• Uncontrolled access to memory– race condition– with multiple writers of a single shared variable,

updates can get lost• Fixed by:– single writers– locks

Page 8: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Before-and-after atomicity

• Sometimes you need an arbitrary sequence of operations to be atomic

• A sequence of operations that needs to be atomic is also called a critical section

• Mutual exclusion means only one thread at a time (one thread in the critical section excludes all others)

Page 9: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Achieving mutual exclusion

• In pthreads, mutual exclusion is provided by mutex objects– created as all other objects (malloc)– initialized by pthread_mutex_init()– acquired by pthread_mutex_lock()– released by pthread_mutex_unlock()

Page 10: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

The lock idiom

• Every critical section is protected by a mutex• The code looks like:

pthread_mutex_lock(&lock);// critical sectionpthread_mutex_unlock(&lock);

Page 11: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Locking PingPongvoid *p(void *arg) { long i; for (i = 0; i < LIMIT; ++i) { pthread_mutex_lock(&lock); // Once the lock is held, this // “critical section” can be as long // as you need or want it to be counter = counter + 1; pthread_mutex_unlock(&lock); } return 0;}

Page 12: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Multiple critical sections

• If there are multiple critical sections that access the same shared data– They need to be protected by the same lock

Page 13: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Multiple critical section idiom

pthread_mutex_lock (&lock);// critical section// for thread 1pthread_mutex_unlock (&lock);

pthread_mutex_lock (&lock);// critical section// for thread 2pthread_mutex_unlock (&lock);

Page 14: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Locking issues

• Fine-grained locks– more parallelism– more overhead– more complexity

• Coarse-grained locks– less parallelism– less overhead– simpler

• Deadlock

Page 15: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Sample thread code

• Lots of examples in the threads directory of the lectures repository

Page 16: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Using threads for speedup

Cores used

Speedup

perfect speedup45o line

Page 17: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Things to think about

• Each core has its own cache• The L3 cache is shared between all the cores• If you have 8 cores, how many “pieces of

work” should you create?– 8?– <8?– >8?

Page 18: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

More things to think about

• What if the “pieces of work” aren’t all the same size?

• Or what if one thread is slower than the other threads?– Why could this be?• Randomness• Interference with other activity on the machine

– These slow threads are called “stragglers” and are a real problem in practice

Page 19: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

The ideal case – all threads finish at the same time

Page 20: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

What might happen

Page 21: Threads Tutorial #7 CPSC 261. A thread is a virtual processor Each thread is provided the illusion that it owns a core – Copy of the registers – It is

Even more things to think about

• Suppose I have 8 cores.• Should I create 8 threads – one for each core• Or more than 8 threads to deal with

“stragglers”• Or ...