This commit is contained in:
greg
2019-03-17 21:24:03 -04:00
parent 0118121ef1
commit d675336a8d
4 changed files with 52 additions and 24 deletions
+4 -5
View File
@@ -8,6 +8,7 @@ PROGS = stl_unordered_map sparsepp phmap abseil_flat abseil_parallel_flat
BUILD_PROGS = $(addprefix build/,$(PROGS))
SIZE = 100000000
ABSEIL = ../../abseil-cpp
PHMAP_SRC = ../parallel_hashmap
all: test
@@ -20,7 +21,7 @@ build/stl_unordered_map: bench.cc Makefile
build/sparsepp: bench.cc Makefile
$(CXX) -DSPARSEPP -I../../sparsepp bench.cc -o $@
build/phmap: bench.cc Makefile
build/phmap: bench.cc Makefile $(PHMAP_SRC)/phmap.h
$(CXX) -DPHMAP -I.. bench.cc /MD -o $@
build/abseil_flat: bench.cc Makefile
@@ -34,7 +35,8 @@ progs: $(BUILD_PROGS)
test: builddir progs
-rm -f output
#./build/stl_unordered_map $(SIZE) random >> output
./build/abseil_flat $(SIZE) random >> output
#./build/abseil_flat $(SIZE) random >> output
./build/phmap $(SIZE) random >> output
#./build/sparsepp $(SIZE) random >> output
./build/abseil_parallel_flat $(SIZE) random >> output
python make_chart_data.py < output
@@ -47,11 +49,8 @@ test_cust:
./build/abseil_parallel_flat $(SIZE) random >> output
python make_chart_data.py < output
chart:
python make_chart_data.py < output
clean:
-rm -fr output build
+13 -8
View File
@@ -17,27 +17,29 @@
#if defined(ABSEIL_PARALLEL_FLAT)
#include "absl/container/parallel_flat_hash_map.h"
#define MAPNAME absl::parallel_flat_hash_map
#define NMSP absl
#else
#include "parallel_hashmap/phmap.h"
#define MAPNAME phmap::parallel_flat_hash_map
#define NMSP phmap
#endif
//#define MT_SUPPORT 2
#define MT_SUPPORT 1
#if MT_SUPPORT == 1
// create the parallel_flat_hash_map without internal mutexes, for when
// we programatically ensure that each thread uses different internal submaps
// --------------------------------------------------------------------------
#define EXTRAARGS , absl::container_internal::hash_default_hash<K>, \
absl::container_internal::hash_default_eq<K>, \
std::allocator<std::pair<const K, V>>, 4, absl::NullMutex
#define EXTRAARGS , NMSP::container_internal::hash_default_hash<K>, \
NMSP::container_internal::hash_default_eq<K>, \
std::allocator<std::pair<const K, V>>, 4, NMSP::NullMutex
#elif MT_SUPPORT == 2
// create the parallel_flat_hash_map with internal mutexes, for when
// we read/write the same parallel_flat_hash_map from multiple threads,
// without any special precautions.
// --------------------------------------------------------------------------
#define EXTRAARGS , absl::container_internal::hash_default_hash<K>, \
absl::container_internal::hash_default_eq<K>, \
std::allocator<std::pair<const K, V>>, 4, absl::Mutex
#define EXTRAARGS , NMSP::container_internal::hash_default_hash<K>, \
NMSP::container_internal::hash_default_eq<K>, \
std::allocator<std::pair<const K, V>>, 4, NMSP::Mutex
#else
#define EXTRAARGS
#endif
@@ -357,8 +359,11 @@ int main(int argc, char ** argv)
srand(1); // for a fair/deterministic comparison
Timer timer(true);
if (!strcmp(program_slug,"absl::parallel_flat_hash_map"))
#ifdef MT_SUPPORT
if (!strcmp(program_slug,"absl::parallel_flat_hash_map") ||
!strcmp(program_slug,"phmap::parallel_flat_hash_map"))
program_slug = xstr(MAPNAME) "_mt";
#endif
std::thread t1(memlog);
+13 -7
View File
@@ -44,6 +44,8 @@ proper_names = {
'std::unordered_map': 'std::unordered_map (1 thread)',
'spp::sparse_hash_map': 'sparsepp (1 thread, use_spp_alloc)',
'absl::flat_hash_map': 'absl::flat_hash_map (1 thread)',
'phmap::parallel_flat_hash_map': 'phmap::parallel_flat_hash_map (1 thread)',
'phmap::parallel_flat_hash_map_mt': 'phmap::parallel_flat_hash_map (8 thread8)',
'absl::parallel_flat_hash_map': 'absl::parallel_flat_hash_map (1 thread)',
'absl::parallel_flat_hash_map_mt': 'absl::parallel_flat_hash_map (8 threads)',
'absl::parallel_flat_hash_map_4': 'absl::parallel_flat_hash_map (N=4, 8 threads)',
@@ -52,14 +54,16 @@ proper_names = {
}
proper_color = {
'std::unordered_map': 0,
'std::unordered_map': 0,
'spp::sparse_hash_map': 0,
'absl::flat_hash_map': 1,
'absl::parallel_flat_hash_map': 2,
'absl::parallel_flat_hash_map_mt': 2,
'absl::parallel_flat_hash_map_4': 2,
'absl::parallel_flat_hash_map_5': 3,
'absl::parallel_flat_hash_map_6': 4
'absl::flat_hash_map': 1,
'phmap::parallel_flat_hash_map': 2,
'phmap::parallel_flat_hash_map_mt': 2,
'absl::parallel_flat_hash_map': 3,
'absl::parallel_flat_hash_map_mt': 3,
'absl::parallel_flat_hash_map_4': 3,
'absl::parallel_flat_hash_map_5': 4,
'absl::parallel_flat_hash_map_6': 5
}
bench_titles = {
@@ -79,6 +83,8 @@ program_slugs = [
'sparsepp',
'absl::flat_hash_map',
'absl::parallel_flat_hash_map',
'phmap::parallel_flat_hash_map',
'phmap::parallel_flat_hash_map_mt',
'absl::parallel_flat_hash_map_mt',
'absl::parallel_flat_hash_map_4',
'absl::parallel_flat_hash_map_5',
+21 -3
View File
@@ -34,8 +34,6 @@
// limitations under the License.
// ---------------------------------------------------------------------------
#include <algorithm>
#include <cmath>
#include <cstdint>
@@ -263,6 +261,7 @@ inline size_t HashSeed(const ctrl_t* ctrl) {
inline size_t H1(size_t hash, const ctrl_t* ctrl) {
return (hash >> 7) ^ HashSeed(ctrl);
}
inline ctrl_t H2(size_t hash) { return hash & 0x7F; }
inline bool IsEmpty(ctrl_t c) { return c == kEmpty; }
@@ -301,6 +300,7 @@ struct GroupSse2Impl
}
// Returns a bitmask representing the positions of slots that match hash.
// ----------------------------------------------------------------------
BitMask<uint32_t, kWidth> Match(h2_t hash) const {
auto match = _mm_set1_epi8(hash);
return BitMask<uint32_t, kWidth>(
@@ -308,6 +308,7 @@ struct GroupSse2Impl
}
// Returns a bitmask representing the positions of empty slots.
// ------------------------------------------------------------
BitMask<uint32_t, kWidth> MatchEmpty() const {
#if PHMAP_HAVE_SSSE3
// This only works because kEmpty is -128.
@@ -319,6 +320,7 @@ struct GroupSse2Impl
}
// Returns a bitmask representing the positions of empty or deleted slots.
// -----------------------------------------------------------------------
BitMask<uint32_t, kWidth> MatchEmptyOrDeleted() const {
auto special = _mm_set1_epi8(kSentinel);
return BitMask<uint32_t, kWidth>(
@@ -326,12 +328,14 @@ struct GroupSse2Impl
}
// Returns the number of trailing empty or deleted elements in the group.
// ----------------------------------------------------------------------
uint32_t CountLeadingEmptyOrDeleted() const {
auto special = _mm_set1_epi8(kSentinel);
return TrailingZeros(
_mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1);
}
// ----------------------------------------------------------------------
void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
auto msbs = _mm_set1_epi8(static_cast<char>(-128));
auto x126 = _mm_set1_epi8(126);
@@ -3971,6 +3975,20 @@ struct HashEq
#if 0
struct int64_t_hash
{
using is_transparent = void;
size_t operator()(int64_t v) const {
return (size_t)v;
}
};
template <>
struct HashEq<int64_t> {
using Hash = int64_t_hash;
using Eq = std::equal_to<int64_t>;
};
struct StringHash
{
using is_transparent = void;
@@ -4118,7 +4136,7 @@ struct HashtableDebugAccess<Set, phmap::void_t<typename Set::raw_hash_set>>
// -----------------------------------------------------------------------------
// A class that implements the Mutex interface, but does nothing. This is to be
// used as a default template parameters for classes who provide optional
// internal locking (like absl::parallel_flat_hash_map).
// internal locking (like phmap::parallel_flat_hash_map).
// -----------------------------------------------------------------------------
class PHMAP_LOCKABLE NullMutex {
public: