SlideShare ist ein Scribd-Unternehmen logo
1 von 146
Downloaden Sie, um offline zu lesen
From Zero to Iterators
Building and Extending the Iterator Hierarchy in a Modern, Multicore World
Patrick M. Niedzielski
pniedzielski.net
0
I’ve heard of iterators before.
0
I’ve used iterators before.
0
I like iterators.
0
I love iterators.
0
I really love iterators.
0
I think iterators are fundamental to computer science.
0
0
The goal
✓ I’ve heard of iterators before.
✓ I’ve used iterators before.
(✓) I love iterators.
× I think iterators are fundamental to computer science.
1
The goal
✓ I’ve heard of iterators before.
✓ I’ve used iterators before.
(✓) I love iterators.
× I think iterators are fundamental to computer science. (Ask me offline!)
1
How we’ll get there
Iterators 101: Introduction to Iterators
Iterators 301: Advanced Iterators
2
How we’ll get there
Iterators 101: Introduction to Iterators
Iterators 301: Advanced Iterators
2
How we’ll get there
Iterators 101: Introduction to Iterators
Iterators 301: Advanced Iterators
Generic Programming
2
What this talk is not
• An introduction to the STL.
• A comprehensive guide to Concepts Lite.
3
A note about questions
4
Iterators 101
A simple starting point
template <typename T>
T* copy(T const* in, T const* in_end,
T* out, T* out_end)
{
while (in != in_end && out != out_end) *out++ = *in++;
return out;
}
5
A simple starting point
auto source = array<T, 5>{ /* ... */ };
auto destination = array<T, 10>{ /* ... */ };
copy(
&source[0], &source[0] + size(source),
&destination[0], &destination[0] + size(destination)
);
6
But we don’t just deal with arrays…
template <typename T>
struct node
{
T value;
node* next;
};
7
But we don’t just deal with arrays…
template <typename T>
struct node
{
T value;
node* next;
};
T{…} T{…} T{…} T{…} T{…} ∅
7
But we don’t just deal with arrays…
template <typename T>
node<T>* copy(node<T> const* in, node<T> const* in_end,
node<T>* out, node<T>* out_end)
{
while (in != in_end && out != out_end) {
out->value = in->value;
in = in->next;
out = out->next;
}
return out;
}
8
But we don’t just deal with arrays…
template <typename T>
T* copy(node<T> const* in, node<T> const* in_end,
T* out, T* out_end)
{
while (in != in_end && out != out_end) {
*out++ = in->value;
in = in->next;
}
return out;
}
9
But we don’t just deal with arrays…
template <typename T>
ostream& copy(T const* in, T const* in_end, ostream& out)
{
while (in != in_end && out) out << *in++;
return out;
}
10
So what?
10
So what?
• Array → Array
• Singly-Linked List → Singly-Linked List
• Singly-Linked List → Array
• Array → Stream
11
So what?
• Array → Array
• Singly-Linked List → Singly-Linked List
• Singly-Linked List → Array
• Array → Stream
But also,
• Array → Singly-Linked List
• Singly-Linked List → Stream
• Stream → Array
• Stream → Singly-Linked List
• Stream → Stream
3 × 3 = 9 functions
11
So what?
4 × 4 = 16 functions
12
So what?
5 × 5 = 25 functions
13
So what?
6 × 6 = 36 functions
14
So what?
7 × 7 = 49 functions
15
So what?
7 × 7 × 2 = 98 functions!
16
So what?
7 × 7 × 3 = 147 functions!
17
So what?
7 × 7 × 4 = 196 functions!
18
So what?
m data structures, n algorithms,
n · m2 functions!
19
We must be missing something.
19
Let’s back up.
20
Let’s back up.
template <typename T>
output copy(input sequence, output sequence)
{
while (input not empty && output not empty) {
write output = read input;
increment output;
increment input;
}
return output;
}
20
Generalization
• T const*
• node<T> const*
• istream&
• …
21
Generalization
• T const*
• node<T> const*
• istream&
• …
• T*
• node<T>*
• ostream&
• …
21
Generalization
• T const*
• node<T> const*
• istream&
• …
• T*
• node<T>*
• ostream&
• …
Iterators
21
Generalization
template <typename T>
output copy(input sequence, output sequence)
{
while (input not empty && output not empty) {
write output = read input;
increment output;
increment input;
}
return output;
}
22
Generalization
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
write output = read input;
increment output;
increment input;
}
return out;
}
23
Generalization
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
write output = source(in); // e.g., *in
increment output;
increment input;
}
return out;
}
24
Generalization
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in); // e.g., *out
increment output;
increment input;
}
return out;
}
25
Generalization
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
26
Generalization
inline auto const& source(auto const* p) { return *p; }
inline auto const& source(node<auto> const* p) { return p->value; }
inline auto& sink(auto* p) { return *p; }
inline auto& sink(node<auto>* p) { return p->value; }
inline auto successor(auto const* p) { return p + 1; }
inline auto successor(node<auto> const* p) { return p->next; }
27
Let’s get formal.
27
What do we need?
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
28
What do we need?
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
Equality Comparison
28
What do we need?
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
Assignment
29
What do we need?
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
Construction
30
What do we need?
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
Destruction
31
What do we need?
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
successor()
32
What do we need?
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
source()
33
What do we need?
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
sink()
34
What do we need?
InputIterator
• Constructible
• Destructible
• Assignable
• Equality Comparable
• successor()
• source()
OutputIterator
• Constructible
• Destructible
• Assignable
• Equality Comparable
• successor()
• sink()
35
What do we need?
InputIterator
Regular
• Constructible
• Destructible
• Assignable
• Equality Comparable
• successor()
• source()
OutputIterator
Regular
• Constructible
• Destructible
• Assignable
• Equality Comparable
• successor()
• sink()
35
What do we need?
InputIterator
Regular
• Constructible
• Destructible
• Assignable
• Equality Comparable
Iterator
• successor()
• source()
OutputIterator
Regular
• Constructible
• Destructible
• Assignable
• Equality Comparable
Iterator
• successor()
• sink()
35
What do we need?
InputIterator
Regular
• Constructible
• Destructible
• Assignable
• Equality Comparable
Iterator
• successor()
Readable
• source()
OutputIterator
Regular
• Constructible
• Destructible
• Assignable
• Equality Comparable
Iterator
• successor()
Writable
• sink()
35
Concepts!
35
Concepts!
template <typename T>
concept bool Concept = /* constexpr boolean expression */;
36
Concepts!
template <typename T>
concept bool Regular =
is_default_constructible_v<T>
&& is_copy_constructible_v<T>
&& is_destructible_v<T>
&& is_copy_assignable_v<T>
&& is_equality_comparable_v<T>;
37
Concepts!
template <typename T>
concept bool Regular =
is_default_constructible_v<T>
&& is_copy_constructible_v<T>
&& is_destructible_v<T>
&& is_copy_assignable_v<T>
&& is_equality_comparable_v<T>;
37
Concepts!
template <typename T>
concept bool Regular =
is_default_constructible_v<T>
&& is_copy_constructible_v<T>
&& is_destructible_v<T>
&& is_copy_assignable_v<T>
&& is_equality_comparable_v<T>;
Doesn’t exist.
37
Concepts!
template <typename T>
concept bool Regular =
is_default_constructible_v<T>
&& is_copy_constructible_v<T>
&& is_destructible_v<T>
&& is_copy_assignable_v<T>
&& ∀x, y ∈ T:
1. x == y can be used in boolean contexts
2. == induces an equivalence relation on T
3. Iff x == y, x and y represent the same value
;
38
Concepts!
template <typename T>
concept bool Regular =
is_default_constructible_v<T>
&& is_copy_constructible_v<T>
&& is_destructible_v<T>
&& is_copy_assignable_v<T>
&& requires(T x, T y) {
1. x == y can be used in boolean contexts
2. == induces an equivalence relation on T
3. Iff x == y, x and y represent the same value
};
39
Concepts!
template <typename T>
concept bool Regular =
is_default_constructible_v<T>
&& is_copy_constructible_v<T>
&& is_destructible_v<T>
&& is_copy_assignable_v<T>
&& requires(T x, T y) {
{ x == y } -> bool;
2. == induces an equivalence relation on T
3. Iff x == y, x and y represent the same value
};
40
Concepts!
template <typename T>
concept bool Regular =
is_default_constructible_v<T>
&& is_copy_constructible_v<T>
&& is_destructible_v<T>
&& is_copy_assignable_v<T>
&& requires(T x, T y) {
{ x == y } -> bool;
// == induces an equivalence relation on T
// Iff x == y, x and y represent the same value
};
41
Concepts!
template <typename T>
concept bool Readable =
requires (T x) {
typename value_type<T>;
{ source(x) } -> value_type<T> const&; // O(1)
};
42
Concepts!
template <typename T>
concept bool Writable =
requires (T x) {
typename value_type<T>;
{ sink(x) } -> value_type<T>&; // O(1)
};
43
Concepts!
template <typename I>
concept bool Iterator =
Regular<I> &&
requires (I i) {
{ successor(i) } -> I; // O(1)
// successor() may mutate other iterators.
};
44
Concepts!
template <typename InputIterator, typename OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
45
Concepts!
template <typename InputIterator, typename OutputIterator>
requires Iterator<InputIterator>
&& Readable<InputIterator>
&& Iterator<OutputIterator>
&& Writable<OutputIterator>
OutputIterator copy(InputIterator in, InputIterator in_end
OutputIterator out, OutputIterator out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
46
Concepts!
template <typename In, typename Out>
requires Iterator<In>
&& Readable<In>
&& Iterator<Out>
&& Writable<Out>
Out copy(In in, In in_end, Out out, Out out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
47
Concepts!
template <Iterator In, Iterator Out>
requires Readable<In> && Writable<Out>
Out copy(In in, In in_end, Out out, Out out_end)
{
while (in != in_end && out != out_end) {
sink(out) = source(in);
out = successor(out);
in = successor(in);
}
return out;
}
48
More algorithms
template <Iterator It>
requires Writable<It>
void fill(It it, It it_end, value_type<It> const& x)
{
while (in != in_end) {
sink(out) = x;
it = successor(it);
}
}
49
More algorithms
template <Iterator It, Function<value_type<It>, value_type<It>> Op>
requires Readable<It>
auto fold(It it, It it_end, value_type<It> acc, Op op)
{
while (in != in_end) {
acc = op(acc, source(it));
it = successor(it);
}
return acc;
}
50
More algorithms
template <Iterator It>
requires Readable<It>
It find_first(It it, It it_end, value_type<It> const& value)
{
while (it != it_end && source(it) != value)
it = successor(it);
return it;
}
51
Moving Forward
52
Moving Forward
template <Iterator It>
requires Readable<It>
It max_element(It it, It it_end)
{
auto max_it = it;
while (it != it_end) {
if (source(it) > source(max_it)) max_it = it;
it = successor(it);
}
return max_it;
}
52
Moving Forward
template <Iterator It>
requires Readable<It>
It max_element(It it, It it_end)
{
auto max_it = it;
while (it != it_end) {
if (source(it) > source(max_it)) max_it = it;
it = successor(it);
}
return max_it;
}
No!
52
Moving Forward
template <typename I>
concept bool Iterator =
Regular<I> &&
requires (I i) {
{ successor(i) } -> I; // O(1)
// successor may mutate other iterators
};
53
Moving Forward
template <typename I>
concept bool Iterator =
Regular<I> &&
requires (I i) {
{ successor(i) } -> I; // O(1)
// successor may mutate other iterators
};
53
Moving Forward
template <typename I>
concept bool ForwardIterator =
Regular<I> &&
requires (I i) {
{ successor(i) } -> I; // O(1)
};
54
Moving Forward
template <typename I>
concept bool ForwardIterator =
Regular<I> &&
requires (I i) {
{ successor(i) } -> I; // O(1)
};
Multi-pass Guarantee
54
Moving Forward
template <ForwardIterator It>
requires Readable<It>
It max_element(It it, It it_end)
{
auto max_it = it;
while (it != it_end) {
if (source(it) > source(max_it)) max_it = it;
it = successor(it);
}
return max_it;
}
55
Moving Forward
Proposition
If a type T models ForwardIterator, it also models Iterator.
56
Moving Forward
Proposition
If a type T models ForwardIterator, it also models Iterator.
A ForwardIterator is just an Iterator that doesn’t mutate other iterators in
successor()!
56
Backing Up
57
Backing Up
template <??? I>
requires Readable<I> && Writable<I>
I reverse(I it_begin, I it_end)
{
while (it_begin != it_end) {
it_end = predecessor(it_end);
if (it_begin == it_end) break;
auto temp = source(it_end);
sink(it_end) = source(it_begin);
sink(it_begin) = temp;
it_begin = successor(it_begin);
}
}
57
Backing Up
template <??? I>
requires Readable<I> && Writable<I>
I reverse(I it_begin, I it_end)
{
while (it_begin != it_end) {
it_end = predecessor(it_end);
if (it_begin == it_end) break;
auto temp = source(it_end);
sink(it_end) = source(it_begin);
sink(it_begin) = temp;
it_begin = successor(it_begin);
}
}
57
Backing Up
template <typename I>
concept bool BidirectionalIterator =
Regular<I> &&
requires (I i) {
{ successor(i) } -> I; // O(1)
{ predecessor(i) } -> I; // O(1)
// i == predecessor(successor(i));
};
58
Backing Up
template <BidirectionalIterator I>
requires Readable<I> && Writable<I>
I reverse(I it_begin, I it_end)
{
while (it_begin != it_end) {
it_end = predecessor(it_end);
if (it_begin == it_end) break;
auto temp = source(it_end);
sink(it_end) = source(it_begin);
sink(it_begin) = temp;
it_begin = successor(it_begin);
}
}
59
Backing Up
template <BidirectionalIterator I>
requires Readable<I> && Writable<I>
I reverse(I it_begin, I it_end)
{
while (it_begin != it_end) {
it_end = predecessor(it_end);
if (it_begin == it_end) break;
auto temp = source(it_end);
sink(it_end) = source(it_begin);
sink(it_begin) = temp;
it_begin = successor(it_begin);
}
}
60
Backing Up
Proposition
If a type T models BidirectionalIterator, it also models
ForwardIterator.
61
Backing Up
Proposition
If a type T models BidirectionalIterator, it also models
ForwardIterator.
A BidirectionalIterator has a successor() function that does not
mutate other iterators.
61
Backing Up
Proposition
If a type T models BidirectionalIterator, its dual also models
BidirectionalIterator.
62
Backing Up
Proposition
If a type T models BidirectionalIterator, its dual also models
BidirectionalIterator.
Let’s define a type whose successor() is our old predecessor() and whose
predecessor() is our old successor(). This new type also models
BidirectionalIterator.
62
Backing Up
Proposition
If a type T models BidirectionalIterator, its dual also models
BidirectionalIterator.
Let’s define a type whose successor() is our old predecessor() and whose
predecessor() is our old successor(). This new type also models
BidirectionalIterator.
We call the dual of a BidirectionalIterator a reverse iterator.
62
Jumping Around
63
Jumping Around
template <ForwardIterator It>
void increment(It& i, size_t n)
{
// Precondition: n >= 0
for (auto i = 0; i < n; ++i) i = successor(i);
}
63
Jumping Around
template <ForwardIterator It>
void increment(It& i, size_t n)
{
// Precondition: n >= 0
for (auto i = 0; i < n; ++i) i = successor(i);
}
void increment(auto*& i, size_t n)
{
// Precondition: n >= 0
i += n;
}
63
Jumping Around
template <BidirectionalIterator It>
void decrement(It& i, size_t n)
{
// Precondition: n >= 0
for (auto i = 0; i < n; ++i) i = predecessor(i);
}
void decrement(auto*& i, size_t n)
{
// Precondition: n >= 0
i -= n;
}
64
Jumping Around
template <typename I>
concept bool RandomAccessIterator =
Regular<I>
&& WeaklyOrdered<I>
&& requires (I i, I j, size_t n) {
{ i + n } -> I; // O(1)
// i + 0 == i if n == 0
// i + n == successor(i) + n - 1 if n > 0
// i + n == predecessor(i) + n + 1 if n < 0
{ i - n } -> I; // O(1)
// i - 0 == i if n == 0
// i - n == predecessor(i) - (n - 1) if n > 0
// i - n == successor(i) - (n + 1) if n < 0
{ i - j } -> size_t; // O(1)
// i + (i - j) = i
};
65
Jumping Around
template <RandomAccessIterator It>
requires Readable<It> && WeaklyOrdered<value_type<It>>
I upper_bound(It it, It it_end, value_type<It> x)
{
// Base case.
if (it == it_end) return it_end;
// mid_dist is always less than or equal to end - begin,
// because of integer division
auto mid_dist = (it_end - it) / 2;
auto mid = it + mid_dist;
// Reduce problem size.
if (source(mid) <= x) return upper_bound(mid + 1, it_end, x);
else return upper_bound( it, mid + 1, x);
}
66
Jumping Around
Proposition
If a type T models RandomAccessIterator, it also models
BidirectionalIterator.
67
Jumping Around
Proposition
If a type T models RandomAccessIterator, it also models
BidirectionalIterator.
Let’s define successor() on an object x of type T to return x + 1. Similarly,
let’s define predecessor() to return x - 1.
67
The story so far
Iterator
Forward
Bidir
Random
68
Extending the Iterator Hierarchy
Pop Quiz!
68
Can I memmove a RandomAccess sequence of bytes?
68
Let’s look at the concept
template <typename I>
concept bool RandomAccessIterator =
Regular<I>
&& WeaklyOrdered<I>
&& requires (I i, I j, size_t n) {
{ i + n } -> I; // O(1)
// i + 0 == i if n == 0
// i + n == successor(i) + n - 1 if n > 0
// i + n == predecessor(i) + n + 1 if n < 0
{ i - n } -> I; // O(1)
// i - 0 == i if n == 0
// i - n == predecessor(i) - (n - 1) if n > 0
// i - n == successor(i) - (n + 1) if n < 0
{ i - j } -> size_t; // O(1)
// i + (i - j) = i
};
69
No!
69
A counterexample
template <Regular T>
struct segmented_array {
vector< vector<T> > data;
// where each inner vector except the last has size segsize
};
70
A counterexample
template <Regular T>
struct segmented_array_iterator {
vector<T>* spine_iter;
size_t inner_index;
};
template <Regular T>
segmented_array_iterator<T> operator+(
segmented_array_iterator<T> it, size_t n)
{
return segmented_array_iterator<T>{
it.spine_iter + (it.inner_index + n) / segsize,
(it.inner_index + n) % segsize
};
}
71
What does memmove need?
72
What does memmove need?
• Trivially copyable data, that is
72
What does memmove need?
• Trivially copyable data, that is
• contiguous in memory.
72
What does contiguous mean?
73
What does contiguous mean?
auto i = /* ... */;
auto j = /* ... */;
pointer_from(i + n) == pointer_from(i) + n;
pointer_from(i - n) == pointer_from(i) - n;
pointer_from(i - j) == pointer_from(i) - pointer_from(j);
73
What does contiguous mean?
auto i = /* ... */;
auto j = /* ... */;
pointer_from(i + n) == pointer_from(i) + n;
pointer_from(i - n) == pointer_from(i) - n;
pointer_from(i - j) == pointer_from(i) - pointer_from(j);
There must be an homomorphism pointer_from that preserves the range
structure.
73
The simplest homomorphism
auto* pointer_from(auto* i) { return i; }
74
The slightly less simple homomorphism
template <typename T>
using base_offset_iterator = pair<T*, size_t>;
auto* pointer_from(base_offset_iterator<auto> i)
{
return i.first + i.second;
}
75
Looks like we have a new concept!
template <typename T>
concept bool ContiguousIterator =
RandomAccessIterator<T>
&& requires (T i) {
typename value_type<T>;
{ pointer_from(i) } -> value_type<T> const*;
// pointer_from homomorphism preserves range
// structure
};
76
Looks like we have a new concept!
template <ContiguousIterator In, ContiguousIterator Out>
requires Readable<In> && Writable<Out>
&& is_same_v< value_type<In>, value_type<Out> >
&& is_trivially_copyable_v< value_type<In> >
Out copy(In in, In in_end, Out out, Out out_end)
{
auto count = min( in_end - in, out_end - out );
memmove(pointer_from(out), pointer_from(in), count);
return out_end;
}
77
Segmentation Problems
78
Segmentation Problems
template <Regular T>
struct segmented_array {
vector< vector<T> > data;
// where each inner vector except the last has size segsize
};
78
Segmentation Problems
template <SegmentedIterator In, Iterator Out>
requires Readable<In> && Writable<Out>
Out copy(In in, In in_end, Out out, Out out_end)
{
auto seg = segment(in);
auto seg_end = segment(in_end);
if (seg == seg_end) copy(local(in), local(in_end), out, out_end);
else {
out = copy(local(in), end(seg), out, out_end);
seg = successor(seg);
while (seg != seg_end) {
out = copy(begin(seg), end(seg), out, out_end);
seg = successor(seg);
}
return copy(begin(seg), local(in_end), out, out_end);
}
}
79
Segmentation Problems
template <typename T>
concept bool SegmentedIterator =
Iterator<T>
&& requires (T i) {
typename local_iterator<T>;
typename segment_iterator<T>;
requires Iterator<local_iterator>;
requires Iterator<segment_iterator>;
requires Range<segment_iterator>; // begin(), end()
{ local(i) } -> local_iterator<T>;
{ segment(i) } -> segment_iterator<T>;
};
80
Segmentation Problems
// Associated types
template <typename T>
using local_iterator< segmented_array_iterator<T> > = T*;
template <typename T>
using segment_iterator< segmented_array_iterator<T> > = vector<T>*;
// Inner iterator range (dirty, to fit on slides!)
auto begin(vector<auto>* vec) { return vec->begin(); }
auto end(vector<auto>* vec) { return vec->end(); }
// Access functions
auto local(segmented_array_iterator<auto> it) {
return &it->spine_iter[it->inner_index];
}
auto segment(segmented_array_iterator<auto> it) {
return it->spine_iter;
} 81
SegmentedIterators are great for parallelization.
82
SegmentedIterators are great for parallelization.
template <RandomAccessIterator In, SegmentedIterator Out>
requires Readable<In> && Writable<Out>
&& RandomAccessIterator<Out>
Out copy(In in, In in_end, Out out, Out out_end)
{
auto& task_pool = get_global_task_pool();
auto seg = segment(out);
auto seg_end = segment(out_end);
if (seg == seg_end) {
// ...
} else {
// ...
}
}
82
SegmentedIterators are great for parallelization.
if (seg == seg_end) {
return copy(in, in_end, local(out), local(out_end));
} else {
// ...
}
83
SegmentedIterators are great for parallelization.
} else {
task_pool.add_task(copy, in, in_end, local(out), end(seg_end));
seg = successor(seg);
in = in + min(in_end - in, end(seg_end) - local(out));
while (seg != seg_end) {
task_pool.add_task(copy, in, in_end, begin(seg), end(seg));
seg = successor(seg);
in = in + min(in_end - in, end(seg) - begin(seg));
}
task_pool.add_task(copy, in, in_end, begin(seg), local(out_end));
return out + min(in_end - in, local(out_end) - begin(out));
}
84
But wait!
84
SegmentedIterators are great for parallelization.
84
ContiguousIterators are great for bit blasting.
84
What if we combine them?
84
Cache-awareness
template <typename T>
concept bool CacheAwareIterator =
SegmentedIterator<T>
&& ContiguousIterator<T>;
85
Cache-awareness
Since,
• each thread is fed its own set of cache lines,
86
Cache-awareness
Since,
• each thread is fed its own set of cache lines,
• no two threads will be writing to the same cache lines,
86
Cache-awareness
Since,
• each thread is fed its own set of cache lines,
• no two threads will be writing to the same cache lines,
• no false-sharing.
86
86
References
• Austern, Matthew H (1998). Segmented Iterators and Hierarchical Algorithms.
In Proceedings of Generic Programming: International Seminar, Dagstuhl
Castle, Germany.
• Liber, Nevin (2014). N3884 — Contiguous Iterators: A Refinement of Random
Access Iterators.
• Stepanov, Alexander and Paul McJones (2009). Elements of Programming.
87
Patrick M. Niedzielski
pniedzielski.net
This work is licensed under a Creative Commons “Attribution 4.0 Inter-
national” license.
87

Weitere ähnliche Inhalte

Was ist angesagt?

Python for High School Programmers
Python for High School ProgrammersPython for High School Programmers
Python for High School ProgrammersSiva Arunachalam
 
Cs hangman
Cs   hangmanCs   hangman
Cs hangmaniamkim
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009Jordan Baker
 
Pre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPaweł Dawczak
 
How to avoid Go gotchas - Ivan Daniluk - Codemotion Milan 2016
How to avoid Go gotchas - Ivan Daniluk - Codemotion Milan 2016How to avoid Go gotchas - Ivan Daniluk - Codemotion Milan 2016
How to avoid Go gotchas - Ivan Daniluk - Codemotion Milan 2016Codemotion
 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcescorehard_by
 
An Intro to Python in 30 minutes
An Intro to Python in 30 minutesAn Intro to Python in 30 minutes
An Intro to Python in 30 minutesSumit Raj
 
CS50 Lecture3
CS50 Lecture3CS50 Lecture3
CS50 Lecture3昀 李
 
Dip Your Toes in the Sea of Security (PHP MiNDS January Meetup 2016)
Dip Your Toes in the Sea of Security (PHP MiNDS January Meetup 2016)Dip Your Toes in the Sea of Security (PHP MiNDS January Meetup 2016)
Dip Your Toes in the Sea of Security (PHP MiNDS January Meetup 2016)James Titcumb
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxyginecorehard_by
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Class 5: If, while & lists
Class 5: If, while & listsClass 5: If, while & lists
Class 5: If, while & listsMarc Gouw
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to pythonAhmed Salama
 
Class 2: Welcome part 2
Class 2: Welcome part 2Class 2: Welcome part 2
Class 2: Welcome part 2Marc Gouw
 
Optionals Swift - Swift Paris Junior #3
Optionals Swift - Swift Paris Junior #3 Optionals Swift - Swift Paris Junior #3
Optionals Swift - Swift Paris Junior #3 LouiseFonteneau
 
Programming Lisp Clojure - 2장 : 클로저 둘러보기
Programming Lisp Clojure - 2장 : 클로저 둘러보기Programming Lisp Clojure - 2장 : 클로저 둘러보기
Programming Lisp Clojure - 2장 : 클로저 둘러보기JangHyuk You
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersLin Yo-An
 

Was ist angesagt? (20)

Python for High School Programmers
Python for High School ProgrammersPython for High School Programmers
Python for High School Programmers
 
Cs hangman
Cs   hangmanCs   hangman
Cs hangman
 
Python Tutorial
Python TutorialPython Tutorial
Python Tutorial
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
 
Pre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to Elixir
 
Embedding perl
Embedding perlEmbedding perl
Embedding perl
 
How to avoid Go gotchas - Ivan Daniluk - Codemotion Milan 2016
How to avoid Go gotchas - Ivan Daniluk - Codemotion Milan 2016How to avoid Go gotchas - Ivan Daniluk - Codemotion Milan 2016
How to avoid Go gotchas - Ivan Daniluk - Codemotion Milan 2016
 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resources
 
An Intro to Python in 30 minutes
An Intro to Python in 30 minutesAn Intro to Python in 30 minutes
An Intro to Python in 30 minutes
 
CS50 Lecture3
CS50 Lecture3CS50 Lecture3
CS50 Lecture3
 
Dip Your Toes in the Sea of Security (PHP MiNDS January Meetup 2016)
Dip Your Toes in the Sea of Security (PHP MiNDS January Meetup 2016)Dip Your Toes in the Sea of Security (PHP MiNDS January Meetup 2016)
Dip Your Toes in the Sea of Security (PHP MiNDS January Meetup 2016)
 
Python: The Dynamic!
Python: The Dynamic!Python: The Dynamic!
Python: The Dynamic!
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxygine
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Class 5: If, while & lists
Class 5: If, while & listsClass 5: If, while & lists
Class 5: If, while & lists
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
 
Class 2: Welcome part 2
Class 2: Welcome part 2Class 2: Welcome part 2
Class 2: Welcome part 2
 
Optionals Swift - Swift Paris Junior #3
Optionals Swift - Swift Paris Junior #3 Optionals Swift - Swift Paris Junior #3
Optionals Swift - Swift Paris Junior #3
 
Programming Lisp Clojure - 2장 : 클로저 둘러보기
Programming Lisp Clojure - 2장 : 클로저 둘러보기Programming Lisp Clojure - 2장 : 클로저 둘러보기
Programming Lisp Clojure - 2장 : 클로저 둘러보기
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
 

Andere mochten auch

Building Hierarchy
Building HierarchyBuilding Hierarchy
Building HierarchyMohamed Samy
 
Structure, hierarchy and functions of pakistani courts
Structure, hierarchy and functions of pakistani courtsStructure, hierarchy and functions of pakistani courts
Structure, hierarchy and functions of pakistani courtsFahad Ur Rehman Khan
 
The building blocks of visual hierarchy
The building blocks of visual hierarchyThe building blocks of visual hierarchy
The building blocks of visual hierarchyHalil Eren Çelik
 
Visual Hierarchy 1, 2, 3
Visual Hierarchy 1, 2, 3Visual Hierarchy 1, 2, 3
Visual Hierarchy 1, 2, 3Jared Ponchot
 
Hierarchy of courts in pakistan
Hierarchy of courts in pakistanHierarchy of courts in pakistan
Hierarchy of courts in pakistanFatima Butt
 
Rhythm in architecture
Rhythm in architectureRhythm in architecture
Rhythm in architectureMario Pathaw
 
Unity, Balance, Scale & Proportion, Contrast, Emphasis & Repetition & Rhythm
Unity, Balance, Scale & Proportion, Contrast, Emphasis & Repetition & RhythmUnity, Balance, Scale & Proportion, Contrast, Emphasis & Repetition & Rhythm
Unity, Balance, Scale & Proportion, Contrast, Emphasis & Repetition & Rhythmtanyalangford
 
Principles of design theory of design module 2 proportion,scale, hierarchy etc
Principles of design theory of design module 2   proportion,scale, hierarchy etcPrinciples of design theory of design module 2   proportion,scale, hierarchy etc
Principles of design theory of design module 2 proportion,scale, hierarchy etcStanly Sunny
 
Yale Art + Architecture Building - Case Study
Yale Art + Architecture Building - Case StudyYale Art + Architecture Building - Case Study
Yale Art + Architecture Building - Case StudyVikram Bengani
 
03 architectural principles & elements
03 architectural principles & elements03 architectural principles & elements
03 architectural principles & elementsJan Echiverri-Quintano
 

Andere mochten auch (10)

Building Hierarchy
Building HierarchyBuilding Hierarchy
Building Hierarchy
 
Structure, hierarchy and functions of pakistani courts
Structure, hierarchy and functions of pakistani courtsStructure, hierarchy and functions of pakistani courts
Structure, hierarchy and functions of pakistani courts
 
The building blocks of visual hierarchy
The building blocks of visual hierarchyThe building blocks of visual hierarchy
The building blocks of visual hierarchy
 
Visual Hierarchy 1, 2, 3
Visual Hierarchy 1, 2, 3Visual Hierarchy 1, 2, 3
Visual Hierarchy 1, 2, 3
 
Hierarchy of courts in pakistan
Hierarchy of courts in pakistanHierarchy of courts in pakistan
Hierarchy of courts in pakistan
 
Rhythm in architecture
Rhythm in architectureRhythm in architecture
Rhythm in architecture
 
Unity, Balance, Scale & Proportion, Contrast, Emphasis & Repetition & Rhythm
Unity, Balance, Scale & Proportion, Contrast, Emphasis & Repetition & RhythmUnity, Balance, Scale & Proportion, Contrast, Emphasis & Repetition & Rhythm
Unity, Balance, Scale & Proportion, Contrast, Emphasis & Repetition & Rhythm
 
Principles of design theory of design module 2 proportion,scale, hierarchy etc
Principles of design theory of design module 2   proportion,scale, hierarchy etcPrinciples of design theory of design module 2   proportion,scale, hierarchy etc
Principles of design theory of design module 2 proportion,scale, hierarchy etc
 
Yale Art + Architecture Building - Case Study
Yale Art + Architecture Building - Case StudyYale Art + Architecture Building - Case Study
Yale Art + Architecture Building - Case Study
 
03 architectural principles & elements
03 architectural principles & elements03 architectural principles & elements
03 architectural principles & elements
 

Ähnlich wie Build and Extend the Iterator Hierarchy in a Modern, Multicore World

Python Peculiarities
Python PeculiaritiesPython Peculiarities
Python Peculiaritiesnoamt
 
2 BytesC++ course_2014_c2_ flow of control
2 BytesC++ course_2014_c2_ flow of control 2 BytesC++ course_2014_c2_ flow of control
2 BytesC++ course_2014_c2_ flow of control kinan keshkeh
 
2 BytesC++ course_2014_c9_ pointers and dynamic arrays
2 BytesC++ course_2014_c9_ pointers and dynamic arrays 2 BytesC++ course_2014_c9_ pointers and dynamic arrays
2 BytesC++ course_2014_c9_ pointers and dynamic arrays kinan keshkeh
 
Add an interactive command line to your C++ application
Add an interactive command line to your C++ applicationAdd an interactive command line to your C++ application
Add an interactive command line to your C++ applicationDaniele Pallastrelli
 
Низкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложенийНизкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложенийAndrey Akinshin
 
Un monde où 1 ms vaut 100 M€ - Devoxx France 2015
Un monde où 1 ms vaut 100 M€ - Devoxx France 2015Un monde où 1 ms vaut 100 M€ - Devoxx France 2015
Un monde où 1 ms vaut 100 M€ - Devoxx France 2015ThierryAbalea
 
JOI夏季セミナー2021 ステップアップ講義|12 章:いろいろなソート・乱択アルゴリズム
JOI夏季セミナー2021 ステップアップ講義|12 章:いろいろなソート・乱択アルゴリズムJOI夏季セミナー2021 ステップアップ講義|12 章:いろいろなソート・乱択アルゴリズム
JOI夏季セミナー2021 ステップアップ講義|12 章:いろいろなソート・乱択アルゴリズムE869120 E869120
 
C++ Standard Template Library
C++ Standard Template LibraryC++ Standard Template Library
C++ Standard Template LibraryIlio Catallo
 
Basic Python Programming: Part 01 and Part 02
Basic Python Programming: Part 01 and Part 02Basic Python Programming: Part 01 and Part 02
Basic Python Programming: Part 01 and Part 02Fariz Darari
 
So I am writing a CS code for a project and I keep getting cannot .pdf
So I am writing a CS code for a project and I keep getting cannot .pdfSo I am writing a CS code for a project and I keep getting cannot .pdf
So I am writing a CS code for a project and I keep getting cannot .pdfezonesolutions
 
10 Recursion
10 Recursion10 Recursion
10 Recursionmaznabili
 
Maze solving app listing
Maze solving app listingMaze solving app listing
Maze solving app listingChris Worledge
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionPaulo Morgado
 
Introduction to programming - class 11
Introduction to programming - class 11Introduction to programming - class 11
Introduction to programming - class 11Paul Brebner
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parserkamaelian
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 

Ähnlich wie Build and Extend the Iterator Hierarchy in a Modern, Multicore World (20)

Python Peculiarities
Python PeculiaritiesPython Peculiarities
Python Peculiarities
 
2 BytesC++ course_2014_c2_ flow of control
2 BytesC++ course_2014_c2_ flow of control 2 BytesC++ course_2014_c2_ flow of control
2 BytesC++ course_2014_c2_ flow of control
 
2 BytesC++ course_2014_c9_ pointers and dynamic arrays
2 BytesC++ course_2014_c9_ pointers and dynamic arrays 2 BytesC++ course_2014_c9_ pointers and dynamic arrays
2 BytesC++ course_2014_c9_ pointers and dynamic arrays
 
Php 2
Php 2Php 2
Php 2
 
Add an interactive command line to your C++ application
Add an interactive command line to your C++ applicationAdd an interactive command line to your C++ application
Add an interactive command line to your C++ application
 
Низкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложенийНизкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложений
 
Python Part 1
Python Part 1Python Part 1
Python Part 1
 
Un monde où 1 ms vaut 100 M€ - Devoxx France 2015
Un monde où 1 ms vaut 100 M€ - Devoxx France 2015Un monde où 1 ms vaut 100 M€ - Devoxx France 2015
Un monde où 1 ms vaut 100 M€ - Devoxx France 2015
 
JOI夏季セミナー2021 ステップアップ講義|12 章:いろいろなソート・乱択アルゴリズム
JOI夏季セミナー2021 ステップアップ講義|12 章:いろいろなソート・乱択アルゴリズムJOI夏季セミナー2021 ステップアップ講義|12 章:いろいろなソート・乱択アルゴリズム
JOI夏季セミナー2021 ステップアップ講義|12 章:いろいろなソート・乱択アルゴリズム
 
C++ Standard Template Library
C++ Standard Template LibraryC++ Standard Template Library
C++ Standard Template Library
 
Basic Python Programming: Part 01 and Part 02
Basic Python Programming: Part 01 and Part 02Basic Python Programming: Part 01 and Part 02
Basic Python Programming: Part 01 and Part 02
 
So I am writing a CS code for a project and I keep getting cannot .pdf
So I am writing a CS code for a project and I keep getting cannot .pdfSo I am writing a CS code for a project and I keep getting cannot .pdf
So I am writing a CS code for a project and I keep getting cannot .pdf
 
10 Recursion
10 Recursion10 Recursion
10 Recursion
 
Maze solving app listing
Maze solving app listingMaze solving app listing
Maze solving app listing
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf Edition
 
Introduction to programming - class 11
Introduction to programming - class 11Introduction to programming - class 11
Introduction to programming - class 11
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
Useful c programs
Useful c programsUseful c programs
Useful c programs
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parser
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 

Kürzlich hochgeladen

Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 

Kürzlich hochgeladen (20)

Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 

Build and Extend the Iterator Hierarchy in a Modern, Multicore World

  • 1. From Zero to Iterators Building and Extending the Iterator Hierarchy in a Modern, Multicore World Patrick M. Niedzielski pniedzielski.net
  • 2. 0
  • 3. I’ve heard of iterators before. 0
  • 7. I really love iterators. 0
  • 8. I think iterators are fundamental to computer science. 0
  • 9. 0
  • 10. The goal ✓ I’ve heard of iterators before. ✓ I’ve used iterators before. (✓) I love iterators. × I think iterators are fundamental to computer science. 1
  • 11. The goal ✓ I’ve heard of iterators before. ✓ I’ve used iterators before. (✓) I love iterators. × I think iterators are fundamental to computer science. (Ask me offline!) 1
  • 12. How we’ll get there Iterators 101: Introduction to Iterators Iterators 301: Advanced Iterators 2
  • 13. How we’ll get there Iterators 101: Introduction to Iterators Iterators 301: Advanced Iterators 2
  • 14. How we’ll get there Iterators 101: Introduction to Iterators Iterators 301: Advanced Iterators Generic Programming 2
  • 15. What this talk is not • An introduction to the STL. • A comprehensive guide to Concepts Lite. 3
  • 16. A note about questions 4
  • 18. A simple starting point template <typename T> T* copy(T const* in, T const* in_end, T* out, T* out_end) { while (in != in_end && out != out_end) *out++ = *in++; return out; } 5
  • 19. A simple starting point auto source = array<T, 5>{ /* ... */ }; auto destination = array<T, 10>{ /* ... */ }; copy( &source[0], &source[0] + size(source), &destination[0], &destination[0] + size(destination) ); 6
  • 20. But we don’t just deal with arrays… template <typename T> struct node { T value; node* next; }; 7
  • 21. But we don’t just deal with arrays… template <typename T> struct node { T value; node* next; }; T{…} T{…} T{…} T{…} T{…} ∅ 7
  • 22. But we don’t just deal with arrays… template <typename T> node<T>* copy(node<T> const* in, node<T> const* in_end, node<T>* out, node<T>* out_end) { while (in != in_end && out != out_end) { out->value = in->value; in = in->next; out = out->next; } return out; } 8
  • 23. But we don’t just deal with arrays… template <typename T> T* copy(node<T> const* in, node<T> const* in_end, T* out, T* out_end) { while (in != in_end && out != out_end) { *out++ = in->value; in = in->next; } return out; } 9
  • 24. But we don’t just deal with arrays… template <typename T> ostream& copy(T const* in, T const* in_end, ostream& out) { while (in != in_end && out) out << *in++; return out; } 10
  • 26. So what? • Array → Array • Singly-Linked List → Singly-Linked List • Singly-Linked List → Array • Array → Stream 11
  • 27. So what? • Array → Array • Singly-Linked List → Singly-Linked List • Singly-Linked List → Array • Array → Stream But also, • Array → Singly-Linked List • Singly-Linked List → Stream • Stream → Array • Stream → Singly-Linked List • Stream → Stream 3 × 3 = 9 functions 11
  • 28. So what? 4 × 4 = 16 functions 12
  • 29. So what? 5 × 5 = 25 functions 13
  • 30. So what? 6 × 6 = 36 functions 14
  • 31. So what? 7 × 7 = 49 functions 15
  • 32. So what? 7 × 7 × 2 = 98 functions! 16
  • 33. So what? 7 × 7 × 3 = 147 functions! 17
  • 34. So what? 7 × 7 × 4 = 196 functions! 18
  • 35. So what? m data structures, n algorithms, n · m2 functions! 19
  • 36. We must be missing something. 19
  • 38. Let’s back up. template <typename T> output copy(input sequence, output sequence) { while (input not empty && output not empty) { write output = read input; increment output; increment input; } return output; } 20
  • 39. Generalization • T const* • node<T> const* • istream& • … 21
  • 40. Generalization • T const* • node<T> const* • istream& • … • T* • node<T>* • ostream& • … 21
  • 41. Generalization • T const* • node<T> const* • istream& • … • T* • node<T>* • ostream& • … Iterators 21
  • 42. Generalization template <typename T> output copy(input sequence, output sequence) { while (input not empty && output not empty) { write output = read input; increment output; increment input; } return output; } 22
  • 43. Generalization template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { write output = read input; increment output; increment input; } return out; } 23
  • 44. Generalization template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { write output = source(in); // e.g., *in increment output; increment input; } return out; } 24
  • 45. Generalization template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); // e.g., *out increment output; increment input; } return out; } 25
  • 46. Generalization template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } 26
  • 47. Generalization inline auto const& source(auto const* p) { return *p; } inline auto const& source(node<auto> const* p) { return p->value; } inline auto& sink(auto* p) { return *p; } inline auto& sink(node<auto>* p) { return p->value; } inline auto successor(auto const* p) { return p + 1; } inline auto successor(node<auto> const* p) { return p->next; } 27
  • 49. What do we need? template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } 28
  • 50. What do we need? template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } Equality Comparison 28
  • 51. What do we need? template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } Assignment 29
  • 52. What do we need? template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } Construction 30
  • 53. What do we need? template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } Destruction 31
  • 54. What do we need? template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } successor() 32
  • 55. What do we need? template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } source() 33
  • 56. What do we need? template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } sink() 34
  • 57. What do we need? InputIterator • Constructible • Destructible • Assignable • Equality Comparable • successor() • source() OutputIterator • Constructible • Destructible • Assignable • Equality Comparable • successor() • sink() 35
  • 58. What do we need? InputIterator Regular • Constructible • Destructible • Assignable • Equality Comparable • successor() • source() OutputIterator Regular • Constructible • Destructible • Assignable • Equality Comparable • successor() • sink() 35
  • 59. What do we need? InputIterator Regular • Constructible • Destructible • Assignable • Equality Comparable Iterator • successor() • source() OutputIterator Regular • Constructible • Destructible • Assignable • Equality Comparable Iterator • successor() • sink() 35
  • 60. What do we need? InputIterator Regular • Constructible • Destructible • Assignable • Equality Comparable Iterator • successor() Readable • source() OutputIterator Regular • Constructible • Destructible • Assignable • Equality Comparable Iterator • successor() Writable • sink() 35
  • 62. Concepts! template <typename T> concept bool Concept = /* constexpr boolean expression */; 36
  • 63. Concepts! template <typename T> concept bool Regular = is_default_constructible_v<T> && is_copy_constructible_v<T> && is_destructible_v<T> && is_copy_assignable_v<T> && is_equality_comparable_v<T>; 37
  • 64. Concepts! template <typename T> concept bool Regular = is_default_constructible_v<T> && is_copy_constructible_v<T> && is_destructible_v<T> && is_copy_assignable_v<T> && is_equality_comparable_v<T>; 37
  • 65. Concepts! template <typename T> concept bool Regular = is_default_constructible_v<T> && is_copy_constructible_v<T> && is_destructible_v<T> && is_copy_assignable_v<T> && is_equality_comparable_v<T>; Doesn’t exist. 37
  • 66. Concepts! template <typename T> concept bool Regular = is_default_constructible_v<T> && is_copy_constructible_v<T> && is_destructible_v<T> && is_copy_assignable_v<T> && ∀x, y ∈ T: 1. x == y can be used in boolean contexts 2. == induces an equivalence relation on T 3. Iff x == y, x and y represent the same value ; 38
  • 67. Concepts! template <typename T> concept bool Regular = is_default_constructible_v<T> && is_copy_constructible_v<T> && is_destructible_v<T> && is_copy_assignable_v<T> && requires(T x, T y) { 1. x == y can be used in boolean contexts 2. == induces an equivalence relation on T 3. Iff x == y, x and y represent the same value }; 39
  • 68. Concepts! template <typename T> concept bool Regular = is_default_constructible_v<T> && is_copy_constructible_v<T> && is_destructible_v<T> && is_copy_assignable_v<T> && requires(T x, T y) { { x == y } -> bool; 2. == induces an equivalence relation on T 3. Iff x == y, x and y represent the same value }; 40
  • 69. Concepts! template <typename T> concept bool Regular = is_default_constructible_v<T> && is_copy_constructible_v<T> && is_destructible_v<T> && is_copy_assignable_v<T> && requires(T x, T y) { { x == y } -> bool; // == induces an equivalence relation on T // Iff x == y, x and y represent the same value }; 41
  • 70. Concepts! template <typename T> concept bool Readable = requires (T x) { typename value_type<T>; { source(x) } -> value_type<T> const&; // O(1) }; 42
  • 71. Concepts! template <typename T> concept bool Writable = requires (T x) { typename value_type<T>; { sink(x) } -> value_type<T>&; // O(1) }; 43
  • 72. Concepts! template <typename I> concept bool Iterator = Regular<I> && requires (I i) { { successor(i) } -> I; // O(1) // successor() may mutate other iterators. }; 44
  • 73. Concepts! template <typename InputIterator, typename OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } 45
  • 74. Concepts! template <typename InputIterator, typename OutputIterator> requires Iterator<InputIterator> && Readable<InputIterator> && Iterator<OutputIterator> && Writable<OutputIterator> OutputIterator copy(InputIterator in, InputIterator in_end OutputIterator out, OutputIterator out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } 46
  • 75. Concepts! template <typename In, typename Out> requires Iterator<In> && Readable<In> && Iterator<Out> && Writable<Out> Out copy(In in, In in_end, Out out, Out out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } 47
  • 76. Concepts! template <Iterator In, Iterator Out> requires Readable<In> && Writable<Out> Out copy(In in, In in_end, Out out, Out out_end) { while (in != in_end && out != out_end) { sink(out) = source(in); out = successor(out); in = successor(in); } return out; } 48
  • 77. More algorithms template <Iterator It> requires Writable<It> void fill(It it, It it_end, value_type<It> const& x) { while (in != in_end) { sink(out) = x; it = successor(it); } } 49
  • 78. More algorithms template <Iterator It, Function<value_type<It>, value_type<It>> Op> requires Readable<It> auto fold(It it, It it_end, value_type<It> acc, Op op) { while (in != in_end) { acc = op(acc, source(it)); it = successor(it); } return acc; } 50
  • 79. More algorithms template <Iterator It> requires Readable<It> It find_first(It it, It it_end, value_type<It> const& value) { while (it != it_end && source(it) != value) it = successor(it); return it; } 51
  • 81. Moving Forward template <Iterator It> requires Readable<It> It max_element(It it, It it_end) { auto max_it = it; while (it != it_end) { if (source(it) > source(max_it)) max_it = it; it = successor(it); } return max_it; } 52
  • 82. Moving Forward template <Iterator It> requires Readable<It> It max_element(It it, It it_end) { auto max_it = it; while (it != it_end) { if (source(it) > source(max_it)) max_it = it; it = successor(it); } return max_it; } No! 52
  • 83. Moving Forward template <typename I> concept bool Iterator = Regular<I> && requires (I i) { { successor(i) } -> I; // O(1) // successor may mutate other iterators }; 53
  • 84. Moving Forward template <typename I> concept bool Iterator = Regular<I> && requires (I i) { { successor(i) } -> I; // O(1) // successor may mutate other iterators }; 53
  • 85. Moving Forward template <typename I> concept bool ForwardIterator = Regular<I> && requires (I i) { { successor(i) } -> I; // O(1) }; 54
  • 86. Moving Forward template <typename I> concept bool ForwardIterator = Regular<I> && requires (I i) { { successor(i) } -> I; // O(1) }; Multi-pass Guarantee 54
  • 87. Moving Forward template <ForwardIterator It> requires Readable<It> It max_element(It it, It it_end) { auto max_it = it; while (it != it_end) { if (source(it) > source(max_it)) max_it = it; it = successor(it); } return max_it; } 55
  • 88. Moving Forward Proposition If a type T models ForwardIterator, it also models Iterator. 56
  • 89. Moving Forward Proposition If a type T models ForwardIterator, it also models Iterator. A ForwardIterator is just an Iterator that doesn’t mutate other iterators in successor()! 56
  • 91. Backing Up template <??? I> requires Readable<I> && Writable<I> I reverse(I it_begin, I it_end) { while (it_begin != it_end) { it_end = predecessor(it_end); if (it_begin == it_end) break; auto temp = source(it_end); sink(it_end) = source(it_begin); sink(it_begin) = temp; it_begin = successor(it_begin); } } 57
  • 92. Backing Up template <??? I> requires Readable<I> && Writable<I> I reverse(I it_begin, I it_end) { while (it_begin != it_end) { it_end = predecessor(it_end); if (it_begin == it_end) break; auto temp = source(it_end); sink(it_end) = source(it_begin); sink(it_begin) = temp; it_begin = successor(it_begin); } } 57
  • 93. Backing Up template <typename I> concept bool BidirectionalIterator = Regular<I> && requires (I i) { { successor(i) } -> I; // O(1) { predecessor(i) } -> I; // O(1) // i == predecessor(successor(i)); }; 58
  • 94. Backing Up template <BidirectionalIterator I> requires Readable<I> && Writable<I> I reverse(I it_begin, I it_end) { while (it_begin != it_end) { it_end = predecessor(it_end); if (it_begin == it_end) break; auto temp = source(it_end); sink(it_end) = source(it_begin); sink(it_begin) = temp; it_begin = successor(it_begin); } } 59
  • 95. Backing Up template <BidirectionalIterator I> requires Readable<I> && Writable<I> I reverse(I it_begin, I it_end) { while (it_begin != it_end) { it_end = predecessor(it_end); if (it_begin == it_end) break; auto temp = source(it_end); sink(it_end) = source(it_begin); sink(it_begin) = temp; it_begin = successor(it_begin); } } 60
  • 96. Backing Up Proposition If a type T models BidirectionalIterator, it also models ForwardIterator. 61
  • 97. Backing Up Proposition If a type T models BidirectionalIterator, it also models ForwardIterator. A BidirectionalIterator has a successor() function that does not mutate other iterators. 61
  • 98. Backing Up Proposition If a type T models BidirectionalIterator, its dual also models BidirectionalIterator. 62
  • 99. Backing Up Proposition If a type T models BidirectionalIterator, its dual also models BidirectionalIterator. Let’s define a type whose successor() is our old predecessor() and whose predecessor() is our old successor(). This new type also models BidirectionalIterator. 62
  • 100. Backing Up Proposition If a type T models BidirectionalIterator, its dual also models BidirectionalIterator. Let’s define a type whose successor() is our old predecessor() and whose predecessor() is our old successor(). This new type also models BidirectionalIterator. We call the dual of a BidirectionalIterator a reverse iterator. 62
  • 102. Jumping Around template <ForwardIterator It> void increment(It& i, size_t n) { // Precondition: n >= 0 for (auto i = 0; i < n; ++i) i = successor(i); } 63
  • 103. Jumping Around template <ForwardIterator It> void increment(It& i, size_t n) { // Precondition: n >= 0 for (auto i = 0; i < n; ++i) i = successor(i); } void increment(auto*& i, size_t n) { // Precondition: n >= 0 i += n; } 63
  • 104. Jumping Around template <BidirectionalIterator It> void decrement(It& i, size_t n) { // Precondition: n >= 0 for (auto i = 0; i < n; ++i) i = predecessor(i); } void decrement(auto*& i, size_t n) { // Precondition: n >= 0 i -= n; } 64
  • 105. Jumping Around template <typename I> concept bool RandomAccessIterator = Regular<I> && WeaklyOrdered<I> && requires (I i, I j, size_t n) { { i + n } -> I; // O(1) // i + 0 == i if n == 0 // i + n == successor(i) + n - 1 if n > 0 // i + n == predecessor(i) + n + 1 if n < 0 { i - n } -> I; // O(1) // i - 0 == i if n == 0 // i - n == predecessor(i) - (n - 1) if n > 0 // i - n == successor(i) - (n + 1) if n < 0 { i - j } -> size_t; // O(1) // i + (i - j) = i }; 65
  • 106. Jumping Around template <RandomAccessIterator It> requires Readable<It> && WeaklyOrdered<value_type<It>> I upper_bound(It it, It it_end, value_type<It> x) { // Base case. if (it == it_end) return it_end; // mid_dist is always less than or equal to end - begin, // because of integer division auto mid_dist = (it_end - it) / 2; auto mid = it + mid_dist; // Reduce problem size. if (source(mid) <= x) return upper_bound(mid + 1, it_end, x); else return upper_bound( it, mid + 1, x); } 66
  • 107. Jumping Around Proposition If a type T models RandomAccessIterator, it also models BidirectionalIterator. 67
  • 108. Jumping Around Proposition If a type T models RandomAccessIterator, it also models BidirectionalIterator. Let’s define successor() on an object x of type T to return x + 1. Similarly, let’s define predecessor() to return x - 1. 67
  • 109. The story so far Iterator Forward Bidir Random 68
  • 112. Can I memmove a RandomAccess sequence of bytes? 68
  • 113. Let’s look at the concept template <typename I> concept bool RandomAccessIterator = Regular<I> && WeaklyOrdered<I> && requires (I i, I j, size_t n) { { i + n } -> I; // O(1) // i + 0 == i if n == 0 // i + n == successor(i) + n - 1 if n > 0 // i + n == predecessor(i) + n + 1 if n < 0 { i - n } -> I; // O(1) // i - 0 == i if n == 0 // i - n == predecessor(i) - (n - 1) if n > 0 // i - n == successor(i) - (n + 1) if n < 0 { i - j } -> size_t; // O(1) // i + (i - j) = i }; 69
  • 114. No! 69
  • 115. A counterexample template <Regular T> struct segmented_array { vector< vector<T> > data; // where each inner vector except the last has size segsize }; 70
  • 116. A counterexample template <Regular T> struct segmented_array_iterator { vector<T>* spine_iter; size_t inner_index; }; template <Regular T> segmented_array_iterator<T> operator+( segmented_array_iterator<T> it, size_t n) { return segmented_array_iterator<T>{ it.spine_iter + (it.inner_index + n) / segsize, (it.inner_index + n) % segsize }; } 71
  • 117. What does memmove need? 72
  • 118. What does memmove need? • Trivially copyable data, that is 72
  • 119. What does memmove need? • Trivially copyable data, that is • contiguous in memory. 72
  • 120. What does contiguous mean? 73
  • 121. What does contiguous mean? auto i = /* ... */; auto j = /* ... */; pointer_from(i + n) == pointer_from(i) + n; pointer_from(i - n) == pointer_from(i) - n; pointer_from(i - j) == pointer_from(i) - pointer_from(j); 73
  • 122. What does contiguous mean? auto i = /* ... */; auto j = /* ... */; pointer_from(i + n) == pointer_from(i) + n; pointer_from(i - n) == pointer_from(i) - n; pointer_from(i - j) == pointer_from(i) - pointer_from(j); There must be an homomorphism pointer_from that preserves the range structure. 73
  • 123. The simplest homomorphism auto* pointer_from(auto* i) { return i; } 74
  • 124. The slightly less simple homomorphism template <typename T> using base_offset_iterator = pair<T*, size_t>; auto* pointer_from(base_offset_iterator<auto> i) { return i.first + i.second; } 75
  • 125. Looks like we have a new concept! template <typename T> concept bool ContiguousIterator = RandomAccessIterator<T> && requires (T i) { typename value_type<T>; { pointer_from(i) } -> value_type<T> const*; // pointer_from homomorphism preserves range // structure }; 76
  • 126. Looks like we have a new concept! template <ContiguousIterator In, ContiguousIterator Out> requires Readable<In> && Writable<Out> && is_same_v< value_type<In>, value_type<Out> > && is_trivially_copyable_v< value_type<In> > Out copy(In in, In in_end, Out out, Out out_end) { auto count = min( in_end - in, out_end - out ); memmove(pointer_from(out), pointer_from(in), count); return out_end; } 77
  • 128. Segmentation Problems template <Regular T> struct segmented_array { vector< vector<T> > data; // where each inner vector except the last has size segsize }; 78
  • 129. Segmentation Problems template <SegmentedIterator In, Iterator Out> requires Readable<In> && Writable<Out> Out copy(In in, In in_end, Out out, Out out_end) { auto seg = segment(in); auto seg_end = segment(in_end); if (seg == seg_end) copy(local(in), local(in_end), out, out_end); else { out = copy(local(in), end(seg), out, out_end); seg = successor(seg); while (seg != seg_end) { out = copy(begin(seg), end(seg), out, out_end); seg = successor(seg); } return copy(begin(seg), local(in_end), out, out_end); } } 79
  • 130. Segmentation Problems template <typename T> concept bool SegmentedIterator = Iterator<T> && requires (T i) { typename local_iterator<T>; typename segment_iterator<T>; requires Iterator<local_iterator>; requires Iterator<segment_iterator>; requires Range<segment_iterator>; // begin(), end() { local(i) } -> local_iterator<T>; { segment(i) } -> segment_iterator<T>; }; 80
  • 131. Segmentation Problems // Associated types template <typename T> using local_iterator< segmented_array_iterator<T> > = T*; template <typename T> using segment_iterator< segmented_array_iterator<T> > = vector<T>*; // Inner iterator range (dirty, to fit on slides!) auto begin(vector<auto>* vec) { return vec->begin(); } auto end(vector<auto>* vec) { return vec->end(); } // Access functions auto local(segmented_array_iterator<auto> it) { return &it->spine_iter[it->inner_index]; } auto segment(segmented_array_iterator<auto> it) { return it->spine_iter; } 81
  • 132. SegmentedIterators are great for parallelization. 82
  • 133. SegmentedIterators are great for parallelization. template <RandomAccessIterator In, SegmentedIterator Out> requires Readable<In> && Writable<Out> && RandomAccessIterator<Out> Out copy(In in, In in_end, Out out, Out out_end) { auto& task_pool = get_global_task_pool(); auto seg = segment(out); auto seg_end = segment(out_end); if (seg == seg_end) { // ... } else { // ... } } 82
  • 134. SegmentedIterators are great for parallelization. if (seg == seg_end) { return copy(in, in_end, local(out), local(out_end)); } else { // ... } 83
  • 135. SegmentedIterators are great for parallelization. } else { task_pool.add_task(copy, in, in_end, local(out), end(seg_end)); seg = successor(seg); in = in + min(in_end - in, end(seg_end) - local(out)); while (seg != seg_end) { task_pool.add_task(copy, in, in_end, begin(seg), end(seg)); seg = successor(seg); in = in + min(in_end - in, end(seg) - begin(seg)); } task_pool.add_task(copy, in, in_end, begin(seg), local(out_end)); return out + min(in_end - in, local(out_end) - begin(out)); } 84
  • 137. SegmentedIterators are great for parallelization. 84
  • 138. ContiguousIterators are great for bit blasting. 84
  • 139. What if we combine them? 84
  • 140. Cache-awareness template <typename T> concept bool CacheAwareIterator = SegmentedIterator<T> && ContiguousIterator<T>; 85
  • 141. Cache-awareness Since, • each thread is fed its own set of cache lines, 86
  • 142. Cache-awareness Since, • each thread is fed its own set of cache lines, • no two threads will be writing to the same cache lines, 86
  • 143. Cache-awareness Since, • each thread is fed its own set of cache lines, • no two threads will be writing to the same cache lines, • no false-sharing. 86
  • 144. 86
  • 145. References • Austern, Matthew H (1998). Segmented Iterators and Hierarchical Algorithms. In Proceedings of Generic Programming: International Seminar, Dagstuhl Castle, Germany. • Liber, Nevin (2014). N3884 — Contiguous Iterators: A Refinement of Random Access Iterators. • Stepanov, Alexander and Paul McJones (2009). Elements of Programming. 87
  • 146. Patrick M. Niedzielski pniedzielski.net This work is licensed under a Creative Commons “Attribution 4.0 Inter- national” license. 87