SlideShare a Scribd company logo
Thinking Outside
the Synchronisation
Quadrant
@KevlinHenney
Architecture represents the
significant design decisions
that shape a system, where
significant is measured by
cost of change.
Grady Booch
Concurrency
Concurrency
Threads
Concurrency
Threads
Locks
Architecture is the art
of how to waste space.
Philip Johnson
Architecture is the art
of how to waste time.
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
Mutable
Immutable
Unshared Shared
Unshared mutable
data needs no
synchronisation
Unshared immutable
data needs no
synchronisation
Shared mutable
data needs
synchronisation
Shared immutable
data needs no
synchronisation
The Synchronisation Quadrant
Systems have properties
— capabilities, features,
characteristics, etc. —
inside and out.
Functional
Operational
Developmental
Functional
Operational
Developmental
This is the monstrosity in love,
lady, that the will is infinite,
and the execution confined;
that the desire is boundless,
and the act a slave to limit.
William Shakespeare
Troilus and Cressida
Multitasking is really just rapid
attention-switching.
And that'd be a useful skill, except it
takes us a second or two to engage
in a new situation we've graced with
our focus.
So, the sum total of attention is
actually decreased as we multitask.
Slicing your attention, in other
words, is less like slicing potatoes
than like slicing plums: you always
lose some juice.
David Weinberger
http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/
completion time
for single thread
𝑡 = 𝑡1
division of
labour
𝑡 =
𝑡1
𝑛
𝑡 = 𝑡1 1 − 𝑝
𝑛 − 1
𝑛
portion in
parallel
Amdahl's law
𝑡 = 𝑡1 1 − 𝑝
𝑛 − 1
𝑛
+ 𝑘
𝑛 𝑛 − 1
2
typical
communication
overhead
inter-thread
connections
(worst case)
𝑡 = 𝑡1 1 − 𝑝
𝑛 − 1
𝑛
+ 𝑘
𝑛 𝑛 − 1
2
template<typename TaskIterator, typename Reducer>
void map_reduce(
TaskIterator begin, TaskIterator end,
Reducer reduce)
{
std::vector<std::thread> threads;
for(auto task = begin; task != end; ++task)
threads.push_back(std::thread(*task));
for(auto & to_join : threads)
to_join.join();
reduce();
}
Command-line tools
can be 235x faster than
your Hadoop cluster
Adam Drake
http://aadrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html
Functional
Operational
Developmental
A large fraction of the flaws in software development
are due to programmers not fully understanding all
the possible states their code may execute in.
In a multithreaded environment, the lack of
understanding and the resulting problems are greatly
amplified, almost to the point of panic if you are
paying attention.
John Carmack
http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
Some people, when confronted with a
problem, think, "I know, I'll use threads,"
and then two they hav erpoblesms.
Ned Batchelder
https://twitter.com/#!/nedbat/status/194873829825327104
Shared memory is like a canvas where threads
collaborate in painting images, except that
they stand on the opposite sides of the canvas
and use guns rather than brushes.
The only way they can avoid killing each other
is if they shout "duck!" before opening fire.
Bartosz Milewski
"Functional Data Structures and Concurrency in C++"
http://bartoszmilewski.com/2013/12/10/functional-data-structures-and-concurrency-in-c/
There are several ways to
address the problem of
deadlock...
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Just ignore it and hope it
doesn't happen.
Ostrich Algorithm
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Detection and recovery —
if it happens, take action.
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Dynamic avoidance by careful
resource allocation — check to
see if a resource can be
granted, and if granting it will
cause deadlock, don't grant it.
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Prevention — change the rules.
http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
Functional
Operational
Developmental
habitable
Habitability is the characteristic
of source code that enables
programmers, coders, bug-fixers,
and people coming to the code
later in its life to understand its
construction and intentions and
to change it comfortably and
confidently.
Habitability makes a place
livable, like home. And this is
what we want in software — that
developers feel at home, can
place their hands on any item
without having to think deeply
about where it is.
testable
Simple Testing Can Prevent
Most Critical Failures
An Analysis of Production Failures in
Distributed Data-Intensive Systems
https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf
We want our code
to be unit testable.
What is a unit test?
A test is not a unit test if:
▪ It talks to the database
▪ It communicates across the network
▪ It touches the file system
▪ It can't run at the same time as any of your other
unit tests
▪ You have to do special things to your environment
(such as editing config files) to run it.
Michael Feathers
http://www.artima.com/weblogs/viewpost.jsp?thread=126923
A unit test is a test of behaviour
whose success or failure is wholly
determined by the correctness of
the test and the correctness of the
unit under test.
Kevlin Henney
http://www.theregister.co.uk/2007/07/28/what_are_your_units/
What do we want
from unit tests?
When a unit test
passes, it shows
the code is correct.
When a unit test
fails, it shows the
code is incorrect.
isolated
asynchronous
sequential
Future
Immediately return a ‘virtual’ data object—
called a future—to the client when it invokes a
service. This future [...] only provides a value
to clients when the computation is complete.
std::future<ResultType>
iou = std::async(function);
...
ResultType result = iou.get();
joiner<ResultType>
iou = thread(function);
...
ResultType result = iou();
"C++ Threading", ACCU Conference, April 2003
"More C++ Threading", ACCU Conference, April 2004
"N1883: Preliminary Threading Proposal for TR2", JTC1/SC22/WG21, August 2005
immutable
In functional programming, programs are
executed by evaluating expressions, in
contrast with imperative programming where
programs are composed of statements which
change global state when executed.
Functional programming typically avoids
using mutable state.
https://wiki.haskell.org/Functional_programming
Many programming languages support
programming in both functional and
imperative style but the syntax and facilities
of a language are typically optimised for only
one of these styles, and social factors like
coding conventions and libraries often force
the programmer towards one of the styles.
https://wiki.haskell.org/Functional_programming
William Cook, "On Understanding Data Abstraction, Revisited"
[](){}
[](){}()
https://twitter.com/mfeathers/status/29581296216
To keep our C++ API boundary simple, we [...] adopted
one-way data flow. The API consists of methods to
perform fire-and-forget mutations and methods to
compute view models required by specific views.
To keep the code understandable, we write functional
style code converting raw data objects into immutable
view models by default. As we identified performance
bottlenecks through profiling, we added caches to avoid
recomputing unchanged intermediate results.
The resulting functional code is easy to maintain,
without sacrificing performance.
https://code.facebook.com/posts/498597036962415/under-the-hood-building-moments/
Immutable Value
Define a value object type whose instances
are immutable. The internal state of a value
object is set at construction and no
subsequent modifications are allowed.
const
&
&&
Copied Value
Define a value object type whose instances
are copyable. When a value is used in
communication with another thread, ensure
that the value is copied.
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
void set_year(int);
void set_month(int);
void set_day_in_month(int);
...
};
Just because you
have a getter,
doesn't mean you
should have a
matching setter.
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
void set(int year, int month, int day_in_month);
...
};
today.set(2016, 11, 16);
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
};
today = date(2016, 11, 16);
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
};
today = date { 2016, 11, 16 };
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
};
today = { 2016, 11, 16 };
"Get something"
is an imperative
with an expected
side effect.
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int get_year() const;
int get_month() const;
int get_day_in_month() const;
...
};
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int year() const;
int month() const;
int day_in_month() const;
...
};
class date
{
public:
date(int year, int month, int day_in_month);
date(const date &);
date & operator=(const date &);
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int) const;
...
};
Builder
Introduce a builder that provides separate
methods for constructing and disposing of
each different part of a complex object, or
for combining cumulative changes in the
construction of whole objects.
class date
{
public:
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int) const;
...
};
class date
{
public:
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int new_year) const
{
return { new_year, month(), day_in_month() };
}
...
};
class date
{
public:
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int new_year) const
{
return
new_year == year
? *this
: date { new_year, month(), day_in_month() };
}
...
};
class date
{
public:
...
int year() const;
int month() const;
int day_in_month() const;
date with_year(int) const;
date with_month(int) const;
date with_day_in_month(int) const
...
};
Asking a question
should not change
the answer.
Bertrand Meyer
Asking a question
should not change
the answer, and
nor should asking
it twice!
Referential transparency is a very
desirable property: it implies that
functions consistently yield the same
results given the same input,
irrespective of where and when they are
invoked. That is, function evaluation
depends less—ideally, not at all—on the
side effects of mutable state.
Edward Garson
"Apply Functional Programming Principles"
// "FTL" (Functional Template Library :->)
// container style
template<typename ValueType>
class container
{
public:
typedef const ValueType value_type;
typedef ... iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
...
container & operator=(const container &);
...
};
template<typename ValueType>
class set
{
public:
typedef const ValueType * iterator;
...
set(std::initializer_list<ValueType> values);
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
iterator find(const ValueType &) const;
std::size_t count(const ValueType &) const;
iterator lower_bound(const ValueType &) const;
iterator upper_bound(const ValueType &) const;
pair<iterator, iterator> equal_range(const ValueType &) const;
...
private:
ValueType * members;
std::size_t cardinality;
};
set<int> c { 2, 9, 9, 7, 9, 2, 4, 5, 8 };
template<typename ValueType>
class array
{
public:
typedef const ValueType * iterator;
...
array(std::initializer_list<ValueType> values);
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
...
private:
ValueType * elements;
std::size_t length;
};
array<int> c { 2, 9, 9, 7, 9, 2, 4, 5, 8 };
In computing, a persistent data structure is a data structure
that always preserves the previous version of itself when it is
modified. Such data structures are effectively immutable, as
their operations do not (visibly) update the structure in-place,
but instead always yield a new updated structure.
http://en.wikipedia.org/wiki/Persistent_data_structure
(A persistent data structure is not a data structure committed
to persistent storage, such as a disk; this is a different and
unrelated sense of the word "persistent.")
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector pop_front() const;
vector pop_back() const;
...
private:
ValueType * anchor;
iterator from, until;
};
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector pop_front() const;
vector pop_back() const;
...
private:
ValueType * anchor;
iterator from, until;
};
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector popped_front() const;
vector popped_back() const;
...
private:
ValueType * anchor;
iterator from, until;
};
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector popped_front() const;
vector popped_back() const;
...
private:
ValueType * anchor;
iterator from, until;
};
I still have a deep fondness for the
Lisp model. It is simple, elegant, and
something with which all developers
should have an infatuation at least
once in their programming life.
Kevlin Henney
"A Fair Share (Part I)", CUJ C++ Experts Forum, October 2002
lispt
template<typename ValueType>
class list
{
public:
class iterator;
...
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & front() const;
list popped_front() const;
list pushed_front() const;
...
private:
struct link
{
link(const ValueType & value, link * next);
ValueType value;
link * next;
};
link * head;
std::size_t length;
};
Hamlet: Yea, from the table of
my memory I'll wipe away all
trivial fond records.
William Shakespeare
The Tragedy of Hamlet
[Act I, Scene 5]
Garbage collection [...] is optional
in C++; that is, a garbage collector
is not a compulsory part of an
implementation.
Bjarne Stroustrup
http://stroustrup.com/C++11FAQ.html
assert(
std::get_pointer_safety() ==
std::pointer_safety::strict);
Ophelia: 'Tis in my memory
locked, and you yourself shall
keep the key of it.
William Shakespeare
The Tragedy of Hamlet
[Act I, Scene 3]
A use-counted class is more
complicated than a non-use-
counted equivalent, and all of
this horsing around with use
counts takes a significant
amount of processing time.
Robert Murray
C++ Strategies and Tactics
template<typename ValueType>
class vector
{
public:
typedef const ValueType * iterator;
...
bool empty() const;
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & operator[](std::size_t) const;
const ValueType & front() const;
const ValueType & back() const;
const ValueType * data() const;
vector popped_front() const;
vector popped_back() const;
...
private:
std::shared_ptr<ValueType> anchor;
iterator from, until;
};
Uses std::default_delete<ValueType[]>, but
cannot be initialised from std::make_shared
template<typename ValueType>
class list
{
public:
class iterator;
...
std::size_t size() const;
iterator begin() const;
iterator end() const;
const ValueType & front() const;
list popped_front() const;
list pushed_front() const;
...
private:
struct link
{
link(const ValueType & value, std::shared_ptr<link> next);
ValueType value;
std::shared_ptr<link> next;
};
std::shared_ptr<link> head;
std::size_t length;
};
{
list<Anything> chain;
std::fill_n(
std::front_inserter(chain),
how_many,
something);
}
On destruction, deletion of links is recursive through each link, causing
the stack to blow up for surprisingly small values of how_many.
Instead of using threads and shared
memory as our programming model, we
can use processes and message passing.
Process here just means a protected
independent state with executing code,
not necessarily an operating system
process.
Russel Winder
"Message Passing Leads to Better Scalability in Parallel Systems"
Languages such as Erlang (and occam
before it) have shown that processes are a
very successful mechanism for
programming concurrent and parallel
systems. Such systems do not have all
the synchronization stresses that shared-
memory, multithreaded systems have.
Russel Winder
"Message Passing Leads to Better Scalability in Parallel Systems"
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
bool try_receive(ValueType &);
private:
...
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
bool try_receive(ValueType &);
private:
std::deque<ValueType> fifo;
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType & to_send)
{
fifo.push_back(to_send);
}
...
};
template<typename ValueType>
class channel
{
public:
...
bool try_receive(ValueType & to_receive)
{
bool received = false;
if (!fifo.empty())
{
to_receive = fifo.front();
fifo.pop_front();
received = true;
}
return received;
}
...
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
bool try_receive(ValueType &);
private:
std::mutex key;
std::deque<ValueType> fifo;
};
void send(const ValueType & to_send)
{
std::lock_guard<std::mutex> guard(key);
fifo.push_back(to_send);
}
bool try_receive(ValueType & to_receive)
{
bool received = false;
if (key.try_lock())
{
std::lock_guard<std::mutex> guard(key, std::adopt_lock);
if (!fifo.empty())
{
to_receive = fifo.front();
fifo.pop_front();
received = true;
}
}
return received;
}
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
private:
std::mutex key;
std::condition_variable_any non_empty;
std::deque<ValueType> fifo;
};
void send(const ValueType & to_send)
{
std::lock_guard<std::mutex> guard(key);
fifo.push_back(to_send);
non_empty.notify_all();
}
void receive(ValueType & to_receive)
{
std::lock_guard<std::mutex> guard(key);
non_empty.wait(
key,
[this]
{
return !fifo.empty();
});
to_receive = fifo.front();
fifo.pop_front();
}
https://twitter.com/richardadalton/status/591534529086693376
std::string fizzbuzz(int n)
{
return
n % 15 == 0 ? "FizzBuzz" :
n % 3 == 0 ? "Fizz" :
n % 5 == 0 ? "Buzz" :
std::to_string(n);
}
void fizzbuzzer(channel<int> & in, channel<std::string> & out)
{
for (;;)
{
int n;
in.receive(n);
out.send(fizzbuzz(n));
}
}
int main()
{
channel<int> out;
channel<std::string> back;
std::thread fizzbuzzing(fizzbuzzer, out, back)
for (int n = 1; n <= 100; ++n)
{
out.send(n);
std::string result;
back.receive(result);
std::cout << result << "n";
}
...
}
int main()
{
channel<int> out;
channel<std::string> back;
std::thread fizzbuzzing(fizzbuzzer, out, back)
for (int n = 1; n <= 100; ++n)
{
out << n;
std::string result;
back >> result;
std::cout << result << "n";
}
...
}
void fizzbuzzer(channel<int> & in, channel<std::string> & out)
{
for (;;)
{
int n;
in >> n;
out << fizzbuzz(n);
}
}
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
void operator<<(const ValueType &);
void operator>>(ValueType &);
private:
std::mutex key;
std::condition_variable_any non_empty;
std::deque<ValueType> fifo;
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
void operator<<(const ValueType &);
receiving operator>>(ValueType &);
private:
std::mutex key;
std::condition_variable_any non_empty;
std::deque<ValueType> fifo;
};
template<typename ValueType>
class channel
{
public:
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
void operator<<(const ValueType & to_send)
{
send(to_send);
}
receiving operator>>(ValueType & to_receive);
{
return receiving(this, to_receive);
}
...
};
class receiving
{
public:
receiving(channel * that, ValueType & to_receive)
: that(that), to_receive(to_receive)
{
}
receiving(receiving && other)
: that(other.that), to_receive(other.to_receive)
{
other.that = nullptr;
}
operator bool()
{
auto from = that;
that = nullptr;
return from && from->try_receive(to_receive);
}
~receiving()
{
if (that)
that->receive(to_receive);
}
private:
channel * that;
ValueType & to_receive;
};
std::string fizzbuzz(int n)
{
if (n < 1 || n > 100)
throw std::domain_error(
"fizzbuzz(n) is defined for n in [1..100]")
return
n % 15 == 0 ? "FizzBuzz" :
n % 3 == 0 ? "Fizz" :
n % 5 == 0 ? "Buzz" :
std::to_string(n);
}
void fizzbuzzer(channel<int> & in, channel<std::any> & out)
{
for (;;)
{
try
{
int n;
in >> n;
out << fizzbuzz(n);
}
catch (...)
{
out << std::current_exception();
}
}
}
int main()
{
channel<int> out;
channel<std::any> back;
std::thread fizzbuzzing(fizzbuzzer, out, back)
for (int n = 1; n <= 100; ++n)
{
out << n;
std::any result;
back >> result;
if (result.type() == typeid(std::string))
std::cout << std::any_cast<std::string>(result) << "n";
}
...
}
template<typename ValueType>
class channel
{
public:
channel();
channel(std::function<void(const ValueType &)>);
void send(const ValueType &);
void receive(ValueType &);
bool try_receive(ValueType &);
void operator<<(const ValueType &);
receiving operator>>(ValueType &);
private:
std::mutex key;
std::condition_variable_any non_empty;
std::deque<ValueType> fifo;
};
int main()
{
channel<int> out;
channel<std::any> back(
[](const any & received)
{
if (received.type() == typeid(std::exception_ptr))
std::rethrow_exception(any_cast<std::exception_ptr>(received));
});
std::thread fizzbuzzing(fizzbuzzer, out, back)
...
}
int main()
{
...
for (int n = 1; n <= 100; ++n)
{
try
{
out << n;
std::any result;
back >> result;
std::cout << std::any_cast<std::string>(result) << "n";
}
catch (std::domain_error & caught)
{
std::cout << caught.what() << "n";
}
}
...
}
Pipes and Filters
Divide the application's task into
several self-contained data
processing steps and connect these
steps to a data processing pipeline
via intermediate data buffers.
Simple filters that can be arbitrarily
chained are more easily re-used, and
more robust, than almost any other
kind of code.
Brandon Rhodes
http://rhodesmill.org/brandon/slides/2012-11-pyconca/
Multithreading is just one
damn thing after, before, or
simultaneous with another.
Andrei Alexandrescu
Actor-based concurrency is
just one damn message after
another.
No matter what language you work in,
programming in a functional style provides
benefits.
You should do it whenever it is convenient,
and you should think hard about the
decision when it isn't convenient.
John Carmack
http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
Programming in a functional style makes
the state presented to your code explicit,
which makes it much easier to reason
about, and, in a completely pure system,
makes thread race conditions impossible.
John Carmack
http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
Think outside the
synchronisation
quadrant...
All computers
wait at the
same speed.

More Related Content

What's hot

A pattern language for microservices (#gluecon #gluecon2016)
A pattern language for microservices (#gluecon #gluecon2016)A pattern language for microservices (#gluecon #gluecon2016)
A pattern language for microservices (#gluecon #gluecon2016)
Chris Richardson
 
Mistral AI Strategic Memo.pdf
Mistral AI Strategic Memo.pdfMistral AI Strategic Memo.pdf
Mistral AI Strategic Memo.pdf
Oliver Molander
 
Apache Beam (incubating)
Apache Beam (incubating)Apache Beam (incubating)
Apache Beam (incubating)
Apache Apex
 
Fairness-aware Machine Learning: Practical Challenges and Lessons Learned (KD...
Fairness-aware Machine Learning: Practical Challenges and Lessons Learned (KD...Fairness-aware Machine Learning: Practical Challenges and Lessons Learned (KD...
Fairness-aware Machine Learning: Practical Challenges and Lessons Learned (KD...
Krishnaram Kenthapadi
 
Scaling Agile | Spotify
Scaling Agile | SpotifyScaling Agile | Spotify
Scaling Agile | Spotify
XPDays
 
Model storming
Model stormingModel storming
Model storming
Alberto Brandolini
 
Challenges in AI LLMs adoption in the Enterprise
Challenges in AI LLMs adoption in the EnterpriseChallenges in AI LLMs adoption in the Enterprise
Challenges in AI LLMs adoption in the Enterprise
George Bara
 
Org Topologies at Scrum Day Europe 2022, Amsterdam
Org Topologies at Scrum Day Europe 2022, AmsterdamOrg Topologies at Scrum Day Europe 2022, Amsterdam
Org Topologies at Scrum Day Europe 2022, Amsterdam
Alexey Krivitsky
 
Align to Strategy with Portfolio Management & Jira Align
Align to Strategy with Portfolio Management & Jira AlignAlign to Strategy with Portfolio Management & Jira Align
Align to Strategy with Portfolio Management & Jira Align
Cprime
 
Learn to Use Databricks for the Full ML Lifecycle
Learn to Use Databricks for the Full ML LifecycleLearn to Use Databricks for the Full ML Lifecycle
Learn to Use Databricks for the Full ML Lifecycle
Databricks
 
ChatGPT, Foundation Models and Web3.pptx
ChatGPT, Foundation Models and Web3.pptxChatGPT, Foundation Models and Web3.pptx
ChatGPT, Foundation Models and Web3.pptx
Jesus Rodriguez
 
⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨
Wen-Tien Chang
 
Open core summit: Observability for data pipelines with OpenLineage
Open core summit: Observability for data pipelines with OpenLineageOpen core summit: Observability for data pipelines with OpenLineage
Open core summit: Observability for data pipelines with OpenLineage
Julien Le Dem
 
UNLEASHING INNOVATION Exploring Generative AI in the Enterprise.pdf
UNLEASHING INNOVATION Exploring Generative AI in the Enterprise.pdfUNLEASHING INNOVATION Exploring Generative AI in the Enterprise.pdf
UNLEASHING INNOVATION Exploring Generative AI in the Enterprise.pdf
Hermes Romero
 
Lean Kanban India 2018 | From Upstream to Portfolio Kanban, a Fresh look | P...
Lean Kanban India 2018  | From Upstream to Portfolio Kanban, a Fresh look | P...Lean Kanban India 2018  | From Upstream to Portfolio Kanban, a Fresh look | P...
Lean Kanban India 2018 | From Upstream to Portfolio Kanban, a Fresh look | P...
LeanKanbanIndia
 
Generative AI at the edge.pdf
Generative AI at the edge.pdfGenerative AI at the edge.pdf
Generative AI at the edge.pdf
Qualcomm Research
 
The Executives Step-by-Step Guide to Leading a Large-Scale Agile Transformation
The Executives Step-by-Step Guide to Leading a Large-Scale Agile TransformationThe Executives Step-by-Step Guide to Leading a Large-Scale Agile Transformation
The Executives Step-by-Step Guide to Leading a Large-Scale Agile Transformation
LeadingAgile
 
Getting up to Speed with MirrorMaker 2 (Mickael Maison, IBM & Ryanne Dolan) K...
Getting up to Speed with MirrorMaker 2 (Mickael Maison, IBM & Ryanne Dolan) K...Getting up to Speed with MirrorMaker 2 (Mickael Maison, IBM & Ryanne Dolan) K...
Getting up to Speed with MirrorMaker 2 (Mickael Maison, IBM & Ryanne Dolan) K...
HostedbyConfluent
 
Stanford AI Report 2023
Stanford AI Report 2023Stanford AI Report 2023
Stanford AI Report 2023
Kapil Khandelwal (KK)
 
Platforms Ecosystems Principles - saved.pptx
Platforms Ecosystems Principles - saved.pptxPlatforms Ecosystems Principles - saved.pptx
Platforms Ecosystems Principles - saved.pptx
Raji Gogulapati
 

What's hot (20)

A pattern language for microservices (#gluecon #gluecon2016)
A pattern language for microservices (#gluecon #gluecon2016)A pattern language for microservices (#gluecon #gluecon2016)
A pattern language for microservices (#gluecon #gluecon2016)
 
Mistral AI Strategic Memo.pdf
Mistral AI Strategic Memo.pdfMistral AI Strategic Memo.pdf
Mistral AI Strategic Memo.pdf
 
Apache Beam (incubating)
Apache Beam (incubating)Apache Beam (incubating)
Apache Beam (incubating)
 
Fairness-aware Machine Learning: Practical Challenges and Lessons Learned (KD...
Fairness-aware Machine Learning: Practical Challenges and Lessons Learned (KD...Fairness-aware Machine Learning: Practical Challenges and Lessons Learned (KD...
Fairness-aware Machine Learning: Practical Challenges and Lessons Learned (KD...
 
Scaling Agile | Spotify
Scaling Agile | SpotifyScaling Agile | Spotify
Scaling Agile | Spotify
 
Model storming
Model stormingModel storming
Model storming
 
Challenges in AI LLMs adoption in the Enterprise
Challenges in AI LLMs adoption in the EnterpriseChallenges in AI LLMs adoption in the Enterprise
Challenges in AI LLMs adoption in the Enterprise
 
Org Topologies at Scrum Day Europe 2022, Amsterdam
Org Topologies at Scrum Day Europe 2022, AmsterdamOrg Topologies at Scrum Day Europe 2022, Amsterdam
Org Topologies at Scrum Day Europe 2022, Amsterdam
 
Align to Strategy with Portfolio Management & Jira Align
Align to Strategy with Portfolio Management & Jira AlignAlign to Strategy with Portfolio Management & Jira Align
Align to Strategy with Portfolio Management & Jira Align
 
Learn to Use Databricks for the Full ML Lifecycle
Learn to Use Databricks for the Full ML LifecycleLearn to Use Databricks for the Full ML Lifecycle
Learn to Use Databricks for the Full ML Lifecycle
 
ChatGPT, Foundation Models and Web3.pptx
ChatGPT, Foundation Models and Web3.pptxChatGPT, Foundation Models and Web3.pptx
ChatGPT, Foundation Models and Web3.pptx
 
⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨⼤語⾔模型 LLM 應⽤開發入⾨
⼤語⾔模型 LLM 應⽤開發入⾨
 
Open core summit: Observability for data pipelines with OpenLineage
Open core summit: Observability for data pipelines with OpenLineageOpen core summit: Observability for data pipelines with OpenLineage
Open core summit: Observability for data pipelines with OpenLineage
 
UNLEASHING INNOVATION Exploring Generative AI in the Enterprise.pdf
UNLEASHING INNOVATION Exploring Generative AI in the Enterprise.pdfUNLEASHING INNOVATION Exploring Generative AI in the Enterprise.pdf
UNLEASHING INNOVATION Exploring Generative AI in the Enterprise.pdf
 
Lean Kanban India 2018 | From Upstream to Portfolio Kanban, a Fresh look | P...
Lean Kanban India 2018  | From Upstream to Portfolio Kanban, a Fresh look | P...Lean Kanban India 2018  | From Upstream to Portfolio Kanban, a Fresh look | P...
Lean Kanban India 2018 | From Upstream to Portfolio Kanban, a Fresh look | P...
 
Generative AI at the edge.pdf
Generative AI at the edge.pdfGenerative AI at the edge.pdf
Generative AI at the edge.pdf
 
The Executives Step-by-Step Guide to Leading a Large-Scale Agile Transformation
The Executives Step-by-Step Guide to Leading a Large-Scale Agile TransformationThe Executives Step-by-Step Guide to Leading a Large-Scale Agile Transformation
The Executives Step-by-Step Guide to Leading a Large-Scale Agile Transformation
 
Getting up to Speed with MirrorMaker 2 (Mickael Maison, IBM & Ryanne Dolan) K...
Getting up to Speed with MirrorMaker 2 (Mickael Maison, IBM & Ryanne Dolan) K...Getting up to Speed with MirrorMaker 2 (Mickael Maison, IBM & Ryanne Dolan) K...
Getting up to Speed with MirrorMaker 2 (Mickael Maison, IBM & Ryanne Dolan) K...
 
Stanford AI Report 2023
Stanford AI Report 2023Stanford AI Report 2023
Stanford AI Report 2023
 
Platforms Ecosystems Principles - saved.pptx
Platforms Ecosystems Principles - saved.pptxPlatforms Ecosystems Principles - saved.pptx
Platforms Ecosystems Principles - saved.pptx
 

Similar to Thinking Outside the Synchronisation Quadrant

Patterns for the People
Patterns for the PeoplePatterns for the People
Patterns for the People
Kevlin Henney
 
Java Programming
Java ProgrammingJava Programming
Java Programming
Tracy Clark
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascript
Ayush Sharma
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Dom
kaven yan
 
C questions
C questionsC questions
C questions
parm112
 
Models vs Reality: Quest for the Roots of Complexity
Models vs Reality: Quest for the Roots of ComplexityModels vs Reality: Quest for the Roots of Complexity
Models vs Reality: Quest for the Roots of Complexity
Julian Warszawski
 
P Training Presentation
P Training PresentationP Training Presentation
P Training PresentationGaurav Tyagi
 
Oopp Lab Work
Oopp Lab WorkOopp Lab Work
Oopp Lab Work
Heather Dionne
 
Singleton Design Pattern - Creation Pattern
Singleton Design Pattern - Creation PatternSingleton Design Pattern - Creation Pattern
Singleton Design Pattern - Creation Pattern
Seerat Malik
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
Iván Fernández Perea
 
cf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Woodcf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Wood
Ortus Solutions, Corp
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
Sergii Stets
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)rashmita_mishra
 
Design Pattern For C# Part 1
Design Pattern For C# Part 1Design Pattern For C# Part 1
Design Pattern For C# Part 1
Shahzad
 
Neal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureNeal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary Architecture
Thoughtworks
 
Neal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureNeal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary Architecture
ThoughtWorks Studios
 
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Ovidiu Farauanu
 
10 ways to make your code rock
10 ways to make your code rock10 ways to make your code rock
10 ways to make your code rockmartincronje
 
Dot Net Accenture
Dot Net AccentureDot Net Accenture
Dot Net AccentureSri K
 

Similar to Thinking Outside the Synchronisation Quadrant (20)

Patterns for the People
Patterns for the PeoplePatterns for the People
Patterns for the People
 
Java Programming
Java ProgrammingJava Programming
Java Programming
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascript
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Dom
 
C questions
C questionsC questions
C questions
 
Models vs Reality: Quest for the Roots of Complexity
Models vs Reality: Quest for the Roots of ComplexityModels vs Reality: Quest for the Roots of Complexity
Models vs Reality: Quest for the Roots of Complexity
 
P Training Presentation
P Training PresentationP Training Presentation
P Training Presentation
 
Oopp Lab Work
Oopp Lab WorkOopp Lab Work
Oopp Lab Work
 
Singleton Design Pattern - Creation Pattern
Singleton Design Pattern - Creation PatternSingleton Design Pattern - Creation Pattern
Singleton Design Pattern - Creation Pattern
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
cf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Woodcf.Objective() 2017 - Design patterns - Brad Wood
cf.Objective() 2017 - Design patterns - Brad Wood
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Effective Java
Effective JavaEffective Java
Effective Java
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)
 
Design Pattern For C# Part 1
Design Pattern For C# Part 1Design Pattern For C# Part 1
Design Pattern For C# Part 1
 
Neal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureNeal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary Architecture
 
Neal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary ArchitectureNeal Ford Emergent Design And Evolutionary Architecture
Neal Ford Emergent Design And Evolutionary Architecture
 
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
Functional Patterns for C++ Multithreading (C++ Dev Meetup Iasi)
 
10 ways to make your code rock
10 ways to make your code rock10 ways to make your code rock
10 ways to make your code rock
 
Dot Net Accenture
Dot Net AccentureDot Net Accenture
Dot Net Accenture
 

More from Kevlin Henney

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
Kevlin Henney
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
Kevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
Kevlin Henney
 
Get Kata
Get KataGet Kata
Get Kata
Kevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Kevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
Kevlin Henney
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
Kevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
Kevlin Henney
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
Kevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
Kevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
Kevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
Kevlin Henney
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
Kevlin Henney
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
Kevlin Henney
 
Good Code
Good CodeGood Code
Good Code
Kevlin Henney
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
Kevlin Henney
 

More from Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
 

Recently uploaded

Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 

Recently uploaded (20)

Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 

Thinking Outside the Synchronisation Quadrant

  • 2.
  • 3.
  • 4.
  • 5. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change. Grady Booch
  • 9. Architecture is the art of how to waste space. Philip Johnson
  • 10. Architecture is the art of how to waste time.
  • 11. Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation
  • 12. Mutable Immutable Unshared Shared Unshared mutable data needs no synchronisation Unshared immutable data needs no synchronisation Shared mutable data needs synchronisation Shared immutable data needs no synchronisation The Synchronisation Quadrant
  • 13. Systems have properties — capabilities, features, characteristics, etc. — inside and out.
  • 14.
  • 17. This is the monstrosity in love, lady, that the will is infinite, and the execution confined; that the desire is boundless, and the act a slave to limit. William Shakespeare Troilus and Cressida
  • 18. Multitasking is really just rapid attention-switching. And that'd be a useful skill, except it takes us a second or two to engage in a new situation we've graced with our focus. So, the sum total of attention is actually decreased as we multitask. Slicing your attention, in other words, is less like slicing potatoes than like slicing plums: you always lose some juice. David Weinberger
  • 20. completion time for single thread 𝑡 = 𝑡1
  • 22. 𝑡 = 𝑡1 1 − 𝑝 𝑛 − 1 𝑛 portion in parallel Amdahl's law
  • 23. 𝑡 = 𝑡1 1 − 𝑝 𝑛 − 1 𝑛 + 𝑘 𝑛 𝑛 − 1 2 typical communication overhead inter-thread connections (worst case)
  • 24. 𝑡 = 𝑡1 1 − 𝑝 𝑛 − 1 𝑛 + 𝑘 𝑛 𝑛 − 1 2
  • 25. template<typename TaskIterator, typename Reducer> void map_reduce( TaskIterator begin, TaskIterator end, Reducer reduce) { std::vector<std::thread> threads; for(auto task = begin; task != end; ++task) threads.push_back(std::thread(*task)); for(auto & to_join : threads) to_join.join(); reduce(); }
  • 26. Command-line tools can be 235x faster than your Hadoop cluster Adam Drake http://aadrake.com/command-line-tools-can-be-235x-faster-than-your-hadoop-cluster.html
  • 28. A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in. In a multithreaded environment, the lack of understanding and the resulting problems are greatly amplified, almost to the point of panic if you are paying attention. John Carmack http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
  • 29. Some people, when confronted with a problem, think, "I know, I'll use threads," and then two they hav erpoblesms. Ned Batchelder https://twitter.com/#!/nedbat/status/194873829825327104
  • 30. Shared memory is like a canvas where threads collaborate in painting images, except that they stand on the opposite sides of the canvas and use guns rather than brushes. The only way they can avoid killing each other is if they shout "duck!" before opening fire. Bartosz Milewski "Functional Data Structures and Concurrency in C++" http://bartoszmilewski.com/2013/12/10/functional-data-structures-and-concurrency-in-c/
  • 31. There are several ways to address the problem of deadlock... http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 32. Just ignore it and hope it doesn't happen. Ostrich Algorithm http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 33. Detection and recovery — if it happens, take action. http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 34. Dynamic avoidance by careful resource allocation — check to see if a resource can be granted, and if granting it will cause deadlock, don't grant it. http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 35. Prevention — change the rules. http://www.cs.rpi.edu/academics/courses/fall04/os/c10/index.html
  • 38.
  • 39. Habitability is the characteristic of source code that enables programmers, coders, bug-fixers, and people coming to the code later in its life to understand its construction and intentions and to change it comfortably and confidently.
  • 40. Habitability makes a place livable, like home. And this is what we want in software — that developers feel at home, can place their hands on any item without having to think deeply about where it is.
  • 42. Simple Testing Can Prevent Most Critical Failures An Analysis of Production Failures in Distributed Data-Intensive Systems https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-yuan.pdf
  • 43. We want our code to be unit testable. What is a unit test?
  • 44. A test is not a unit test if: ▪ It talks to the database ▪ It communicates across the network ▪ It touches the file system ▪ It can't run at the same time as any of your other unit tests ▪ You have to do special things to your environment (such as editing config files) to run it. Michael Feathers http://www.artima.com/weblogs/viewpost.jsp?thread=126923
  • 45. A unit test is a test of behaviour whose success or failure is wholly determined by the correctness of the test and the correctness of the unit under test. Kevlin Henney http://www.theregister.co.uk/2007/07/28/what_are_your_units/
  • 46. What do we want from unit tests?
  • 47. When a unit test passes, it shows the code is correct.
  • 48. When a unit test fails, it shows the code is incorrect.
  • 52.
  • 53. Future Immediately return a ‘virtual’ data object— called a future—to the client when it invokes a service. This future [...] only provides a value to clients when the computation is complete.
  • 55. joiner<ResultType> iou = thread(function); ... ResultType result = iou(); "C++ Threading", ACCU Conference, April 2003 "More C++ Threading", ACCU Conference, April 2004 "N1883: Preliminary Threading Proposal for TR2", JTC1/SC22/WG21, August 2005
  • 57. In functional programming, programs are executed by evaluating expressions, in contrast with imperative programming where programs are composed of statements which change global state when executed. Functional programming typically avoids using mutable state. https://wiki.haskell.org/Functional_programming
  • 58. Many programming languages support programming in both functional and imperative style but the syntax and facilities of a language are typically optimised for only one of these styles, and social factors like coding conventions and libraries often force the programmer towards one of the styles. https://wiki.haskell.org/Functional_programming
  • 59. William Cook, "On Understanding Data Abstraction, Revisited"
  • 63. To keep our C++ API boundary simple, we [...] adopted one-way data flow. The API consists of methods to perform fire-and-forget mutations and methods to compute view models required by specific views. To keep the code understandable, we write functional style code converting raw data objects into immutable view models by default. As we identified performance bottlenecks through profiling, we added caches to avoid recomputing unchanged intermediate results. The resulting functional code is easy to maintain, without sacrificing performance. https://code.facebook.com/posts/498597036962415/under-the-hood-building-moments/
  • 64. Immutable Value Define a value object type whose instances are immutable. The internal state of a value object is set at construction and no subsequent modifications are allowed.
  • 65. const
  • 66. &
  • 67. &&
  • 68. Copied Value Define a value object type whose instances are copyable. When a value is used in communication with another thread, ensure that the value is copied.
  • 69. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... void set_year(int); void set_month(int); void set_day_in_month(int); ... };
  • 70. Just because you have a getter, doesn't mean you should have a matching setter.
  • 71. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... void set(int year, int month, int day_in_month); ... }; today.set(2016, 11, 16);
  • 72. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... }; today = date(2016, 11, 16);
  • 73. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... }; today = date { 2016, 11, 16 };
  • 74. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... }; today = { 2016, 11, 16 };
  • 75. "Get something" is an imperative with an expected side effect.
  • 76. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int get_year() const; int get_month() const; int get_day_in_month() const; ... };
  • 77. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int year() const; int month() const; int day_in_month() const; ... };
  • 78. class date { public: date(int year, int month, int day_in_month); date(const date &); date & operator=(const date &); ... int year() const; int month() const; int day_in_month() const; date with_year(int) const; ... };
  • 79. Builder Introduce a builder that provides separate methods for constructing and disposing of each different part of a complex object, or for combining cumulative changes in the construction of whole objects.
  • 80. class date { public: ... int year() const; int month() const; int day_in_month() const; date with_year(int) const; ... };
  • 81. class date { public: ... int year() const; int month() const; int day_in_month() const; date with_year(int new_year) const { return { new_year, month(), day_in_month() }; } ... };
  • 82. class date { public: ... int year() const; int month() const; int day_in_month() const; date with_year(int new_year) const { return new_year == year ? *this : date { new_year, month(), day_in_month() }; } ... };
  • 83. class date { public: ... int year() const; int month() const; int day_in_month() const; date with_year(int) const; date with_month(int) const; date with_day_in_month(int) const ... };
  • 84. Asking a question should not change the answer. Bertrand Meyer
  • 85. Asking a question should not change the answer, and nor should asking it twice!
  • 86. Referential transparency is a very desirable property: it implies that functions consistently yield the same results given the same input, irrespective of where and when they are invoked. That is, function evaluation depends less—ideally, not at all—on the side effects of mutable state. Edward Garson "Apply Functional Programming Principles"
  • 87. // "FTL" (Functional Template Library :->) // container style template<typename ValueType> class container { public: typedef const ValueType value_type; typedef ... iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; ... container & operator=(const container &); ... };
  • 88. template<typename ValueType> class set { public: typedef const ValueType * iterator; ... set(std::initializer_list<ValueType> values); ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; iterator find(const ValueType &) const; std::size_t count(const ValueType &) const; iterator lower_bound(const ValueType &) const; iterator upper_bound(const ValueType &) const; pair<iterator, iterator> equal_range(const ValueType &) const; ... private: ValueType * members; std::size_t cardinality; }; set<int> c { 2, 9, 9, 7, 9, 2, 4, 5, 8 };
  • 89. template<typename ValueType> class array { public: typedef const ValueType * iterator; ... array(std::initializer_list<ValueType> values); ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; ... private: ValueType * elements; std::size_t length; }; array<int> c { 2, 9, 9, 7, 9, 2, 4, 5, 8 };
  • 90. In computing, a persistent data structure is a data structure that always preserves the previous version of itself when it is modified. Such data structures are effectively immutable, as their operations do not (visibly) update the structure in-place, but instead always yield a new updated structure. http://en.wikipedia.org/wiki/Persistent_data_structure (A persistent data structure is not a data structure committed to persistent storage, such as a disk; this is a different and unrelated sense of the word "persistent.")
  • 91.
  • 92.
  • 93.
  • 94.
  • 95. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector pop_front() const; vector pop_back() const; ... private: ValueType * anchor; iterator from, until; };
  • 96. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector pop_front() const; vector pop_back() const; ... private: ValueType * anchor; iterator from, until; };
  • 97. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector popped_front() const; vector popped_back() const; ... private: ValueType * anchor; iterator from, until; };
  • 98. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector popped_front() const; vector popped_back() const; ... private: ValueType * anchor; iterator from, until; };
  • 99.
  • 100. I still have a deep fondness for the Lisp model. It is simple, elegant, and something with which all developers should have an infatuation at least once in their programming life. Kevlin Henney "A Fair Share (Part I)", CUJ C++ Experts Forum, October 2002
  • 101. lispt
  • 102. template<typename ValueType> class list { public: class iterator; ... std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & front() const; list popped_front() const; list pushed_front() const; ... private: struct link { link(const ValueType & value, link * next); ValueType value; link * next; }; link * head; std::size_t length; };
  • 103. Hamlet: Yea, from the table of my memory I'll wipe away all trivial fond records. William Shakespeare The Tragedy of Hamlet [Act I, Scene 5]
  • 104. Garbage collection [...] is optional in C++; that is, a garbage collector is not a compulsory part of an implementation. Bjarne Stroustrup http://stroustrup.com/C++11FAQ.html
  • 106. Ophelia: 'Tis in my memory locked, and you yourself shall keep the key of it. William Shakespeare The Tragedy of Hamlet [Act I, Scene 3]
  • 107. A use-counted class is more complicated than a non-use- counted equivalent, and all of this horsing around with use counts takes a significant amount of processing time. Robert Murray C++ Strategies and Tactics
  • 108. template<typename ValueType> class vector { public: typedef const ValueType * iterator; ... bool empty() const; std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & operator[](std::size_t) const; const ValueType & front() const; const ValueType & back() const; const ValueType * data() const; vector popped_front() const; vector popped_back() const; ... private: std::shared_ptr<ValueType> anchor; iterator from, until; }; Uses std::default_delete<ValueType[]>, but cannot be initialised from std::make_shared
  • 109. template<typename ValueType> class list { public: class iterator; ... std::size_t size() const; iterator begin() const; iterator end() const; const ValueType & front() const; list popped_front() const; list pushed_front() const; ... private: struct link { link(const ValueType & value, std::shared_ptr<link> next); ValueType value; std::shared_ptr<link> next; }; std::shared_ptr<link> head; std::size_t length; };
  • 110. { list<Anything> chain; std::fill_n( std::front_inserter(chain), how_many, something); } On destruction, deletion of links is recursive through each link, causing the stack to blow up for surprisingly small values of how_many.
  • 111. Instead of using threads and shared memory as our programming model, we can use processes and message passing. Process here just means a protected independent state with executing code, not necessarily an operating system process. Russel Winder "Message Passing Leads to Better Scalability in Parallel Systems"
  • 112. Languages such as Erlang (and occam before it) have shown that processes are a very successful mechanism for programming concurrent and parallel systems. Such systems do not have all the synchronization stresses that shared- memory, multithreaded systems have. Russel Winder "Message Passing Leads to Better Scalability in Parallel Systems"
  • 113.
  • 114. template<typename ValueType> class channel { public: void send(const ValueType &); bool try_receive(ValueType &); private: ... };
  • 115. template<typename ValueType> class channel { public: void send(const ValueType &); bool try_receive(ValueType &); private: std::deque<ValueType> fifo; };
  • 116. template<typename ValueType> class channel { public: void send(const ValueType & to_send) { fifo.push_back(to_send); } ... };
  • 117. template<typename ValueType> class channel { public: ... bool try_receive(ValueType & to_receive) { bool received = false; if (!fifo.empty()) { to_receive = fifo.front(); fifo.pop_front(); received = true; } return received; } ... };
  • 118. template<typename ValueType> class channel { public: void send(const ValueType &); bool try_receive(ValueType &); private: std::mutex key; std::deque<ValueType> fifo; };
  • 119. void send(const ValueType & to_send) { std::lock_guard<std::mutex> guard(key); fifo.push_back(to_send); }
  • 120. bool try_receive(ValueType & to_receive) { bool received = false; if (key.try_lock()) { std::lock_guard<std::mutex> guard(key, std::adopt_lock); if (!fifo.empty()) { to_receive = fifo.front(); fifo.pop_front(); received = true; } } return received; }
  • 121. template<typename ValueType> class channel { public: void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); private: std::mutex key; std::condition_variable_any non_empty; std::deque<ValueType> fifo; };
  • 122. void send(const ValueType & to_send) { std::lock_guard<std::mutex> guard(key); fifo.push_back(to_send); non_empty.notify_all(); }
  • 123. void receive(ValueType & to_receive) { std::lock_guard<std::mutex> guard(key); non_empty.wait( key, [this] { return !fifo.empty(); }); to_receive = fifo.front(); fifo.pop_front(); }
  • 125. std::string fizzbuzz(int n) { return n % 15 == 0 ? "FizzBuzz" : n % 3 == 0 ? "Fizz" : n % 5 == 0 ? "Buzz" : std::to_string(n); }
  • 126. void fizzbuzzer(channel<int> & in, channel<std::string> & out) { for (;;) { int n; in.receive(n); out.send(fizzbuzz(n)); } }
  • 127. int main() { channel<int> out; channel<std::string> back; std::thread fizzbuzzing(fizzbuzzer, out, back) for (int n = 1; n <= 100; ++n) { out.send(n); std::string result; back.receive(result); std::cout << result << "n"; } ... }
  • 128. int main() { channel<int> out; channel<std::string> back; std::thread fizzbuzzing(fizzbuzzer, out, back) for (int n = 1; n <= 100; ++n) { out << n; std::string result; back >> result; std::cout << result << "n"; } ... }
  • 129. void fizzbuzzer(channel<int> & in, channel<std::string> & out) { for (;;) { int n; in >> n; out << fizzbuzz(n); } }
  • 130. template<typename ValueType> class channel { public: void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); void operator<<(const ValueType &); void operator>>(ValueType &); private: std::mutex key; std::condition_variable_any non_empty; std::deque<ValueType> fifo; };
  • 131. template<typename ValueType> class channel { public: void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); void operator<<(const ValueType &); receiving operator>>(ValueType &); private: std::mutex key; std::condition_variable_any non_empty; std::deque<ValueType> fifo; };
  • 132. template<typename ValueType> class channel { public: void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); void operator<<(const ValueType & to_send) { send(to_send); } receiving operator>>(ValueType & to_receive); { return receiving(this, to_receive); } ... };
  • 133. class receiving { public: receiving(channel * that, ValueType & to_receive) : that(that), to_receive(to_receive) { } receiving(receiving && other) : that(other.that), to_receive(other.to_receive) { other.that = nullptr; } operator bool() { auto from = that; that = nullptr; return from && from->try_receive(to_receive); } ~receiving() { if (that) that->receive(to_receive); } private: channel * that; ValueType & to_receive; };
  • 134. std::string fizzbuzz(int n) { if (n < 1 || n > 100) throw std::domain_error( "fizzbuzz(n) is defined for n in [1..100]") return n % 15 == 0 ? "FizzBuzz" : n % 3 == 0 ? "Fizz" : n % 5 == 0 ? "Buzz" : std::to_string(n); }
  • 135. void fizzbuzzer(channel<int> & in, channel<std::any> & out) { for (;;) { try { int n; in >> n; out << fizzbuzz(n); } catch (...) { out << std::current_exception(); } } }
  • 136. int main() { channel<int> out; channel<std::any> back; std::thread fizzbuzzing(fizzbuzzer, out, back) for (int n = 1; n <= 100; ++n) { out << n; std::any result; back >> result; if (result.type() == typeid(std::string)) std::cout << std::any_cast<std::string>(result) << "n"; } ... }
  • 137. template<typename ValueType> class channel { public: channel(); channel(std::function<void(const ValueType &)>); void send(const ValueType &); void receive(ValueType &); bool try_receive(ValueType &); void operator<<(const ValueType &); receiving operator>>(ValueType &); private: std::mutex key; std::condition_variable_any non_empty; std::deque<ValueType> fifo; };
  • 138. int main() { channel<int> out; channel<std::any> back( [](const any & received) { if (received.type() == typeid(std::exception_ptr)) std::rethrow_exception(any_cast<std::exception_ptr>(received)); }); std::thread fizzbuzzing(fizzbuzzer, out, back) ... }
  • 139. int main() { ... for (int n = 1; n <= 100; ++n) { try { out << n; std::any result; back >> result; std::cout << std::any_cast<std::string>(result) << "n"; } catch (std::domain_error & caught) { std::cout << caught.what() << "n"; } } ... }
  • 140. Pipes and Filters Divide the application's task into several self-contained data processing steps and connect these steps to a data processing pipeline via intermediate data buffers.
  • 141. Simple filters that can be arbitrarily chained are more easily re-used, and more robust, than almost any other kind of code. Brandon Rhodes http://rhodesmill.org/brandon/slides/2012-11-pyconca/
  • 142.
  • 143. Multithreading is just one damn thing after, before, or simultaneous with another. Andrei Alexandrescu
  • 144. Actor-based concurrency is just one damn message after another.
  • 145. No matter what language you work in, programming in a functional style provides benefits. You should do it whenever it is convenient, and you should think hard about the decision when it isn't convenient. John Carmack http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
  • 146. Programming in a functional style makes the state presented to your code explicit, which makes it much easier to reason about, and, in a completely pure system, makes thread race conditions impossible. John Carmack http://www.gamasutra.com/view/news/169296/Indepth_Functional_programming_in_C.php
  • 148. All computers wait at the same speed.