Skip to content

Commit

Permalink
fix SFINAE bug
Browse files Browse the repository at this point in the history
  • Loading branch information
marzer committed Jul 26, 2023
1 parent 8c85fee commit 0bdfb36
Show file tree
Hide file tree
Showing 11 changed files with 1,734 additions and 82 deletions.
15 changes: 15 additions & 0 deletions docs/pages.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#intro_motivation table:first-of-type th, td
{
text-align: center;
}

#intro_motivation table:first-of-type th:nth-child(odd)
{
background-color: rgba(255,255,255,0.05);
}

#intro_motivation table:first-of-type td:nth-child(n+11),
#intro_motivation table:first-of-type td:nth-child(-n+5)
{
background-color: rgba(255,255,255,0.05);
}
68 changes: 68 additions & 0 deletions docs/pages/intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
@mainpage soagen: A Structure-of-Arrays generator for C++

@tableofcontents

@section intro_tldr TL;DR

This article is an introduction to, and overview of, **soagen** - a new Structure-Of-Arrays generator
and library for C++. Skip to @ref intro_getting_started if you already know all about SoA and want to give it a try!

@section intro_motivation Motivation

@subsection intro_motivation_typical Typical data layouts (Array of Structures)

Data records in a typical C++ program will be organized into `structs` and/or `classes`, one per 'object' unit type,
and multiples of these will be stored in arrays. For example, a program for managing employee records
might contain something akin to this:

```cpp
struct employee
{
std::string name;
unsigned long long id;
std::tuple<uint16_t, uint8_t, uint8_t> dob;
int salary;
void* tag;
// ... plus a bunch more
};
```

And elsewhere in the program you'd almost certainly find this:

```cpp
std::vector<employee> employees;
```

This paradigm is broadly called [Array of Structures](https://en.wikipedia.org/wiki/AoS_and_SoA) \(AoS\).
Stored this way, the all employee members are laid out sequentially in memory, so the `employees`array would look like this:

@m_class{m-block m-success}

<table>
<tr><th colspan="5"> employees[0] <th colspan="5"> employees[1] <th colspan="5"> employees[2]
<tr><td> `name` <td> `id` <td> `dob` <td> `salary` <td> `tag` <td> `name` <td> `id` <td> `dob` <td> `salary` <td> `tag` <td> `name` <td> `id` <td> `dob` <td> `salary` <td> `tag`
</table>

when iterating over the array depicted above, the CPU's cache will constantly be mostly (or entirely) filled by only a
single `employee`. This is likely fine - most tasks pertaining to `employee` objects are going to want to access
multiple data members, so here the linear layout is is useful. Rare would be the situation where you'd need to loop
over the `employees` and fetch only a single-field.

What about scenarios where you _do_ want to only manipulate a single field of an object, though? Let's say the array
example above had 100,000 `employee` elements, and you wanted to query the total labour cost of your company by summing
up the `salary` member. Suddenly all those cache line hits start to add up and your `calculate_labour_cost()` routine
is slow as hell!

@inline_remark <i>Yes, yes, you wouldn't use C++ for this. It'd be in SQL or similar. This is an example. Put down your pitchforks.</i>

Still, in the general case, the access patterns for an `employee` would likely benefit enough from the current layout
that the benefit of restructuring anything to solve this one specific problem would be minimal at best
(likely even a pessimization).

Let's have a look at a situation where the benefit of restructing away from an explicit object layout is much greater.

@subsection intro_motivation_soa_layout Structure of Arrays

```cpp

```
3 changes: 3 additions & 0 deletions docs/poxy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ changelog = true
#favicon = 'images/favicon.ico'
theme = 'light'
extra_files = ['images/badge-gitter.svg', 'images/badge-sponsor.svg']
stylesheets = ['pages.css']

[warnings]
enabled = true
Expand All @@ -27,6 +28,7 @@ paths = [
'../src/soagen/hpp',
'../src/soagen/hpp/generated',
'../examples/shapes.hpp',
'pages',
]
patterns = ['*.hpp', '*.dox', '*.md']
strip_paths = ['../src/soagen/hpp', '../examples/']
Expand All @@ -43,6 +45,7 @@ paths = ['images']

[code_blocks]
macros = ['SOAGEN_[A-Z0-9_]+?']
types = ['employee']


[badges]
Expand Down
Empty file added examples/employees.cpp
Empty file.
Loading

0 comments on commit 0bdfb36

Please sign in to comment.