rename again!

This commit is contained in:
greg
2019-03-09 15:47:38 -05:00
parent 65f6b1439e
commit cdd4f68168
12 changed files with 3 additions and 2 deletions
View File
View File
View File
View File
View File
+3 -2
View File
@@ -106,7 +106,7 @@
\]</span></p>
</div>
<h1 id="the-parallel-hashmap">The Parallel Hashmap</h1>
<p>or Abseiling from the shoulders of giants - © Gregory Popovitch - March 3, 2019</p>
<p>or Abseiling from the shoulders of giants - © Gregory Popovitch - March 10, 2019</p>
<p>[tl;dr] We present a novel hashmap design, the Parallel Hashmap. Built on top of Abseil's <em>flat_hash_map</em>, the Parallel Hashmap has lower space requirements, is nearly as fast as the underlying <em>flat_hash_map</em>, and can be used from multiple threads with high levels of concurrency.</p>
<h3 id="a-quick-look-at-the-current-state-of-the-art">A quick look at the current state of the art</h3>
<p>If you haven't been living under a rock, you know that Google open sourced late last year their Abseil library, which includes a very efficient flat hash table implementation. The <em>absl::flat_hash_map</em> stores the values directly in a memory array, which avoids memory indirections (this is referred to as closed hashing).</p>
@@ -153,7 +153,7 @@
</ol>
<p>The first step (compute the hash) is the most problematic one, as it can potentially be costly. As we mentioned above, the second step (computing the index from the hash) is very simple and its cost in minimal (3 processor instruction as shown below in <em>Matt Godbolt</em>'s compiler explorer):</p>
<p><img src="https://github.com/greg7mdp/parallel-hashmap/blob/master/img/idx_computation_cost.PNG?raw=true" alt="index computation cost" /></p>
<p>As for the hash value computation, fortunately we can eliminate this cost by providing the computed hash to the submap functions, so that it is computed only once. This is exactly what I have done in my implementation pof the parallel_hash_map within the Abseil library, adding a few extra APIs to the Abseil internal raw_hash_map.h header,= which allow the parallel_hash_map to pass the precomputed hash value to the underlying hash tables.</p>
<p>As for the hash value computation, fortunately we can eliminate this cost by providing the computed hash to the submap functions, so that it is computed only once. This is exactly what I have done in my implementation of the parallel_hash_map within the Abseil library, adding a few extra APIs to the Abseil internal raw_hash_map.h header, which allow the parallel_hash_map to pass the precomputed hash value to the underlying submaps.</p>
<p>So we have all but eliminated the cost of the first step, and seen that the cost of the second step is very minimal. At this point we expect that the parallel_hash_map performance will be close to the one of its underlying <em>flat_hash_map</em>, and this is confirmed by the chart below:</p>
<p><img src="https://github.com/greg7mdp/parallel-hashmap/blob/master/img/stl_flat_par_speed.PNG?raw=true" alt="stl_flat_par comparison" /></p>
<p>Indeed, because of the scale is somewhat compressed due to the longer times of the std::unordered_map, we can barely distinguish between the blue curve of the <em>flat_hash_map</em> and the red curve of the parallel_hash_map. So let's look at a graph without the std::unordered_map:</p>
@@ -318,6 +318,7 @@ class parallel_flat_hash_map;
<h3 id="links">Links</h3>
<p><a href="https://github.com/greg7mdp/parallel-hashmap">Github repository for the benchmark code used in this paper</a></p>
<p><a href="https://abseil.io/blog/20180927-swisstables">Swiss Tables doc</a></p>
<p><a href="https://github.com/greg7mdp/abseil-cpp">My fork of Google Abseil repository, with the parallel_flat_hash_map implementation</a></p>
<p><a href="https://github.com/abseil/abseil-cpp">Google Abseil repository</a></p>
<p><a href="https://www.youtube.com/watch?v=ncHmEUmJZf4">Matt Kulukindis: Designing a Fast, Efficient, Cache-friendly Hash Table, Step by Step</a></p>
</div>
View File
View File