Top Banner
Parallelism in C++ Lecture 2 [email protected] 9/26/2019 Parallel Programming in C++ (Lecture 1) Hartmut Kaiser 1
24

Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 [email protected] 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Aug 17, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Parallelism in C++Lecture 2

[email protected]

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

1

Page 2: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

The Future of Computation

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

2

Page 3: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

What is a (the) Future?• Many ways to get hold of a (the) future, simplest way is to use (std) async:

int universal_answer() { return 42; }

void deep_thought(){

future<int> promised_answer = async(&universal_answer);

// do other things for 7.5 million years

cout << promised_answer.get() << endl; // prints 42}

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

3

Page 4: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

What is a (the) future• A future is an object representing a result which has not been calculated yet

Locality 1

Suspend consumerthread

Execute another thread

Resume consumerthread

Locality 2

Execute Future:

Producer thread

Future object

Result is being returned

Enables transparent synchronization with producer

Hides notion of dealing with threads

Represents a data-dependency

Makes asynchrony manageable

Allows for composition of several asynchronous operations

(Turns concurrency into parallelism)

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

4

Page 5: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Ways to Create a future

•Standard defines 3 possible ways to create a future, 3 different ‘asynchronous providers’

std::async

std::packaged_task

std::promise

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

5

Page 6: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Promising a Future• std::promise is main ‘producer’ of futures

It gives away a future representing the value it received

Promise/future is a one-shot pipeline where the promise is the ‘sender’ and the future is the ‘receiver’

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

6

Page 7: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Promising a Future

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

7

template <typename F, typename... Args>

std::future<typename std::result_of<F(Args...)>::type>

simple_async(F f, Args... args)

{

using result_type = typename std::result_of<F(Args...)>::type;

std::promise<result_type> p;

std::future<result_type> f = p.get_future();

std::thread t([=]() { p.set_value(f(args...)); }); // note: simplified!

t.detach(); // detach the thread from this object

return f;

}

Page 8: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Packaging a Future• std::packaged_task is a function object

It gives away a future representing the result of its invocation

• Can be used as a synchronization primitive

Pass to std::thread

• Converting a callback into a future

Observer pattern, allows to wait for a callback to happen

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

8

Page 9: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Packaging a Future

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

9

template <typename F, typename... Args>

std::future<typename std::result_of<F(Args...)>::type>

simple_async(F f, Args... args)

{

std::packaged_task<F> pt(f);

auto f = pt.get_future();

std::thread t(pt, args...); // note: simplified!

t.detach(); // detach the thread from this object

return f;

}

Page 10: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Promising a Future• std::promise is also an asynchronous provider ("an object

that provides a result to a shared state") The promise is the thing that you set a result on, so that you can

get it from the associated future.

The promise initially creates the shared state

The future created by the promise shares the state with it

The shared state stores the value

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

10

Page 11: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Promising a Futuretemplate <typename F> class simple_packaged_task;

template <typename R, typename... Args>class simple_packaged_task<R(Args...)> // must be move-only{

std::function<R(Args...)> fn;std::promise<R> p; // the promise for the result

public: template <typename F>explicit simple_packaged_task(F f) : (f) {}

void operator()(Args... args) { p.set_value(fn(args...)); }

std::future<R> get_future() { return p.get_future(); }};

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

11

Page 12: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Extending std::future

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

12

Page 13: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Extending std::future

• Several proposals for next C++ Standard, also HPX Extension for std::future

Compositional facilities

Parallel composition

Sequential composition

Parallel Algorithms

Parallel Task Regions

Extended async semantics: dataflow

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

13

Page 14: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Make a ready Future• Create a future which is ready at construction (N3857)

future<int> compute(int x)

{

if (x < 0) return make_ready_future(-1);

if (x == 0) return make_ready_future(0);

return async(

[](int param) { return do_work(param); },

x);

}

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

14

Page 15: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Compositional facilities• Sequential composition of futures

string make_string()

{

future<int> f1 = async([]() -> int { return 123; });

future<string> f2 = f1.then(

[](future<int> f) -> string {

return to_string(f.get()); // here .get() won’t block

});

}

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

15

Page 16: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Compositional facilities• Parallel composition of futures

void test_when_all()

{

shared_future<int> shared_future1 = async([]() -> int { return 125; });

future<string> future2 = async([]() -> string { return string("hi"); });

future<tuple<shared_future<int>, future<string>>> all_f =

when_all(shared_future1, future2); // also: when_any, when_some, etc.

future<int> result = all_f.then(

[](auto f) -> int {

return do_work(f.get());

});

}

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

16

Page 17: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Parallel Algorithms (C++17)

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

17

Page 18: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Parallel Algorithms (C++17)• Add Execution Policy as first argument

• Execution policies have associated default executor and default executor parameters

execution::parallel_policy, generated with par

parallel executor, static chunk size

execution::sequenced_policy, generated with seq

sequential executor, no chunking

// add execution policystd::fill(

std::execution::par, begin(d), end(d), 0.0);

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

18

Page 19: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Parallel Algorithms (Extensions)

// uses default executor: par

std::vector<double> d = { ... };

fill(execution::par, begin(d), end(d), 0.0);

// rebind par to user-defined executor (where and how to execute)

my_executor my_exec = ...;

fill(execution::par.on(my_exec), begin(d), end(d), 0.0);

// rebind par to user-defined executor and user defined executor

// parameters (affinities, chunking, scheduling, etc.)

my_params my_par = ...

fill(execution::par.on(my_exec).with(my_par), begin(d), end(d), 0.0);

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

19

Page 20: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Execution Policies (Extensions)• Extensions: asynchronous execution policies

parallel_task_execution_policy (asynchronous version of parallel_execution_policy), generated with par(task)

sequenced_task_execution_policy (asynchronous version of sequenced_execution_policy), generated with seq(task)

In all cases the formerly synchronous functions return a future<>

Instruct the parallel construct to be executed asynchronously

Allows integration with asynchronous control flow

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

20

Page 21: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Extending Parallel Algorithms

12/6

/2014

Hart

mu

t K

ais

er:

Pla

in T

hre

ad

s are

th

e G

OT

O o

f

Tod

ay's

Com

pu

tin

g

21Sean Parent: C++ Seasoning, Going Native 2013

Page 22: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Extending Parallel Algorithms• New algorithm: gather

template <typename BiIter, typename Pred>

pair<BiIter, BiIter> gather(BiIter f, BiIter l, BiIter p, Pred pred)

{

BiIter it1 = stable_partition(f, p, not1(pred));

BiIter it2 = stable_partition(p, l, pred);

return make_pair(it1, it2);

}

12/6

/2014

Hart

mu

t K

ais

er:

Pla

in T

hre

ad

s are

th

e G

OT

O o

f

Tod

ay's

Com

pu

tin

g

22Sean Parent: C++ Seasoning, Going Native 2013

Page 23: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

Extending Parallel Algorithms• New algorithm: gather_async

template <typename BiIter, typename Pred>

future<pair<BiIter, BiIter>> gather_async(BiIter f, BiIter l, BiIter p, Pred pred)

{

future<BiIter> f1 = stable_partition(par(task), f, p, not1(pred));

future<BiIter> f2 = stable_partition(par(task), p, l, pred);

return dataflow(

unwrapped([](BiIter r1, BiIter r2) { return make_pair(r1, r2); }),

f1, f2);

}

12/6

/2014

Hart

mu

t K

ais

er:

Pla

in T

hre

ad

s are

th

e G

OT

O o

f

Tod

ay's

Com

pu

tin

g

23

Page 24: Parallelism in C++pdiehl/teaching/2019/4977... · Parallelism in C++ Lecture 2 hkaiser@cct.lsu.edu 9 er 1. The Future of Computation 9 er 2. What is a (the) Future? ... Locality 1

9/2

6/2

019

Para

llel

Pro

gra

mm

ing in

C+

+ (

Lect

ure

1)

Hart

mu

t K

ais

er

24