Anda di halaman 1dari 28

Threads in C++

Gabor Czilli
University of Erlangen-Nuremberg - Advanced C++ Seminar

July 11, 2011

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

1 / 26

Table of Contents
1 2

Introduction & Motivation Pthreads (Posix Threads) Pthread example Boost Threads Thread Management Synchronization Thread Pool OpenMP Thread Management Synchronization Boost vs. OpenMP Summary / Conclusion
Threads in C++ July 11, 2011 2 / 26

5 6

Gabor Czilli (CS Masters Student)

Introduction & Motivation


Why everyone wants Threads

Processors do not get (much) faster anymore But the number of processing units increase on a single chip (2,4,8,16 core machines) As well as the number of simultaneous operations per clock cycle We need to solve bigger and bigger problems In reasonable execution times

So...
Computational work has to be done in parallel, to take advantage of modern processors

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

3 / 26

Topics
Topics covered by this presentation

How to use shared memory parallelism on CPUs in C++ Pthreads (posix threads) Boost::thread, related classes and functions OpenMP (Open Multi-Processing) Boost vs. OpenMP performance comparison This presentation will not cover basics about threads and related problems (deadlocks, race conditions, critical sections, ...) But feel free to ask anything

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

4 / 26

Pthreads
Posix Threads

Posix: Portable Operating System Interface for Unix Standard API for Unix systems not available on Windows C thread library
i n t pthread create ( pthread t t , const p t h r e a d a t t r t attr , void ( s t a r t r o u t i n e ) ( v o i d ) , v o i d arg ) ; i n t p t h r e a d j o i n ( p t h r e a d t t , v o i d r e t v a l ) ; i n t p t h r e a d m u t e x i n i t ( p t h r e a d m u t e x t mutex , c o n s t pthread mutexattr t attr ) ; i n t p t h r e a d m u t e x d e s t r o y ( p t h r e a d m u t e x t mutex ) ; i n t p t h r e a d m u t e x l o c k ( p t h r e a d m u t e x t mutex ) ; // and same u n l o c k function

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

5 / 26

Pthreads
Example

// l i n k w i t h p t h r e a d #i n c l u d e <p t h r e a d . h> #i n c l u d e <i o s t r e a m > #d e f i n e NTHREADS 4 s t a t i c p t h r e a d m u t e x t mutex1 ; i n t main ( ) { p t h r e a d m u t e x i n i t (&mutex1 , 0 ) ; p t h r e a d t t h r e a d [ NTHREADS ] ; for ( int i = 0 ; i < NTHREADS ; ++i ) p t h r e a d c r e a t e ( t h r e a d + i , 0 , t h r e a d s t a r t , ( v o i d ) i ) ; i = 0 ; i < NTHREADS ; ++i ) p t h r e a d j o i n ( thread [ i ] , 0) ;

for ( int

p t h r e a d m u t e x d e s t r o y (&mutex1 ) ; return 0; }

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

6 / 26

Pthreads
Example

s t a t i c void t h r e a d s t a r t ( void arg ) { i n t index = ( i n t ) arg ; p t h r e a d m u t e x l o c k (&mutex1 ) ; s t d : : c o u t << H e l l o from t h r e a d << i n d e x << s t d : : e n d l ; p t h r e a d m u t e x u n l o c k (&mutex1 ) ; return 0; }

Hello Hello Hello Hello

from from from from

thread thread thread thread

1 2 0 3

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

7 / 26

Boost Threads
General

Part of the next C++ standard Portable threading library (all systems boost supports) Uses e.g. pthreads in Linux and Windows-Threads in Windows C++ API with support for RAII

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

8 / 26

Boost Threads
Thread Management
c l a s s boost : : thread ;

For launching and managing threads Constructor takes class with function call operator
member f u n c t i o n b o o s t : : t h r e a d : : j o i n ( )

Wait for thread to nish execution


boost : : t h i s t h r e a d : : g e t i d ()

Non-member function, returns unique id representing the currently executing thread


#i n c l u d e <b o o s t / t h r e a d . hpp> s t r u c t MyThread { void operator () () { // new t h r e a d s s t a r t h e r e } }; i n t main ( ) { b o o s t : : t h r e a d t h r e a d ( MyThread ( ) ) ; thread . j o i n () ; return 0; } Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

9 / 26

Boost Threads
Synchronization

c l a s s b o o s t : : mutex ;

Implements Lockable interface ( for lock(), unlock(), try lock()) Should be used with a boost::lock for RAII resource management
c l a s s boost : : lock guard ;

Calls lock() in its constructor and unlock in destructor


c l a s s boost : : unique lock ;

Constructor can wait for locking or try to lock, when additionally passing boost::try to lock functions: owns lock, timed lock, unlock, release more exible
c l a s s boost : : shared lock ;

Used when only read access is needed for a thread Underlying mutex can be shared e.g. with a unique lock
Gabor Czilli (CS Masters Student) Threads in C++ July 11, 2011 10 / 26

Boost Threads
Synchronization example
#i n c l u d e <b o o s t / t h r e a d . hpp> s t a t i c b o o s t : : s h a r e d m u t e x mutex ; s t a t i c void read () { b o o s t : : s h a r e d l o c k <b o o s t : : s h a r e d m u t e x > l o c k ( mutex ) ; // do r e a d o n l y o p e r a t i o n s h e r e i n p a r a l l e l } s t a t i c void write () { b o o s t : : u n i q u e l o c k <b o o s t : : s h a r e d m u t e x > l o c k ( mutex ) ; // do w r i t e o p e r a t i o n s h e r e } i n t main ( ) { boost boost boost boost

:: :: :: ::

thread thread thread thread . . . . join join join join () () () ()

thread1 ( read ) ; thread2 ( read ) ; thread3 ( read ) ; thread4 ( write ) ; ; ; ; ;

thread1 thread2 thread3 thread4

return 0; }

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

11 / 26

Boost Threads
Synchronization
boost : : lock ( Lockable1 , Lockable2 , b o o s t : : l o c k ( b e g i n , end ) ...) ,

Non-member functions, acquire multiple locks in a way that avoids deadlocks


c l a s s boost : : b a r r i e r ; boost : : b a r r i e r : : wait () ;

Barriers are created for n threads, as threads reach the barrier (call wait()) they must wait until all n threads have arrived.
c l a s s boost : : c o n d i t i o n v a r i a b l e ; boost : : c o n d i t i o n v a r i a b l e : : wait ( lock ) , notify one , notify all ;

Provide a mechanism for one thread to wait for notication from another thread. Atomically unlocks the lock and starts sleeping.
Gabor Czilli (CS Masters Student) Threads in C++ July 11, 2011 12 / 26

Boost Threads
Synchronization

b o o s t : : c o n d i t i o n v a r i a b l e cond ; b o o s t : : mutex mutex ; v o l a t i l e bool data ready ; void create data () { // . . . data ready = true ; cond . n o t i f y o n e ( ) ; // . . . } void wait for data to process () { // . . . b o o s t : : u n i q u e l o c k <b o o s t : : mutex> l o c k ( mutex ) ; w h i l e ( ! d a t a r e a d y ) { // mutex i s l o c k e d h e r e cond . w a i t ( l o c k ) ; // a t o m i c a l l y w a i t and u n l o c k // mutex l o c k e d a g a i n } process data () ; // . . . }

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

13 / 26

Boost Threads
Thread Pool

Concept of a thread pool

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

14 / 26

Boost Threads
Thread Pool

Concept of a thread pool

There is no implementation of a thread pool in Boost, but a very good implementation based on Boost (http://threadpool.sourceforge.net)

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

14 / 26

OpenMP
General

API for multi-threaded, shared memory parallelism Based on compiler support makes heavy use of compiler directives (#pragma omp) Portable to all platforms with supporting compilers, even when compiler ignores directives (among others: Intel-, Microsoft-, GNU-, IBM- and Cray-Compilers) Number of threads determined by: enviroment variable, explicit function call or automatically by the number of processors (at runtime) Higher level multithreaded programming

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

15 / 26

OpenMP
Example

Matrix-Matrix multiplication:
for ( int i = 0 ; i < n ; ++i ) f o r ( i n t k = 0 ; k < n ; ++k ) f o r ( i n t j = 0 ; j < n ; ++j ) o u t [ i n+j ] += a [ i n+k ] b [ k n+j ] ;

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

16 / 26

OpenMP
Example

Matrix-Matrix multiplication:
for ( int i = 0 ; i < n ; ++i ) f o r ( i n t k = 0 ; k < n ; ++k ) f o r ( i n t j = 0 ; j < n ; ++j ) o u t [ i n+j ] += a [ i n+k ] b [ k n+j ] ;

Parallel with OpenMp:


#i n c l u d e <omp . h> // . . . #pragma omp p a r a l l e l f o r f o r ( i n t i = 0 ; i < n ; ++i ) f o r ( i n t k = 0 ; k < n ; ++k ) f o r ( i n t j = 0 ; j < n ; ++j ) o u t [ i n+j ] += a [ i n+k ] b [ k n+j ] ; // . . .

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

16 / 26

OpenMP
Management Directives

#pragma omp p a r a l l e l { / b l o c k / }

Start team of threads, execute the block in parallel, join threads at the end
#pragma omp f o r { / b l o c k / }

Partition loop iterations, to be executed in parallel


#pragma omp s e c t i o n s { #pragma omp s e c t i o n { / b l o c k / } #pragma omp s e c t i o n { / b l o c k / } }

Execute sections in parallel, each section once, by one thread


Gabor Czilli (CS Masters Student) Threads in C++ July 11, 2011 17 / 26

OpenMP
Synchronization Directives

#pragma omp c r i t i c a l ( name ) { / b l o c k / }

Critical section, cannot be executed in parallel, identied by name


#pragma omp b a r r i e r

A thread will wait at the barrier until all other threads have reached this point Data scope attributes:
shared ( l i s t ) private ( l i s t )

Declare data to be shared between threads, or to give each thread a local copy

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

18 / 26

Boost vs. OpenMP


Performance comparison

On Linux, Boost is implemented with the help of pthreads . . . OpenMP too Performance comparison:
How well do the implementations scale on a calculation intensive problem? (like matrix multiplication) Synchronization is often unaviodable, which locking mechanisms are implemented more eciently? (when facing high lock contention)

Problem 1: multithreaded calculation of a matrix-matrix multiplication Problem 2: like problem 1, but locking a critical section in each iteration of the second loop Hardware: 4x Intel Xeon CPU E7340 @ 2.40GHz server 16 cores, 32GB RAM Software: g++ 4.4.5, options: -O3 -march=native -mtune=native -mfpmath=sse Boost version 1.42 (no change since 1.41)
Gabor Czilli (CS Masters Student) Threads in C++ July 11, 2011 19 / 26

Boost vs. OpenMP


Results Problem 1

300

OpenMP Boost Single threaded

250

200 time in ms

150

100

50

0 0 100 200 300 matrix size 400 500 600

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

20 / 26

Boost vs. OpenMP


Results Problem 1

30

OpenMP Boost

25

20 time in ms

15

10

0 0 100 200 300 matrix size 400 500 600

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

21 / 26

Boost vs. OpenMP


Results Problem 2

400

OpenMP Boost Single threaded

350

300

250 time in ms

200

150

100

50

0 0 100 200 300 matrix size 400 500 600

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

22 / 26

Boost vs. OpenMP


Results Problem 2, threads: 4

300

OpenMP Boost Single threaded

250

200 time in ms

150

100

50

0 0 100 200 300 matrix size 400 500 600

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

23 / 26

Summary / Conclusion
Pthreads:
low level, medium portable interface can be of high performance but a lot of manual resource management needed therefore error-prone

Boost threads
medium level, highly portable interface medium performance, when locking RAII style management of resources still full exibility

OpenMP
high level, highly portable interface high perfomance, if it ts to your application completely dierent approach to multithreading does not save the programmer from thinking about deadlocks, race conditions, synchronization and ecient parallel algorithms
Gabor Czilli (CS Masters Student) Threads in C++ July 11, 2011 24 / 26

Boost. Boost C++ Libraries, July 2011. http://www.boost.org. Boost. Boost C++ Libraries, July 2011. http: //www.boost.org/doc/libs/1_46_1/doc/html/thread.html. OpenMP. Open Multi-Processing, July 2011. http://openmp.org. OpenMP. Open Multi-Processing, July 2011. https://computing.llnl.gov/tutorials/openMP.

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

25 / 26

Thank you for your attention. Questions?

Gabor Czilli (CS Masters Student)

Threads in C++

July 11, 2011

26 / 26