• Keine Ergebnisse gefunden

CAF – A Short Introduction

N/A
N/A
Protected

Academic year: 2022

Aktie "CAF – A Short Introduction"

Copied!
55
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

.

.

CAF – A Short Introduction

Dominik Charousset

dominik.charousset@haw-hamburg.de

iNET RG, Department of Computer Science Hamburg University of Applied Sciences

October 2014

(2)

The Problem With Implicit Sharing

When writing concurrent programs:

Stateful objects need to be synchronized (if shared) Developer is responsible for thread-safety

Challenges are ...

Race conditions (“solved” by locks) Deadlocks/Lifelocks (caused by locks)

Poor scalability due to queueing (Coarse-Grained Locking) Very high complexity (Fine-Grained Locking)

Time-dependent errors make testing (almost) impossible

⇒ Expert knowledge & experience required

(3)

The Problem With Implicit Sharing

When writing concurrent programs:

Stateful objects need to be synchronized (if shared) Developer is responsible for thread-safety

Challenges are ...

Race conditions (“solved” by locks) Deadlocks/Lifelocks (caused by locks)

Poor scalability due to queueing (Coarse-Grained Locking) Very high complexity (Fine-Grained Locking)

Time-dependent errors make testing (almost) impossible

⇒ Expert knowledge & experience required

Dominik Charousset iNET – HAW Hamburg 2

(4)

Compose Synchronized Classes

class Subject { public:

void subscribe( function <void(int)> fun ) { unique_lock<mutex > guard{ m_mtx };

m_subscribers . push_back ( move ( fun ));

}

void broadcast(int value ) {

unique_lock<mutex > guard{ m_mtx };

for (auto& s : m_subscribers ) s( value );

}

private: mutex m_mtx ;

vector < function <void(int)>> m_subscribers ; };

(5)

Compose Synchronized Classes

class FooBar { public:

void foo( Subject * s) {

unique_lock<mutex > guard{ m_mtx };

m_subjects . push_back (s );

s ->subscribe([=](int v) { /* ... */ bar (v); /* ... */

});

// ...

}

void bar(int value ) {

unique_lock<mutex > guard{ m_mtx };

// ...

}

private:

vector < Subject *> m_subjects ; mutex m_mtx ;

};

Dominik Charousset iNET – HAW Hamburg 4

(6)

Compose Synchronized Classes

Thread1 Thread2

Subject s

FooBar fb

(7)

Compose Synchronized Classes

Thread1 Thread2

Subject s

FooBar fb Functor

f subscribe(f)

[](int val) { ....

fb.bar();

....

}

Dominik Charousset iNET – HAW Hamburg 5

(8)

Compose Synchronized Classes

Thread1 Thread2

FooBar fb Functor

f

broadcast(42)

foo()

operator()(42) Subject

s

(9)

Compose Synchronized Classes

Thread1 Thread2

Functor f

broadcast(42)

foo()

operator()(42)

bar()

subscribe(...)

Subject s

FooBar fb

Dominik Charousset iNET – HAW Hamburg 5

(10)

Locks Are Not Composable

“Mutable, stateful objects are the new spaghetti code.”

– Rich Hickey

Libraries with threads & locks are no longer black boxes Composition of two thread-safe classes can deadlock User has to know about implementation details:

Which code runs asynchronously/where?

Which functions are “thread-safe”?

Which function uses which lock?

⇒ Abstraction of OO programming unfolds

(11)

Locks Are Not Composable

“Mutable, stateful objects are the new spaghetti code.”

– Rich Hickey

Libraries with threads & locks are no longer black boxes Composition of two thread-safe classes can deadlock User has to know about implementation details:

Which code runs asynchronously/where?

Which functions are “thread-safe”?

Which function uses which lock?

⇒ Abstraction of OO programming unfolds

Dominik Charousset iNET – HAW Hamburg 6

(12)

Locks Are Not Composable

“Mutable, stateful objects are the new spaghetti code.”

– Rich Hickey

Libraries with threads & locks are no longer black boxes Composition of two thread-safe classes can deadlock User has to know about implementation details:

Which code runs asynchronously/where?

Which functions are “thread-safe”?

Which function uses which lock?

⇒ Abstraction of OO programming unfolds

(13)

The Actor Model

Actors are concurrent entities, that ...

Communicate via message passing Do not share state

Can create (“spawn”) more actors Can monitor other actors

Dominik Charousset iNET – HAW Hamburg 7

(14)

The Actor Model – Programming Model

case 1 input: M pattern 1 matched M

case 2 pattern 2 matched M

else

receive next message

case N pattern N matched M

else else

Actor Programmingis Message-Oriented Programming Actors are activeobjects

No direct method invocation, only messages Messages passinghideslocation of receiver

Receiver pattern matches on content of incoming messages

(15)

The Actor Model – Linking of Actors

alice

exit message

(non-normal exit reason)

link

bob

quit()

Dominik Charousset iNET – HAW Hamburg 9

(16)

The Actor Model – Linking of Actors

alice

exit message

(non-normal exit reason)

link bob

quit()

Actors canlink their lifetime

Errors are propagated through exit messages When receiving an exit message:

Actors fail for the same reason per default

Actors cantrapexit messages to handle failure manually

Build systems where all actors are alive or have collectively failed

(17)

The Actor Model – Linking of Actors

Trapping exit messages enables:

Notification on success (normal exit reason)

Report errors back to client (non-normal exit reason) Re-deployment of workers on (hardware) node failure Supervisingspawned workers

Dominik Charousset iNET – HAW Hamburg 10

(18)

Benefits of the Actor Model

High-level, explicit communication between SW components Robust software design: No locks, no implicit sharing High level of abstraction for developing software Abstraction over deployment

Flexible & modular systems

Managing heterogeneous environments (but not yet on HW level) Applies to both concurrencyand distribution

Divide workload by spawning actors Network-transparent messaging Provides strong failure semantics

Hierarchical error management Re-deployment at runtime

(19)

Benefits of the Actor Model

High-level, explicit communication between SW components Robust software design: No locks, no implicit sharing High level of abstraction for developing software Abstraction over deployment

Flexible & modular systems

Managing heterogeneous environments (but not yet on HW level) Applies to both concurrencyand distribution

Divide workload by spawning actors Network-transparent messaging Provides strong failure semantics

Hierarchical error management Re-deployment at runtime

Dominik Charousset iNET – HAW Hamburg 11

(20)

Benefits of the Actor Model

High-level, explicit communication between SW components Robust software design: No locks, no implicit sharing High level of abstraction for developing software Abstraction over deployment

Flexible & modular systems

Managing heterogeneous environments (but not yet on HW level) Applies to both concurrencyand distribution

Divide workload by spawning actors Network-transparent messaging Provides strong failure semantics

Hierarchical error management Re-deployment at runtime

(21)

Benefits of the Actor Model

High-level, explicit communication between SW components Robust software design: No locks, no implicit sharing High level of abstraction for developing software Abstraction over deployment

Flexible & modular systems

Managing heterogeneous environments (but not yet on HW level) Applies to both concurrencyand distribution

Divide workload by spawning actors Network-transparent messaging Provides strong failure semantics

Hierarchical error management Re-deployment at runtime

Dominik Charousset iNET – HAW Hamburg 11

(22)

CAF – Actors in C++11

CAF is an actor system based on C++11 Efficient program execution

Low memory footprint

Fast, lock-free mailbox implementation

Targets both low-end and high-performance computing Embedded HW

Multi-core systems

Uses internal DSL for pattern matching of messages

(23)

CAF – Actors in C++11

CAF is an actor system based on C++11 Efficient program execution

Low memory footprint

Fast, lock-free mailbox implementation

Targets both low-end and high-performance computing Embedded HW

Multi-core systems

Uses internal DSL for pattern matching of messages

Dominik Charousset iNET – HAW Hamburg 12

(24)

CAF – Actors in C++11

CAF is an actor system based on C++11 Efficient program execution

Low memory footprint

Fast, lock-free mailbox implementation

Targets both low-end and high-performance computing Embedded HW

Multi-core systems

Uses internal DSL for pattern matching of messages

(25)

CAF – Actors in C++11

CAF is an actor system based on C++11 Efficient program execution

Low memory footprint

Fast, lock-free mailbox implementation

Targets both low-end and high-performance computing Embedded HW

Multi-core systems

Uses internal DSL for pattern matching of messages

Dominik Charousset iNET – HAW Hamburg 12

(26)

CAF Core Architecture

Type System

1/8

(27)

CAF Core Architecture

Type System

Pattern Matching Engine Serialization Layer

2/8

Dominik Charousset iNET – HAW Hamburg 13

(28)

CAF Core Architecture

Type System

Pattern Matching Engine Serialization Layer

Middleman

Cooperative Scheduler OpenCL Binding

3/8

(29)

CAF Core Architecture

Type System

Pattern Matching Engine Serialization Layer

Middleman

Cooperative Scheduler OpenCL Binding

Proxy Actor

Local (CPU) Actor OpenCL Actor Facade

4/8

Dominik Charousset iNET – HAW Hamburg 13

(30)

CAF Core Architecture

Type System

Pattern Matching Engine Serialization Layer

Middleman

Message Passing Layer

Proxy Actor

Local (CPU) Actor

Cooperative Scheduler OpenCL Actor Facade

OpenCL Binding

5/8

(31)

CAF Core Architecture

Type System

Pattern Matching Engine Serialization Layer

Middleman

Cooperative Scheduler OpenCL Binding

Proxy Actor

Local (CPU) Actor OpenCL Actor Facade

Message Passing Layer

Managed completely by middleman

6/8

Dominik Charousset iNET – HAW Hamburg 13

(32)

CAF Core Architecture

Type System

Pattern Matching Engine Serialization Layer

Middleman

Cooperative Scheduler OpenCL Binding

Proxy Actor

Local (CPU) Actor OpenCL Actor Facade

Message Passing Layer

Crated by using spawn_cl<Signature>(

kernel_source, kernel_name, dimensions);

7/8

(33)

CAF Core Architecture

Type System

Pattern Matching Engine Serialization Layer

Middleman

Cooperative Scheduler OpenCL Binding

Proxy Actor

Local (CPU) Actor OpenCL Actor Facade

Message Passing Layer

Crated by using one of:

spawn(fun, args…);

spawn<Impl>(ctor_args…);

8/8

Dominik Charousset iNET – HAW Hamburg 13

(34)

Classes vs. Actors

class KeyValStore { public:

void set ( Key k , Val v );

Val get ( Key k) const; };

Method invocation Race conditions likely Concurrent performance is a function of

developer skill

become (

on( atom (" set "), arg_match )

>> [=]( Key k , Val v) { }, on( atom (" get "), arg_match )

>> [=]( Key k) { } );

Message passing Data race impossible Supports massively parallel access &

remote invocation

(35)

Classes vs. Actors

class KeyValStore { public:

void set ( Key k , Val v );

Val get ( Key k) const; };

Method invocation Race conditions likely Concurrent performance is a function of

developer skill

become (

on( atom (" set "), arg_match )

>> [=]( Key k , Val v) { }, on( atom (" get "), arg_match )

>> [=]( Key k) { } );

Message passing Data race impossible Supports massively parallel access &

remote invocation

Dominik Charousset iNET – HAW Hamburg 14

(36)

Classes vs. Actors

class KeyValStore { public:

void set ( Key k , Val v );

Val get ( Key k) const; };

Method invocation Race conditions likely Concurrent performance is a function of

developer skill

become (

on( atom (" set "), arg_match )

>> [=]( Key k , Val v) { }, on( atom (" get "), arg_match )

>> [=]( Key k) { } );

Message passing Data race impossible Supports massively parallel access &

remote invocation

(37)

Classes vs. Actors

class KeyValStore { public:

void set ( Key k , Val v );

Val get ( Key k) const; };

Method invocation Race conditions likely Concurrent performance is a function of

developer skill

become (

on( atom (" set "), arg_match )

>> [=]( Key k , Val v) { }, on( atom (" get "), arg_match )

>> [=]( Key k) { } );

Message passing Data race impossible Supports massively parallel access &

remote invocation

Dominik Charousset iNET – HAW Hamburg 14

(38)

API – Creating Actors

// args : constructor arguments for Impl template<class Impl ,

spawn_options Os = no_spawn_options , typename... Ts >

actor spawn ( Ts &&... args );

// args : functor followed by its arguments template< spawn_options Os = no_spawn_options ,

typename... Ts >

actor spawn ( Ts &&... args );

Create actors from either functors or classes

Spawn options can be used for monitoring, detaching, etc.

Creates event-based actors per default

(39)

API – Event-based Actor Class

class event_based_actor : ... { template<typename... Ts >

void send ( actor whom , Ts &&... what );

template<typename... Ts >

response_handle sync_send ( actor whom , Ts &&... what );

void become ( behavior bhvr );

void quit (uint32_t reason );

// ...

};

Base for class-based actors

Type of implicitself pointer for functor-based actors

Dominik Charousset iNET – HAW Hamburg 16

(40)

API – Remote Communication

// makes actor accessible via network void publish ( actor whom , uint16_t port );

// get handle to remotely running actor

actor remote_actor ( std :: string host , uint16_t port );

Message passing is network transparent

Both local and remote actors use handles of type actor

Network primitives not exposed to programmer

(41)

Example

behavior math_server () { return {

[](int a , int b) { return a + b;

} };

}

void math_client ( event_based_actor * self , actor ms ) { sync_send (ms , 40 , 2). then (

[=](int result ){

cout << " 40 + 2 = " << result << endl ; }

);

}

// spawn ( math_client , spawn ( math_server ));

Dominik Charousset iNET – HAW Hamburg 18

(42)

Example

behavior math_server () { return {

[](int a , int b) { return a + b;

} };

}

void math_client ( event_based_actor * self , actor ms ) { sync_send (ms , 40 , 2). then (

[=](int result ){

cout << " 40 + 2 = " << result << endl ; }

);

}

// spawn ( math_client , spawn ( math_server ));

return message handler for incoming messages (used until

replaced or actor is done)

(43)

Example

behavior math_server () { return {

[](int a , int b) { return a + b;

} };

}

void math_client ( event_based_actor * self , actor ms ) { sync_send (ms , 40 , 2). then (

[=](int result ){

cout << " 40 + 2 = " << result << endl ; }

);

}

// spawn ( math_client , spawn ( math_server ));

send a message and then wait for response (using a "one-shot handler")

Dominik Charousset iNET – HAW Hamburg 18

(44)

Example

behavior math_server () { return {

[](int a , int b) { return a + b;

} };

}

void math_client ( event_based_actor * self , actor ms ) { sync_send (ms , 40 , 2). then (

[=](int result ){

cout << " 40 + 2 = " << result << endl ; }

);

}

// spawn ( math_client , spawn ( math_server ));

this actor "loops" forever (or until it is forced to quit)

(45)

Example

behavior math_server () { return {

[](int a , int b) { return a + b;

} };

}

void math_client ( event_based_actor * self , actor ms ) { sync_send (ms , 40 , 2). then (

[=](int result ){

cout << " 40 + 2 = " << result << endl ; }

);

}

// spawn ( math_client , spawn ( math_server ));

this actor sends one message and receives one

messages

Dominik Charousset iNET – HAW Hamburg 18

(46)

Example

behavior math_server () { return {

[](int a , int b) { return a + b;

} };

}

void math_client ( event_based_actor * self , actor ms ) { sync_send (ms , 40 , 2). then (

[=](int result ){

cout << " 40 + 2 = " << result << endl ; }

);

}

// spawn ( math_client , spawn ( math_server ));

spawn server & client

(47)

Serialization in CAF

Non-intrusive serialization backend User-defined types need to beannounced

POD-like data: pointer to members or getter + setter Complex data: implementation of custom uniform_type_info

All announced types can usecaf::to_string

Dominik Charousset iNET – HAW Hamburg 19

(48)

Serialization in CAF – PODs

struct foo {

std :: vector <int> a;

int b;

};

// required by announce ()

bool operator==(const foo & lhs , const foo & rhs ) { return lhs .a == rhs .a

&& lhs .b == rhs .b;

}

int main (int, char**) {

announce <foo >(& foo ::a , & foo :: b );

// ...

}

(49)

Patterns for Actor Programming

Spawn one actor per task, keep individual actors simple Compose complex behavior out of small, easily testable actors Push stateful operations to new actors

Use “recursive” message loops (no stack overflow possible) Do not block indefinitely, define “continuation points”

Dominik Charousset iNET – HAW Hamburg 21

(50)

Patterns for Actor Programming

Spawn one actor per task, keep individual actors simple Compose complex behavior out of small, easily testable actors Push stateful operations to new actors

Use “recursive” message loops (no stack overflow possible) Do not block indefinitely, define “continuation points”

(51)

Patterns for Actor Programming

Spawn one actor per task, keep individual actors simple Compose complex behavior out of small, easily testable actors Push stateful operations to new actors

Use “recursive” message loops (no stack overflow possible) Do not block indefinitely, define “continuation points”

Dominik Charousset iNET – HAW Hamburg 21

(52)

Patterns for Actor Programming

Spawn one actor per task, keep individual actors simple Compose complex behavior out of small, easily testable actors Push stateful operations to new actors

Use “recursive” message loops (no stack overflow possible) Do not block indefinitely, define “continuation points”

(53)

Patterns for Actor Programming

Spawn one actor per task, keep individual actors simple Compose complex behavior out of small, easily testable actors Push stateful operations to new actors

Use “recursive” message loops (no stack overflow possible) Do not block indefinitely, define “continuation points”

Dominik Charousset iNET – HAW Hamburg 21

(54)

Interruptible Computation

// adds numbers [i , last ) unless ’stop ’ is received void counter ( event_based_actor * self , actor client ,

size_t value , size_t i , size_t last ) { if (i == last ) {

self -> send ( client , value );

self -> quit ();

return; }

self -> become (

on( atom (" stop ")) >> [=] { self -> quit ();

},

after ( std :: chrono :: seconds (0)) >> [=] {

counter ( self , client , value + i , i + 1, last );

} );

}

(55)

Thank you for your attention!

Home page: http://actor-framework.org

Sources: https://github.com/actor-framework/actor-framework

Dominik Charousset iNET – HAW Hamburg 23

Referenzen

ÄHNLICHE DOKUMENTE

We presented work done in the context of a run- ning student software project consisting in access- ing WordNet for providing for lexical semantic in- formation that can be used

Agha, Actors: A Model of Concurrent Computation In Distributed Systems, Tech. Carlsson, Erlang and OTP in Action, Manning Publications Co., Stamford, CT,

He has conducted research and published papers and articles in the fields of Islamic economics, economic legislation, regional economic integration, sustainable development, the zakat

It is only by acknowledging the distinctions and peculiarities of the different Islamist movements and parties and their interplay in the broader political arena of each

Finally, it is our conjecture that Classic Actors and Processes are mostly used in a fine-grained concurrency setting and lead to a style of programming where the state of an

• synergo practices consulting, research, policy evaluation, project management and planning in mobility management, transport and land- use, environment and energy, urban

enough finito i’ve had enough i don’t want to do this anymore this wasn’t part of the deal are we being drugged here or what a play is play bullshit i have abso- lutely no

In this model, the main F-actin-based structures involved in the fusion process of myeloid cells are presented: tunneling nanotubes (TNTs, insert 1) likely participate in the