- All right, good evening everybody.
Thank you so much for being here.
And today, I'm going to talk about
fast parallel programming
using Modern C++.
And I'm going to show you
a very cool open source
project called CPP-Taskflow.
And it's a open source project
about how to make the parallel
programming easier to handle.
I believe everyone over here all agrees
parallel programming is
a super important skill,
and you should have known that, right?
And it's all about how to
maximize the performance
of your software, in other words,
you can scale up your program across
a different number of CPUs.
And at the same time
though, parallel programming
is not a very trivial task to do.
And the main reason to this
is the task dependency.
Some task has to finish
before some other task.
And some task has to finish
after some other task.
And because of this dependency,
we always have to worry
about, be very careful about
the risk condition, where
we create multiple threads
to help us do multiple
thing at the same time.
Then we use lock to protect
the section of the code
such that only one thread can access
a particular region at the same time.
This also gives us the
issue of thread contention.
Multiple threads are waiting
for the lock on there
to release the resource of the lock
while they are not
actually doing anything.
But they can really a lot
of re-cip-ri-al resources.
And if something goes wrong,
we move to the most painful
state, which is debugging.
And we all agree, debugging
a parallel programming
is extremely painful.
With that being said,
people try really hard
to hard-code a lot of
time the task dependency
when writing a parallel program.
For example, suppose we are
running a kitchen brigade,
where we have two line cooks
working on the meat and garnish,
one chef working on the plating,
putting together meat and
garnish together to the plates,
and two waiters doing the service
and delivering food to two hungry diners.
And like you can see, we have five tasks
plus four dependencies.
And we cannot start plating
until meat and garnish are finished.
Similarly, we cannot serve
food until plating finishes.
Well in terms of C++ code,
we usually clarify fast
to represent our kitchen brigade.
Cook one, cook two, chef,
waiter one and waiter two,
and then we will create three variables
to initialize too fast,
to represent the state
of the readiness of these dishes.
Then when cook one finish the garnish,
he will mark the variable to true.
And similarly, when cook
two finish the meat,
he will mark the variable to true.
When chef start his task,
he has to spin waiter
and these two variables
until they become true
before he can move to
the next instruction.
And similarly for waiter
one and waiter two,
they have to spin waiter on this variable,
and when it become true,
before he can move to
the next instruction.
Well this is a solution, but everything
is very pretty much hard-coded,
and we explicitly create threads
to elicit atomic variables
to do this manual locking control.
And this just turns out to be very messy
and we don't like this.
This code doesn't scale out very well.
So we come up with a better solution
in open source project,
called Cpp-Taskflow.
In a nutshell, Cpp-Taskflow
is C++ hed-on-ly library,
to help you quickly parallel
program with task dependencies.
And this is how it looks
with Cpp-Taskflow to the previous example.
So first, we will create a taskflow object
to represent the kitchen flow.
And then we will create five tasks
for cook one, cook two, chef,
waiter one and waiter two.
And then we will use the matter precede.
You see a matter precede over here
to represent which task has
to run before which task,
and which task has to
run after other task.
And once we specify these precedents
between different tasks,
then we can use this
wait for all matter to dispatch the task.
And the taskflow object
will automatically handle
all these difficult
concurrency control for you.
You don't really need to worry
about those thread management
and block control by yourself,
which turns out to be very tedious.
We also support dynamic tasking,
and this is a very helpful
feature of the library.
This is a way for you to create
a task dependency graph at the runtime,
and particularly very
useful for many application
where you cannot decide
a task dependency graph
before running the program.
So feel free to check out
our github and give it a try.
Thank you.
