Skip to content

Commit

Permalink
cpponsea2024
Browse files Browse the repository at this point in the history
  • Loading branch information
kris-jusiak committed Jun 30, 2024
1 parent c433ce0 commit 139bd3c
Showing 1 changed file with 57 additions and 18 deletions.
75 changes: 57 additions & 18 deletions cpponsea2024/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1609,42 +1609,80 @@

#### string_to_enum - Minimal perfect hashing

#### bit mixer - magic
```cpp
enum uri { ftp = 0, file = 1, http = 2, ws = 3, wss = 4, };
```
<!-- .element: class="fragment" style="float:left" data-fragment-index="0" -->

---

#### bit mixer
<!-- .element: class="fragment" style="float:left" data-fragment-index="1" -->
<br />

```cpp
(value * magic) >> shift
```
<!-- .element: class="fragment" data-fragment-index="1" -->
<!-- .element: class="fragment" data-fragment-index="2" -->

```cpp
// shift
static_assert(
(sizeof(u32) * CHAR_BIT) - bits_required(max(enumerator<E>.second))
==
32 - bits_required(4) == 32 - 3 = 29
);
```
<!-- .element: class="fragment" data-fragment-index="3" -->

#### lookup table - lut
---

```cpp
// magic
assert((to<u32>("ftp") * 2893426669) >> 29) == 1);
assert((to<u32>("file") * 2893426669) >> 29) == 4);
assert((to<u32>("http") * 2893426669) >> 29) == 0);
assert((to<u32>("ws") * 2893426669) >> 29) == 2);
assert((to<u32>("wss") * 2893426669) >> 29) == 3);
```
<!-- .element: class="fragment" data-fragment-index="4" -->

----

#### string_to_enum - Minimal perfect hashing

#### lookup table
<!-- .element: class="fragment" style="float:left" data-fragment-index="2" -->
<br />

```cpp
{7, 42, 1, 10}[n]
{1, 4, 0, 2, 3}[n]
```
<!-- .element: class="fragment" data-fragment-index="3" -->

```cpp
{0b000111, 0b101010, 0b000001, 0b001010}[n]
{0b001, 0b100, 0b000, 0b010, 0b011}[n]
```
<!-- .element: class="fragment" data-fragment-index="4" -->

```cpp
(0b'000111'101010'000001'001010 >> 6*n) & 0b111111
(0b'001'100'000'010'011 >> 3*n) & 0b111
```
<!-- .element: class="fragment" data-fragment-index="5" -->

---

#### lookup
<!-- .element: class="fragment" style="float:left" data-fragment-index="6" -->
<br />

```cpp
// shift: how many bits are required to represent all values (6 bits)
// mask: 0b111111 (6 bits)
// magic: ???
// lut: ???
((lut >> (value * magic)) >> shift) & mask
// shift: 29
// mask: 0b111
// magic: 2893426669 (???)
// lut: 0b001'100'000'010'011 = 6163 (???)
```
<!-- .element: class="fragment" data-fragment-index="6" -->

Expand All @@ -1659,10 +1697,11 @@
<!-- .element: class="fragment" data-fragment-index="0" -->

```cpp
constexpr auto size = sizeof(T) * CHAR_BIT; // T = uint32_t/...
using T = uint32_t;
constexpr auto size = sizeof(T) * CHAR_BIT;
constexpr auto nbits = size - countr_zero(max(enumerators<E>));
constexpr auto shift = size - nbits;
constexpr auto mask = (1u << nbits) - 1u; // 0b111111...
constexpr auto shift = size - nbits; // 29
constexpr auto mask = (1u << nbits) - 1u; // 0b111
constexpr auto [magic, lut] = magic_lut(mask, shift, MaxAttempts);
```
<!-- .element: class="fragment" data-fragment-index="1" -->
Expand Down Expand Up @@ -1725,7 +1764,7 @@
#### string_to_enum - Minimal perfect hashing - https://godbolt.org/z/3j8qcabsj

```cpp
enum uri { ftp = 1, file = 2, http = 3, ws = 4, wss = 5, };
enum uri { ftp = 0, file = 1, http = 2, ws = 3, wss = 4, };
```
<!-- .element: class="fragment" data-fragment-index="0" -->

Expand All @@ -1741,11 +1780,11 @@
[1] [2] [3] [4] [5] [6] Instructions:
1 1 0.50 shl edi, 3
2 5 0.50 * bzhi eax, dword ptr [rsi], edi
1 3 1.00 imul eax, eax, 385596323 /*magic*/
1 1 0.50 shr eax, 29 /*shift*/
1 1 0.50 mov ecx, 358 /*lut*/
1 3 1.00 imul eax, eax, 2893426669 /*magic*/
1 1 0.50 shr eax, 29 /*shift*/
1 1 0.50 mov ecx, 6163 /*lut*/
1 1 0.50 shrx eax, ecx, eax
1 1 0.25 and eax, 7 /*mask*/
1 1 0.25 and eax, 0b111 /*mask*/
1 5 0.50 U ret
</code></pre>

Expand Down

0 comments on commit 139bd3c

Please sign in to comment.