From a5c4f9abb37cd877dbb7be486657e9dca281274d Mon Sep 17 00:00:00 2001 From: Peizhao Ou Date: Fri, 9 Feb 2018 13:31:25 -0800 Subject: [PATCH 1/1] Uses cdsstress library --- test/CMakeLists.txt | 17 ++-- test/junction_parallel_driver.cpp | 137 +++++++++++++++++++----------- 2 files changed, 100 insertions(+), 54 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index fe8a11e..adb76de 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,7 +3,14 @@ cmake_minimum_required(VERSION 2.8.5) set(CMAKE_CONFIGURATION_TYPES "Release" CACHE INTERNAL "Build configs") include_directories( - /scratch/googletest/googletest/include/ + /scratch/googletest/googletest/include + /scratch/benchmarks/libcds/test/include + /scratch/benchmarks/libcds +) + +link_directories( + /scratch/benchmarks/libcds/build/bin + /scratch/googletest/googletest ) set(SEQUENTIAL_DRIVER stress-sequential-junction) @@ -12,10 +19,10 @@ set(PARALLEL_DRIVER stress-parallel-junction) set(JUNCTION_LIB junction turf - # AArch64 lib - /scratch/googletest/googletest/libgtest.a - # x86 lib - #/scratch/googletest/libgtest.a + # It's fine to link the lib compiled from original clang because we are only + # using the config parsing functionality. + stress-framework + gtest ) add_executable(${SEQUENTIAL_DRIVER} junction_sequential_driver.cpp) diff --git a/test/junction_parallel_driver.cpp b/test/junction_parallel_driver.cpp index b9f5d8f..b6f74f6 100644 --- a/test/junction_parallel_driver.cpp +++ b/test/junction_parallel_driver.cpp @@ -3,38 +3,41 @@ #include #include -#include +#include +#include #include +#include #include #include +#include namespace junction_test { -class JunctionMapInsDelFindTest_Parallel : public ::testing::Test { +class JunctionMapInsDelFindTest_Parallel : public cds_test::stress_fixture { protected: typedef junction::ConcurrentMap_Grampa GrampaMap; typedef junction::ConcurrentMap_Linear LinearMap; typedef junction::ConcurrentMap_Leapfrog LeapfrogMap; typedef junction::ConcurrentMap_Crude CrudeMap; - static const unsigned s_nInsertPercentage = 5; - static const unsigned s_nDeletePercentage = 5; - - // Run GC after "kGCFrequency" operations. - const size_t kGCFrequency = 1500; - const size_t kMapSize = 20000; + static unsigned s_nInsertPercentage; + static unsigned s_nDeletePercentage; + static size_t s_nGCFrequency; // Run GC after "s_nGCFrequency" operations. + static size_t s_nThreadCount; + static size_t s_nMapKeyRange; + static size_t s_nCrudeMapCapacity; enum actions { do_find, do_insert, do_delete }; static const unsigned int kShuffleSize = 100; static actions s_arrShuffle[kShuffleSize]; - const size_t kCrudePassCount = 400000; - const size_t kGrampaPassCount = 60000; - const size_t kLinearPassCount = 70000; - const size_t kLeapfrogPassCount = 75000; + static size_t s_nCrudePassCount; + static size_t s_nGrampaPassCount; + static size_t s_nLinearPassCount; + static size_t s_nLeapfrogPassCount; - static void SetUpTestCase() { + static void InitShuffleArray() { // Build an array of shuffled actions. EXPECT_LE(s_nInsertPercentage + s_nDeletePercentage, 100); actions* pFirst = s_arrShuffle; @@ -53,10 +56,26 @@ protected: std::shuffle(s_arrShuffle, pLast, g); } + static void SetUpTestCase() { + InitShuffleArray(); + const cds_test::config& cfg = get_config("ParallelJunction"); + GetConfigNonZeroExpected(InsertPercentage, 5); + GetConfigNonZeroExpected(DeletePercentage, 5); + GetConfigNonZeroExpected(ThreadCount, 4); + GetConfigNonZeroExpected(MapKeyRange, 20000); + GetConfigNonZeroExpected(CrudeMapCapacity, s_nMapKeyRange * 64); + GetConfigNonZeroExpected(GCFrequency, 1500); + GetConfigNonZeroExpected(CrudePassCount, 1500000000); + GetConfigNonZeroExpected(GrampaPassCount, 650000000); + GetConfigNonZeroExpected(LinearPassCount, 900000000); + GetConfigNonZeroExpected(LeapfrogPassCount, 850000000); + } + template static bool map_insert(Map* map, Key key, Value value) { auto iter = map->insertOrFind(key); - if (!iter.getValue()) { + if (!iter.getValue() || iter.getValue() != value) { + // Insert/update the pair iter.assignValue(value); return true; } else { @@ -88,7 +107,8 @@ protected: // Specialization for CrudeMap template static bool map_insert(CrudeMap* map, Key key, Value value) { - if (!map->get(key)) { + auto old_val = map->get(key); + if (!old_val || old_val != value) { map->assign(key, value); return true; } else { @@ -109,12 +129,12 @@ protected: return map->get(key) != ((Key)0); } - template void run_test(Map* map, size_t pass_count) { + template static void run_test(Map* map, size_t pass_count) { auto qsbrContext = junction::DefaultQSBR.createContext(); std::random_device rd; std::mt19937 gen(rd()); - std::uniform_int_distribution dis(kMapSize, 2 * kMapSize); + std::uniform_int_distribution dis(2, s_nMapKeyRange); unsigned action_index = 0; size_t nInsertedNum = 0; @@ -122,35 +142,34 @@ protected: size_t nOperations = 0; for (size_t count = 0; count < pass_count; count++) { - for (size_t i = 0; i < kMapSize; ++i) { - // The number to operate on the map. - size_t n = dis(gen); - switch (s_arrShuffle[action_index]) { - case do_insert: { - if (map_insert(map, n, n)) { - nInsertedNum++; - } - break; - } - case do_delete: { - map_delete(map, n); - break; + // The number to operate on the map. + size_t key = dis(gen); + switch (s_arrShuffle[action_index]) { + case do_insert: { + size_t val = dis(gen); + if (map_insert(map, key, val)) { + nInsertedNum++; } - case do_find: { - if (map_find(map, n)) { - ++nFindSuccess; - } - break; - } - default: { break; } + break; } - if (++action_index >= kShuffleSize) { - action_index = 0; + case do_delete: { + map_delete(map, key); + break; } - if (++nOperations > kGCFrequency) { - junction::DefaultQSBR.update(qsbrContext); - nOperations = 0; + case do_find: { + if (map_find(map, key)) { + ++nFindSuccess; + } + break; } + default: { break; } + } + if (++action_index >= kShuffleSize) { + action_index = 0; + } + if (++nOperations > s_nGCFrequency) { + junction::DefaultQSBR.update(qsbrContext); + nOperations = 0; } } junction::DefaultQSBR.update(qsbrContext); @@ -158,35 +177,55 @@ protected: } }; -const unsigned JunctionMapInsDelFindTest_Parallel::s_nInsertPercentage; -const unsigned JunctionMapInsDelFindTest_Parallel::s_nDeletePercentage; +size_t JunctionMapInsDelFindTest_Parallel::s_nThreadCount; +size_t JunctionMapInsDelFindTest_Parallel::s_nMapKeyRange; +size_t JunctionMapInsDelFindTest_Parallel::s_nCrudeMapCapacity; +size_t JunctionMapInsDelFindTest_Parallel::s_nGCFrequency; +unsigned JunctionMapInsDelFindTest_Parallel::s_nInsertPercentage; +unsigned JunctionMapInsDelFindTest_Parallel::s_nDeletePercentage; const unsigned int JunctionMapInsDelFindTest_Parallel::kShuffleSize; JunctionMapInsDelFindTest_Parallel::actions JunctionMapInsDelFindTest_Parallel:: s_arrShuffle[JunctionMapInsDelFindTest_Parallel::kShuffleSize]; +size_t JunctionMapInsDelFindTest_Parallel::s_nCrudePassCount; +size_t JunctionMapInsDelFindTest_Parallel::s_nGrampaPassCount; +size_t JunctionMapInsDelFindTest_Parallel::s_nLinearPassCount; +size_t JunctionMapInsDelFindTest_Parallel::s_nLeapfrogPassCount; + +#define JunctionThreading(map_type, pass_count) \ + std::unique_ptr threads(new std::thread[s_nThreadCount]); \ + for (size_t i = 0; i < s_nThreadCount; i++) { \ + threads[i] = std::thread(run_test, map.get(), pass_count); \ + } \ + for (size_t i = 0; i < s_nThreadCount; i++) { \ + threads[i].join(); \ + } TEST_F(JunctionMapInsDelFindTest_Parallel, JunctionMapCrude) { - std::unique_ptr map(new CrudeMap(kMapSize * 32)); - run_test(map.get(), kCrudePassCount); + std::unique_ptr map(new CrudeMap(s_nCrudeMapCapacity)); + JunctionThreading(CrudeMap, s_nCrudePassCount); } TEST_F(JunctionMapInsDelFindTest_Parallel, JunctionMapLeapfrog) { std::unique_ptr map(new LeapfrogMap()); - run_test(map.get(), kLeapfrogPassCount); + JunctionThreading(LeapfrogMap, s_nLeapfrogPassCount); } TEST_F(JunctionMapInsDelFindTest_Parallel, JunctionMapLinear) { std::unique_ptr map(new LinearMap()); - run_test(map.get(), kLinearPassCount); + JunctionThreading(LinearMap, s_nLinearPassCount); } TEST_F(JunctionMapInsDelFindTest_Parallel, JunctionMapGrampa) { std::unique_ptr map(new GrampaMap()); - run_test(map.get(), kGrampaPassCount); + JunctionThreading(GrampaMap, s_nGrampaPassCount); } } // namespace junction_test int main(int argc, char** argv) { + // Read test config file + cds_test::init_config(argc, argv); + // Init Google test ::testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); -- 2.34.1