Template Class Node¶
Defined in File node.hpp
Class Documentation¶
-
template<size_t
Alignment
, size_tMinStorage
= 72>
classripple
::
Node
¶ Implementation type of a node class, which defines an operation a graph which performs work.
It should be given an alignment which is a multiple of the cache line size so that there is no false sharing of nodes when they are used across threads.
There is a small amount of overhead in the nodes, but they are still cheap In order for the Node’s work to be any callable object, the abstract base class NodeExecutor pointer needs to be stores.
This is not really a problem in terms of storage overhead since ndoes are cache line aligned, and the 8 bytes are usually only a fraction of the cache line size, but it does reduce the available storage for the callable for the executor’s work and more importantly, the arguments for the callable. It is therefore only a problem if the callable has many arguments, or the arguments are large. If this is a problem, a compile time error will be generated, in which case the alignment of the Node can be increased by the cachline size.
Executing the Node’s work then requires invoking the stored callable through the base NodeExecutor class. Benchmarks have shown that the compiler is usually able to remove the virtual function indirection, and the performance is usually the same as a non inlined function call. The major drawback therefore is the loss of the ability for the compiler to inline.
However, the benchmarking also showed that the the cost is approximately 1.1ns for any body of work executed through the NodeExecutor vs 0.25ns for an inlined version. This cost is therfore pretty small, and worth the added flexibility of allowing nodes to have any signature.
The above limitations are also not significant, since the
correct use of nodes in the graph is to perform non trivial workloads. Even a node with a ~30ns workload only incurrs a ~2.5% overhead compared to if the Node’s work body was executed inline. Most work should be in the us to ms range anyway, making the overhead negligible.- Note
The benchmarks were also on very cheap nodes (with small workloads).
- Template Parameters
Alignment
: The aligment for the node.MinStorage
: The number of bytes of storage required for a node.
Public Functions
-
Node
() noexcept = default¶ Default constructor.
-
~Node
() noexcept = default¶ Default destructor.
-
Node
(const Node &other) noexcept¶ Copy constructor which clones the executor and copies the rest of the node state.
- Note
This will check against the executor being a nullptr in debug mode, in release there is not check and a null executor will likely cause a segfault.
- Note
This could be expensive if the node has a lot of successors.
- Note
This does not copy the node’s information. Information for a node is unique and should be allocated and set after copying a noce.
- Parameters
other
: The other node to copy into this node.
-
Node
(Node &&other) noexcept¶ Move constructor which just calls the copy constructor for most of the node data, but moves the successors of the other node into this node.
- Parameters
other
: The other task to move from.
-
template<typename
F
, typename ...Args
, non_node_enable_t<F> = 0>Node
(F &&callable, Args&&... args) noexcept¶ Constructs the node, creating its executor by storing the callable and the callable’s arguments in the additional storage for the node.
- Note
This constructor is only enabled if F is not a Node.
- Note
If the callable and its arguments will not fit into the node storage then this will fail at compile time and the size of the node will need to be increased.
- Parameters
callable
: The callable object to store.args
: The arguments to store.
- Template Parameters
F
: The type of the callable object.Args
: The type of the arguments for the callable.
-
auto
operator=
(const Node &other) noexcept -> Node&¶ Copy assignment overload which clones the executor and copies the node state.
- Note
This will check against the other node’s executor being a nullptr in debug, but will likely cause a segfault in release.
- Note
This does not copy the node information, which should be unique and therefore allocated and then set after copying the node.
- Return
A reference to the new node.
- Parameters
other
: The other node to copy.
-
auto
operator=
(Node &&other) noexcept -> Node&¶ Move assignment overload which clones the executor, copies the other node state, moves the other node’s successors, and invalidates the other node.
- Note
This will check against the other node’s executor being a nullptr in debug, in release it will likely cause a segfault.
- Return
A reference to the new node.
- Parameters
other
: The other node to move from.
-
template<typename
F
, typename ...Args
>
autoset_executor
(F &&callable, Args&&... args) noexcept -> void¶ Sets the executor of the node to use the given callable and its args.
- Note
This will check that there is enough space in the node storage for the callable and its arguments. If there is not enough space, a compile time error is generated with the required additional number of bytes.
- Parameters
callable
: The callable object to store.args
: The arguments to store.
- Template Parameters
F
: The type of the callable object.Args
: The type of the arguments for the callable.
-
auto
try_run
() noexcept -> bool¶ Tries to run the node.
- Return
true if the node has no dependencies and therefore executes, otherwise returns false.
-
auto
add_successor
(Node &node) noexcept -> void¶ Add sthe given node as a successor for this node.
- Parameters
node
: The node to add as a successor to this node.
-
auto
add_friend
(typename NodeInfo::IdType friend_id) noexcept -> void¶ Adds the node with the given id as a friend of this node.
For example, if x is a friend of y, then y
uses x for an operation, and x cannot be modified by any operations on it until y has performed its operation.- Note
A friend node is a node which can execute in parallel with another node, but which is used by the other node for the other node’s operation, but is not modified by it.
- Parameters
friend_id
: The id of the friend to add.
-
auto
friends
() const noexcept -> typename NodeInfo::Friends&¶ Gets all friends for the node.
- Return
A container of all friend node ids.
-
auto
increment_num_dependents
() noexcept -> void¶ Increments the number of dependents for the node.
-
auto
name
() const noexcept -> typename NodeInfo::Name¶ Gets the name of the node.
- Return
the name of the node.
-
auto
id
() const noexcept -> typename NodeInfo::IdType¶ Gets the id of the node.
- Return
The id of the node.
-
auto
execution_kind
() const noexcept -> ExecutionKind¶ Gets the execution target for the node.
- Return
The kind of the execution target for the node.
-
auto
num_dependents
() const noexcept -> CounterValue¶ Gets the number of dependents for the node.
- Return
The number of dependents for the node.