diff --git a/CMakeLists.txt b/CMakeLists.txt index 9afcf610..49067cca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -223,9 +223,9 @@ ENDIF() if(NOT MSVC) set(NOTMSVC_SRC seahash.c) - set_source_files_properties(HashMapTest.cpp PROPERTIES COMPILE_FLAGS "-std=c++11") + set_source_files_properties(HashMapTest.cpp PROPERTIES COMPILE_FLAGS "-std=c++11 -I${CMAKE_SOURCE_DIR}") set_source_files_properties(SpeedTest.cpp PROPERTIES COMPILE_FLAGS "-std=c++0x -I${CMAKE_SOURCE_DIR}") - set_source_files_properties(main.cpp PROPERTIES COMPILE_FLAGS "-std=c++0x") + set_source_files_properties(main.cpp PROPERTIES COMPILE_FLAGS "-std=c++0x -I${CMAKE_SOURCE_DIR}") set_source_files_properties(bittest.cpp PROPERTIES COMPILE_FLAGS "-std=c++0x") # https://github.com/dgryski/trifles/tree/master/tsip set(TSIP_SRC tsip.c) diff --git a/HashMapTest.cpp b/HashMapTest.cpp index c248eec7..8cf39c45 100644 --- a/HashMapTest.cpp +++ b/HashMapTest.cpp @@ -39,11 +39,12 @@ std::vector HashMapInit(bool verbose) { return words; } +template bool HashMapTest ( pfHash pfhash, const int hashbits, std::vector words, const int trials, bool verbose ) { - double mean = HashMapSpeedTest( pfhash, hashbits, words, trials, verbose); + double mean = HashMapSpeedTest( pfhash, hashbits, words, trials, verbose); // if faster than ~sha1 if (mean > 5. && mean < 1500.) printf(" ....... PASS\n"); diff --git a/SpeedTest.cpp b/SpeedTest.cpp index c1fb463a..ca4a3df6 100644 --- a/SpeedTest.cpp +++ b/SpeedTest.cpp @@ -7,15 +7,6 @@ #include // for sort, min #include -#include -#include -#include - -typedef std::unordered_map> std_hashmap; -typedef phmap::flat_hash_map> fast_hashmap; - //----------------------------------------------------------------------------- // We view our timing values as a series of random variables V that has been // contaminated with occasional outliers due to cache misses, thread @@ -300,139 +291,4 @@ double TinySpeedTest ( pfHash hash, int hashsize, int keysize, uint32_t seed, bo return cycles; } -double HashMapSpeedTest ( pfHash pfhash, const int hashbits, - std::vector words, - const int trials, bool verbose ) -{ - //using phmap::flat_node_hash_map; - Rand r(82762); - const uint32_t seed = r.rand_u32(); - std_hashmap hashmap(words.size(), [=](const std::string &key) - { - // 256 needed for hasshe2, but only size_t used - static char out[256] = { 0 }; - pfhash(key.c_str(), key.length(), seed, &out); - return *(size_t*)out; - }); - fast_hashmap phashmap(words.size(), [=](const std::string &key) - { - static char out[256] = { 0 }; // 256 for hasshe2, but stripped to 64/32 - pfhash(key.c_str(), key.length(), seed, &out); - return *(size_t*)out; - }); - - std::vector::iterator it; - std::vector times; - double t1; - - printf("std::unordered_map\n"); - printf("Init std HashMapTest: "); - fflush(NULL); - times.reserve(trials); - { // hash inserts and 1% deletes - volatile int64_t begin, end; - int i = 0; - begin = timer_start(); - for (it = words.begin(); it != words.end(); it++, i++) { - std::string line = *it; - hashmap[line] = 1; - if (i % 100 == 0) - hashmap.erase(line); - } - end = timer_end(); - t1 = (double)(end - begin) / (double)words.size(); - } - fflush(NULL); - printf("%0.3f cycles/op (%zu inserts, 1%% deletions)\n", - t1, words.size()); - printf("Running std HashMapTest: "); - if (t1 > 10000.) { // e.g. multiply_shift 459271.700 - printf("SKIP"); - return 0.; - } - fflush(NULL); - - for(int itrial = 0; itrial < trials; itrial++) - { // hash query - volatile int64_t begin, end; - int i = 0, found = 0; - double t; - begin = timer_start(); - for ( it = words.begin(); it != words.end(); it++, i++ ) - { - std::string line = *it; - if (hashmap[line]) - found++; - } - end = timer_end(); - t = (double)(end - begin) / (double)words.size(); - if(found > 0 && t > 0) times.push_back(t); - } - hashmap.clear(); - - std::sort(times.begin(),times.end()); - FilterOutliers(times); - double mean = CalcMean(times); - double stdv = CalcStdv(times); - printf("%0.3f cycles/op", mean); - printf(" (%0.1f stdv)\n", stdv); - - times.clear(); - - printf("\ngreg7mdp/parallel-hashmap\n"); - printf("Init fast HashMapTest: "); - fflush(NULL); - times.reserve(trials); - { // hash inserts and 1% deletes - volatile int64_t begin, end; - int i = 0; - begin = timer_start(); - for (it = words.begin(); it != words.end(); it++, i++) { - std::string line = *it; - phashmap[line] = 1; - if (i % 100 == 0) - phashmap.erase(line); - } - end = timer_end(); - t1 = (double)(end - begin) / (double)words.size(); - } - fflush(NULL); - printf("%0.3f cycles/op (%zu inserts, 1%% deletions)\n", - t1, words.size()); - printf("Running fast HashMapTest: "); - if (t1 > 10000.) { // e.g. multiply_shift 459271.700 - printf("SKIP"); - return 0.; - } - fflush(NULL); - for(int itrial = 0; itrial < trials; itrial++) - { // hash query - volatile int64_t begin, end; - int i = 0, found = 0; - double t; - begin = timer_start(); - for ( it = words.begin(); it != words.end(); it++, i++ ) - { - std::string line = *it; - if (phashmap[line]) - found++; - } - end = timer_end(); - t = (double)(end - begin) / (double)words.size(); - if(found > 0 && t > 0) times.push_back(t); - } - phashmap.clear(); - fflush(NULL); - - std::sort(times.begin(),times.end()); - FilterOutliers(times); - double mean1 = CalcMean(times); - double stdv1 = CalcStdv(times); - printf("%0.3f cycles/op", mean1); - printf(" (%0.1f stdv) ", stdv1); - fflush(NULL); - - return mean; -} - //----------------------------------------------------------------------------- diff --git a/SpeedTest.h b/SpeedTest.h index aca02eec..4315c05b 100644 --- a/SpeedTest.h +++ b/SpeedTest.h @@ -1,9 +1,161 @@ #pragma once #include "Types.h" +#include "Random.h" void BulkSpeedTest ( pfHash hash, uint32_t seed ); double TinySpeedTest ( pfHash hash, int hashsize, int keysize, uint32_t seed, bool verbose ); -double HashMapSpeedTest ( pfHash pfhash, int hashbits, std::vector words, - const int trials, bool verbose ); + +double CalcMean ( std::vector & v ); +double CalcStdv ( std::vector & v ); +bool ContainsOutlier ( std::vector & v, size_t len ); +void FilterOutliers ( std::vector & v ); + +#include // for sort, min +#include +#include +#include +#include + +typedef std::unordered_map> std_hashmap; +typedef phmap::flat_hash_map> fast_hashmap; + +template< typename hashtype > +double HashMapSpeedTest ( pfHash pfhash, const int hashbits, + std::vector words, + const int trials, bool verbose ) +{ + //using phmap::flat_node_hash_map; + Rand r(82762); + const uint32_t seed = r.rand_u32(); + std_hashmap hashmap(words.size(), [=](const std::string &key) + { + // 256 needed for hasshe2, but only size_t used + static hashtype out; + pfhash(key.c_str(), key.length(), seed, &out); + return *(size_t*)out; + }); + fast_hashmap phashmap(words.size(), [=](const std::string &key) + { + static hashtype out; + pfhash(key.c_str(), key.length(), seed, &out); + return *(size_t*)out; + }); + + std::vector::iterator it; + std::vector times; + double t1; + + printf("std::unordered_map\n"); + printf("Init std HashMapTest: "); + fflush(NULL); + times.reserve(trials); + { // hash inserts and 1% deletes + volatile int64_t begin, end; + int i = 0; + begin = timer_start(); + for (it = words.begin(); it != words.end(); it++, i++) { + std::string line = *it; + hashmap[line] = 1; + if (i % 100 == 0) + hashmap.erase(line); + } + end = timer_end(); + t1 = (double)(end - begin) / (double)words.size(); + } + fflush(NULL); + printf("%0.3f cycles/op (%zu inserts, 1%% deletions)\n", + t1, words.size()); + printf("Running std HashMapTest: "); + if (t1 > 10000.) { // e.g. multiply_shift 459271.700 + printf("SKIP"); + return 0.; + } + fflush(NULL); + + for(int itrial = 0; itrial < trials; itrial++) + { // hash query + volatile int64_t begin, end; + int i = 0, found = 0; + double t; + begin = timer_start(); + for ( it = words.begin(); it != words.end(); it++, i++ ) + { + std::string line = *it; + if (hashmap[line]) + found++; + } + end = timer_end(); + t = (double)(end - begin) / (double)words.size(); + if(found > 0 && t > 0) times.push_back(t); + } + hashmap.clear(); + + std::sort(times.begin(),times.end()); + FilterOutliers(times); + double mean = CalcMean(times); + double stdv = CalcStdv(times); + printf("%0.3f cycles/op", mean); + printf(" (%0.1f stdv)\n", stdv); + + times.clear(); + + printf("\ngreg7mdp/parallel-hashmap\n"); + printf("Init fast HashMapTest: "); + fflush(NULL); + times.reserve(trials); + { // hash inserts and 1% deletes + volatile int64_t begin, end; + int i = 0; + begin = timer_start(); + for (it = words.begin(); it != words.end(); it++, i++) { + std::string line = *it; + phashmap[line] = 1; + if (i % 100 == 0) + phashmap.erase(line); + } + end = timer_end(); + t1 = (double)(end - begin) / (double)words.size(); + } + fflush(NULL); + printf("%0.3f cycles/op (%zu inserts, 1%% deletions)\n", + t1, words.size()); + printf("Running fast HashMapTest: "); + if (t1 > 10000.) { // e.g. multiply_shift 459271.700 + printf("SKIP"); + return 0.; + } + fflush(NULL); + for(int itrial = 0; itrial < trials; itrial++) + { // hash query + volatile int64_t begin, end; + int i = 0, found = 0; + double t; + begin = timer_start(); + for ( it = words.begin(); it != words.end(); it++, i++ ) + { + std::string line = *it; + if (phashmap[line]) + found++; + } + end = timer_end(); + t = (double)(end - begin) / (double)words.size(); + if(found > 0 && t > 0) times.push_back(t); + } + phashmap.clear(); + fflush(NULL); + + std::sort(times.begin(),times.end()); + FilterOutliers(times); + double mean1 = CalcMean(times); + double stdv1 = CalcStdv(times); + printf("%0.3f cycles/op", mean1); + printf(" (%0.1f stdv) ", stdv1); + fflush(NULL); + + return mean; +} + //----------------------------------------------------------------------------- diff --git a/main.cpp b/main.cpp index f66281c4..dcc42822 100644 --- a/main.cpp +++ b/main.cpp @@ -522,7 +522,7 @@ void test ( hashfunc hash, HashInfo* info ) result = false; } else { std::vector words = HashMapInit(g_drawDiagram); - result &= HashMapTest(hash,info->hashbits,words,trials,g_drawDiagram); + result &= HashMapTest(hash,info->hashbits,words,trials,g_drawDiagram); } if(!result) printf("*********FAIL*********\n"); printf("\n");