SlideShare a Scribd company logo
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

More Related Content

What's hot

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
 
Python Tutorial
Python TutorialPython Tutorial
Python Tutorial
Eueung Mulyana
 
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
Jordan Baker
 
Pre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to ElixirPre-Bootcamp introduction to Elixir
Pre-Bootcamp introduction to Elixir
Paweł Dawczak
 
Embedding perl
Embedding perlEmbedding perl
Embedding perl
Marian Marinov
 
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
Codemotion
 
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
corehard_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 minutes
Sumit 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
 
Python: The Dynamic!
Python: The Dynamic!Python: The Dynamic!
Python: The Dynamic!
Omid Mogharian
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxygine
corehard_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 & lists
Marc Gouw
 
Introduction to python
Introduction to pythonIntroduction to python
Introduction to python
Ahmed Salama
 
Class 2: Welcome part 2
Class 2: Welcome part 2Class 2: Welcome part 2
Class 2: Welcome part 2
Marc 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
 

What's hot (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
 

Viewers also liked

Building Hierarchy
Building HierarchyBuilding Hierarchy
Building Hierarchy
Mohamed 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 courts
Fahad 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 hierarchy
Halil Eren Çelik
 
Visual Hierarchy 1, 2, 3
Visual Hierarchy 1, 2, 3Visual Hierarchy 1, 2, 3
Visual Hierarchy 1, 2, 3
Jared Ponchot
 
Hierarchy of courts in pakistan
Hierarchy of courts in pakistanHierarchy of courts in pakistan
Hierarchy of courts in pakistan
Fatima Butt
 
Rhythm in architecture
Rhythm in architectureRhythm in architecture
Rhythm in architecture
Mario 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 & Rhythm
tanyalangford
 
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
Stanly Sunny
 
Yale Art + Architecture Building - Case Study
Yale Art + Architecture Building - Case StudyYale Art + Architecture Building - Case Study
Yale Art + Architecture Building - Case Study
Vikram Bengani
 
03 architectural principles & elements
03 architectural principles & elements03 architectural principles & elements
03 architectural principles & elementsJan Echiverri-Quintano
 

Viewers also liked (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
 

Similar to From Zero to Iterators: Building and Extending the Iterator Hierarchy in a Modern, Multicore World

Python Peculiarities
Python PeculiaritiesPython Peculiarities
Python Peculiarities
noamt
 
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++ application
Daniele Pallastrelli
 
Низкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложенийНизкоуровневые оптимизации .NET-приложений
Низкоуровневые оптимизации .NET-приложений
Andrey Akinshin
 
Python Part 1
Python Part 1Python Part 1
Python Part 1
Mohamed Ramadan
 
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
ThierryAbalea
 
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 Library
Ilio 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 02
Fariz 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 .pdf
ezonesolutions
 
10 Recursion
10 Recursion10 Recursion
10 Recursion
maznabili
 
Maze solving app listing
Maze solving app listingMaze solving app listing
Maze solving app listing
Chris 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 Edition
Paulo Morgado
 
Introduction to programming - class 11
Introduction to programming - class 11Introduction to programming - class 11
Introduction to programming - class 11
Paul 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
 
Useful c programs
Useful c programsUseful c programs
Useful c programs
MD SHAH FAHAD
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parser
kamaelian
 
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
Michael Pirnat
 

Similar to From Zero to Iterators: Building and Extending 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
 

Recently uploaded

GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
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
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
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
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
Gerardo Pardo-Castellote
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
lorraineandreiamcidl
 
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
 
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
 

Recently uploaded (20)

GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
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)
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
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
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
 
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
 
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
 

From Zero to Iterators: Building and Extending 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