├── task1 ├── .gitignore ├── presentation │ ├── .gitignore │ ├── core_i5.png │ ├── saturn.png │ └── presentation.tex ├── src │ ├── CMakeLists.txt │ ├── balancer.hpp │ ├── pcn.cpp │ ├── block.hpp │ ├── layer.hpp │ ├── periodic.hpp │ └── pcn.hpp ├── GNUmakefile ├── CMakeLists.txt └── README ├── task2 ├── .gitignore ├── go │ ├── .gitignore │ ├── GNUmakefile │ ├── main.go │ └── src │ │ ├── probe │ │ └── probe.go │ │ └── cuckoo │ │ ├── cuckoo_test.go │ │ └── cuckoo.go ├── data │ ├── .gitignore │ ├── prep.sh │ ├── striped_8locks.dat │ ├── stdset.dat │ ├── refined.dat │ ├── striped.dat │ └── refined_refCounting.dat ├── protocol │ ├── .gitignore │ ├── gp.sh │ ├── Makefile │ ├── 05contains_025add.gp │ ├── 099contains_0005add.gp │ ├── striped.gp │ ├── refined.gp │ └── protocol.tex ├── test │ ├── CMakeLists.txt │ └── cuckooset.cpp ├── src │ ├── CMakeLists.txt │ ├── probeset.hpp │ ├── hash.hpp │ ├── cuckoolock.hpp │ ├── stdset.hpp │ ├── probeset.cpp │ ├── hash.cpp │ ├── atomicmarkablereference.hpp │ ├── stdset.cpp │ ├── cuckoolock.cpp │ ├── cuckooset.hpp │ ├── atomicmarkablereference.cpp │ └── cuckooset.cpp ├── GNUmakefile ├── CMakeLists.txt └── README ├── .gitignore ├── exercises_batch_1 ├── .gitignore └── Makefile ├── exercises_batch_2 ├── .gitignore ├── Makefile └── exercises.tex └── CMakeModules └── FindCheck.cmake /task1/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /task2/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | -------------------------------------------------------------------------------- /task2/go/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .ssh-cfg 3 | -------------------------------------------------------------------------------- /task2/data/.gitignore: -------------------------------------------------------------------------------- 1 | 1_*.dat 2 | 2_*.dat 3 | -------------------------------------------------------------------------------- /exercises_batch_1/.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.log 3 | *.pdf 4 | *.toc 5 | -------------------------------------------------------------------------------- /exercises_batch_2/.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.log 3 | *.pdf 4 | *.toc 5 | -------------------------------------------------------------------------------- /task2/protocol/.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.eps 3 | *.log 4 | *.out 5 | *.pdf 6 | *.toc 7 | -------------------------------------------------------------------------------- /task2/protocol/gp.sh: -------------------------------------------------------------------------------- 1 | rm -f *.pdf 2 | rm -f *.eps 3 | 4 | for f in *.gp; do 5 | gnuplot $f; 6 | done 7 | 8 | -------------------------------------------------------------------------------- /task1/presentation/.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.log 3 | *.nav 4 | *.out 5 | *.pdf 6 | *.snm 7 | *.synctex.gz 8 | *.toc 9 | *.vrb 10 | -------------------------------------------------------------------------------- /task1/presentation/core_i5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schuay/advanced_multiprocessor_programming/HEAD/task1/presentation/core_i5.png -------------------------------------------------------------------------------- /task1/presentation/saturn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schuay/advanced_multiprocessor_programming/HEAD/task1/presentation/saturn.png -------------------------------------------------------------------------------- /task2/go/GNUmakefile: -------------------------------------------------------------------------------- 1 | all: check 2 | 3 | check: 4 | GOPATH=$$(pwd) go test cuckoo 5 | 6 | bench: 7 | GOPATH=$$(pwd) go test -bench . -benchtime 5s -cpu 1,2,4,8,16 cuckoo 8 | -------------------------------------------------------------------------------- /task1/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${PHEET_INCLUDE_DIR} 3 | ) 4 | 5 | add_executable(pcn pcn.cpp) 6 | target_link_libraries(pcn ${CMAKE_THREAD_LIBS_INIT} ${HWLOC_LIBRARIES}) 7 | -------------------------------------------------------------------------------- /task2/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${CHECK_INCLUDE_DIRS} 3 | ${CMAKE_SOURCE_DIR}/src 4 | ${PHEET_INCLUDE_DIR} 5 | ) 6 | 7 | add_executable(cuckoo_test cuckooset.cpp) 8 | target_link_libraries(cuckoo_test ${CHECK_LIBRARIES} cuckooset) 9 | add_test(cuckoo_test ${CMAKE_CURRENT_BINARY_DIR}/cuckoo_test) 10 | -------------------------------------------------------------------------------- /task2/protocol/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = protocol 2 | 3 | protocol: 4 | cd ../data/ && ./prep.sh && cd ../protocol/ 5 | ./gp.sh 6 | pdflatex $(PROJECT) 7 | pdflatex $(PROJECT) 8 | 9 | clean: 10 | rm -f *.aux $(PROJECT).bbl $(PROJECT).blg $(PROJECT).log $(PROJECT).dvi \ 11 | $(PROJECT).toc $(PROJECT).pdf $(PROJECT).ps $(PROJECT).out *.eps *.pdf 12 | 13 | -------------------------------------------------------------------------------- /task2/data/prep.sh: -------------------------------------------------------------------------------- 1 | rm -f 1_*.dat 2 | rm -f 2_*.dat 3 | for f in *.dat 4 | do 5 | sed -e '/test/d' -n -e 's/.*[\ \t]\(0.5 0.25\)[\ \t]0[\ \t]\([0-9]*[\ \t][0-9.]*\)[\ \t]*$/\2/p' $f | sort -g -k1 -k2 | sort -gu -k1 >1_$f 6 | sed -e '/test/d' -n -e 's/.*[\ \t]\(0.99 0.005\)[\ \t]0[\ \t]\([0-9]*[\ \t][0-9.]*\)[\ \t]*$/\2/p' $f | sort -g -k1 -k2 | sort -gu -k1 >2_$f 7 | done 8 | -------------------------------------------------------------------------------- /task2/go/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "cuckoo" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | c := cuckoo.NewSet() 10 | 11 | c.Put(30) 12 | fmt.Printf("c.Contains(30) = %v\n", c.Contains(30)) 13 | fmt.Printf("c.Size() = %v\n", c.Size()) 14 | 15 | c.Remove(30) 16 | fmt.Printf("c.Contains(30) = %v\n", c.Contains(30)) 17 | fmt.Printf("c.Size() = %v\n", c.Size()) 18 | } 19 | -------------------------------------------------------------------------------- /task2/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${PHEET_INCLUDE_DIR} 3 | ) 4 | 5 | add_library(cuckooset SHARED 6 | atomicmarkablereference.cpp 7 | cuckoolock.cpp 8 | cuckooset.cpp 9 | hash.cpp 10 | probeset.cpp 11 | ) 12 | target_link_libraries(cuckooset ${CMAKE_THREAD_LIBS_INIT} ${HWLOC_LIBRARIES}) 13 | 14 | add_library(stdset SHARED stdset.cpp) 15 | target_link_libraries(stdset ${CMAKE_THREAD_LIBS_INIT} ${HWLOC_LIBRARIES}) 16 | -------------------------------------------------------------------------------- /task1/src/balancer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __BALANCER_H 2 | #define __BALANCER_H 3 | 4 | #include 5 | 6 | class Balancer 7 | { 8 | public: 9 | Balancer(); 10 | 11 | int traverse(); 12 | private: 13 | std::atomic toggle; 14 | }; 15 | 16 | Balancer::Balancer() : 17 | toggle(0) 18 | { 19 | } 20 | 21 | int 22 | Balancer::traverse() 23 | { 24 | return toggle.fetch_xor(1, std::memory_order_relaxed); 25 | } 26 | 27 | #endif /* __BALANCER_H */ 28 | -------------------------------------------------------------------------------- /task2/src/probeset.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __PROBESET_H 2 | #define __PROBESET_H 3 | 4 | #include 5 | #include 6 | 7 | #define PROBE_THRESHOLD (8) 8 | #define PROBE_SIZE (16) 9 | 10 | template > 12 | class ProbeSet { 13 | public: 14 | void add(const T &item); 15 | bool contains(const T &item) const; 16 | T first() const; 17 | void remove(const T &item); 18 | size_t size() const; 19 | 20 | private: 21 | std::set the_set; 22 | }; 23 | 24 | #endif /* __PROBESET_H */ 25 | -------------------------------------------------------------------------------- /task2/protocol/05contains_025add.gp: -------------------------------------------------------------------------------- 1 | set terminal postscript eps enhanced size 13cm,6cm color font 'Helvetica,15' 2 | set output '05contains_025add.eps' 3 | set xrange [1:48] 4 | set nokey 5 | set key top left 6 | set xlabel 'Number of cores [byte]' 7 | set ylabel 'Time [s]' 8 | set logscale x 2 9 | #set logscale y 10 | 11 | plot \ 12 | '../data/1_globallock.dat' using 1:2 title 'GlobalLock' with linespoints,\ 13 | '../data/1_striped.dat' using 1:2 title 'Striped Cuckkoo' with linespoints,\ 14 | '../data/1_refined.dat' using 1:2 title 'Refined Cuckoo' with linespoints; 15 | set output 16 | -------------------------------------------------------------------------------- /task2/protocol/099contains_0005add.gp: -------------------------------------------------------------------------------- 1 | set terminal postscript eps enhanced size 13cm,6cm color font 'Helvetica,15' 2 | set output '099contains_005add.eps' 3 | set xrange [1:48] 4 | set nokey 5 | set key top left 6 | set xlabel 'Number of cores [byte]' 7 | set ylabel 'Time [s]' 8 | set logscale x 2 9 | #set logscale y 10 | 11 | plot \ 12 | '../data/2_globallock.dat' using 1:2 title 'GlobalLock' with linespoints,\ 13 | '../data/2_striped.dat' using 1:2 title 'Striped Cuckkoo' with linespoints,\ 14 | '../data/2_refined.dat' using 1:2 title 'Refined Cuckoo' with linespoints; 15 | set output 16 | -------------------------------------------------------------------------------- /exercises_batch_1/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = exercises 2 | 3 | #------------------------------------------------------------------------------ 4 | protocol: 5 | #------------------------------------------------------------------------------ 6 | pdflatex $(PROJECT) 7 | pdflatex $(PROJECT) 8 | 9 | 10 | #------------------------------------------------------------------------------ 11 | clean: 12 | #------------------------------------------------------------------------------ 13 | rm -f *.aux $(PROJECT).bbl $(PROJECT).blg $(PROJECT).log $(PROJECT).dvi \ 14 | $(PROJECT).toc $(PROJECT).pdf $(PROJECT).ps $(PROJECT).out 15 | 16 | -------------------------------------------------------------------------------- /exercises_batch_2/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = exercises 2 | 3 | #------------------------------------------------------------------------------ 4 | protocol: 5 | #------------------------------------------------------------------------------ 6 | pdflatex $(PROJECT) 7 | pdflatex $(PROJECT) 8 | 9 | 10 | #------------------------------------------------------------------------------ 11 | clean: 12 | #------------------------------------------------------------------------------ 13 | rm -f *.aux $(PROJECT).bbl $(PROJECT).blg $(PROJECT).log $(PROJECT).dvi \ 14 | $(PROJECT).toc $(PROJECT).pdf $(PROJECT).ps $(PROJECT).out 15 | 16 | -------------------------------------------------------------------------------- /task2/src/hash.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __HASH_H 2 | #define __HASH_H 3 | 4 | #include 5 | 6 | using std::size_t; 7 | 8 | /** 9 | * The first hash function used by our cuckoo hashing. 10 | * An instance of this function must exist for each hash set 11 | * element type. 12 | */ 13 | 14 | template 15 | size_t 16 | h0(const T &item); 17 | 18 | /** 19 | * The second hash function used by our cuckoo hashing. 20 | * An instance of this function must exist for each hash set 21 | * element type. 22 | */ 23 | 24 | template 25 | size_t 26 | h1(const T &item); 27 | 28 | #endif /* __HASH_H */ 29 | -------------------------------------------------------------------------------- /task2/src/cuckoolock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __CUCKOOLOCK_H 2 | #define __CUCKOOLOCK_H 3 | 4 | #include 5 | 6 | /* 7 | * Provides the 2 dimensional array of mutexes required for CuckooSet. 8 | */ 9 | template 10 | class CuckooLock { 11 | public: 12 | CuckooLock(const size_t capacity); 13 | virtual ~CuckooLock(); 14 | 15 | void lock(const TT &item); 16 | void unlock(const TT &item); 17 | 18 | void lockAll(); 19 | void unlockAll(); 20 | 21 | void quiesce(); 22 | 23 | private: 24 | std::recursive_mutex *the_lock[2]; 25 | const size_t the_capacity; 26 | }; 27 | 28 | #endif /* __CUCKOOLOCK_H */ 29 | -------------------------------------------------------------------------------- /task1/GNUmakefile: -------------------------------------------------------------------------------- 1 | RSYNC = rsync 2 | SSH = ssh 3 | 4 | SFLAGS = -F '../.ssh-cfg' 5 | RFLAGS = --recursive --progress --copy-links --exclude=build/ -e "$(SSH) $(SFLAGS)" 6 | 7 | HOST = saturn 8 | REMOTEDIR = ~/advanced_multiprocessor_programming/task1 9 | REMOTEPHEETDIR = ~ 10 | SOURCE = . ../CMakeModules 11 | PHEETDIR = ../../pheet 12 | 13 | bake: 14 | mkdir -p build 15 | cd build; cmake -DCMAKE_BUILD_TYPE="Debug" ..; make -j6 16 | 17 | check: bake 18 | cd build; ctest --output-on-failure 19 | 20 | bench: 21 | cd $(PHEETDIR) && make clean test && bin/pheet_test 22 | 23 | hand-in: 24 | $(RSYNC) $(RFLAGS) $(PHEETDIR) $(HOST):$(REMOTEPHEETDIR) 25 | $(RSYNC) $(RFLAGS) $(SOURCE) $(HOST):$(REMOTEDIR) 26 | 27 | clean: 28 | rm -rf build 29 | -------------------------------------------------------------------------------- /task2/src/stdset.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __STDSET_H 2 | #define __STDSET_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /** 9 | * A set implemented using cuckoo hashing. 10 | */ 11 | 12 | template > 15 | class StdSet { 16 | public: 17 | StdSet() { } 18 | virtual ~StdSet() { } 19 | 20 | void put(const TT &item); 21 | bool contains(const TT &item); 22 | bool remove(const TT &item); 23 | 24 | bool is_empty(); 25 | size_t size(); 26 | 27 | static void print_name(); 28 | 29 | private: 30 | std::set the_set; 31 | std::mutex the_mutex; 32 | }; 33 | 34 | #endif /* __STDSET_H */ 35 | -------------------------------------------------------------------------------- /task2/protocol/striped.gp: -------------------------------------------------------------------------------- 1 | set terminal postscript eps enhanced size 13cm,6cm color font 'Helvetica,15' 2 | set output 'striped.eps' 3 | set xrange [1:48] 4 | set nokey 5 | set key top left 6 | set xlabel 'Number of cores [byte]' 7 | set ylabel 'Time [s]' 8 | set logscale x 2 9 | set logscale y 10 | 11 | plot \ 12 | '../data/1_striped.dat' using 1:2 title '2x1024 locks, 50% contains, 25% add operations' with linespoints,\ 13 | '../data/1_striped_8locks.dat' using 1:2 title '2x8 locks, 99% contains, 0.5% add operations' with linespoints,\ 14 | '../data/2_striped.dat' using 1:2 title '2x1024 locks, 99% contains, 0.5% add operations' with linespoints,\ 15 | '../data/2_striped_8locks.dat' using 1:2 title '2x8 locks, 50% contains, 25% add operations' with linespoints; 16 | set output 17 | -------------------------------------------------------------------------------- /task1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.0) 2 | 3 | project(task1) 4 | 5 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/../CMakeModules/") 6 | 7 | if(NOT PHEET_PATH) 8 | set(PHEET_PATH "${CMAKE_SOURCE_DIR}/../../pheet") 9 | endif() 10 | 11 | include(FindPkgConfig) 12 | pkg_search_module(HWLOC REQUIRED hwloc) 13 | 14 | find_path(PHEET_INCLUDE_DIR pheet/pheet.h PATHS ${PHEET_PATH}) 15 | if(PHEET_INCLUDE_DIR) 16 | message(STATUS "Pheet found in ${PHEET_INCLUDE_DIR}") 17 | else() 18 | message(FATAL_ERROR "Pheet not found") 19 | endif() 20 | 21 | find_package(Threads REQUIRED) 22 | 23 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 24 | add_definitions("-Wall -Wextra -pedantic -std=gnu++11 -O3") 25 | endif() 26 | 27 | add_subdirectory(src) 28 | -------------------------------------------------------------------------------- /task2/protocol/refined.gp: -------------------------------------------------------------------------------- 1 | set terminal postscript eps enhanced size 13cm,6cm color font 'Helvetica,15' 2 | set output 'refined.eps' 3 | set xrange [1:48] 4 | set nokey 5 | set key top left 6 | set xlabel 'Number of cores [byte]' 7 | set ylabel 'Time [s]' 8 | set logscale x 2 9 | #set logscale y 10 | 11 | plot \ 12 | '../data/1_refined.dat' using 1:2 title 'Refined (final implementation): 50% contains, 25% add operations' with linespoints,\ 13 | '../data/1_refined_refCounting.dat' using 1:2 title 'Refined (reference counting): 99% contains, 0.5% add operations' with linespoints,\ 14 | '../data/2_refined.dat' using 1:2 title 'Refined (final implementation): 99% contains, 0.5% add operations' with linespoints,\ 15 | '../data/2_refined_refCounting.dat' using 1:2 title 'Refined (reference counting): 50% contains, 25% add operations' with linespoints; 16 | 17 | -------------------------------------------------------------------------------- /task2/GNUmakefile: -------------------------------------------------------------------------------- 1 | RSYNC = rsync 2 | SSH = ssh 3 | 4 | SFLAGS = -F '../.ssh-cfg' 5 | RFLAGS = --recursive --progress --copy-links --exclude=build/ -e "$(SSH) $(SFLAGS)" 6 | 7 | HOST = saturn 8 | REMOTEDIR = ~/advanced_multiprocessor_programming/task2 9 | REMOTEPHEETDIR = ~ 10 | SOURCE = . ../CMakeModules 11 | PHEETDIR = ../../pheet 12 | AMPDIR = ../advanced_multiprocessor_programming/task2/build/src/ 13 | 14 | all: check 15 | 16 | bake: 17 | mkdir -p build 18 | cd build; cmake -DCMAKE_BUILD_TYPE="Debug" ..; make -j6 19 | 20 | check: bake 21 | cd build; ctest --output-on-failure 22 | 23 | bench: bake 24 | cd $(PHEETDIR) && make test && LD_LIBRARY_PATH=$(AMPDIR) bin/pheet_test 25 | 26 | hand-in: 27 | $(RSYNC) $(RFLAGS) $(PHEETDIR) $(HOST):$(REMOTEPHEETDIR) 28 | $(RSYNC) $(RFLAGS) $(SOURCE) $(HOST):$(REMOTEDIR) 29 | 30 | clean: 31 | rm -rf build 32 | -------------------------------------------------------------------------------- /task1/src/pcn.cpp: -------------------------------------------------------------------------------- 1 | #include "pcn.hpp" 2 | 3 | #include 4 | #include 5 | 6 | typedef pheet::Pheet Pheet; 7 | 8 | static void 9 | inc_n_times(PeriodicCountingNetwork *pcn, 10 | const int n) 11 | { 12 | for (int i = 0; i < n; i++) { 13 | pcn->incr(); 14 | } 15 | } 16 | 17 | int 18 | main(int argc __attribute__ ((unused)), 19 | char **argv __attribute__ ((unused))) 20 | { 21 | const int n = 50000; 22 | 23 | PeriodicCountingNetwork pcn; 24 | 25 | { 26 | Pheet::Environment p; 27 | Pheet::spawn(inc_n_times, &pcn, n); 28 | Pheet::spawn(inc_n_times, &pcn, n); 29 | Pheet::spawn(inc_n_times, &pcn, n); 30 | Pheet::spawn(inc_n_times, &pcn, n); 31 | } 32 | 33 | printf("Expected: %d Actual: %d\n", n * 4, pcn.get_sum()); 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /task2/go/src/probe/probe.go: -------------------------------------------------------------------------------- 1 | package probe 2 | 3 | import ( 4 | "errors" 5 | ) 6 | 7 | const THRESHOLD int = 8 8 | const SIZE int = 16 9 | 10 | type Set interface { 11 | Add(item int64) 12 | Contains(item int64) bool 13 | First() (int64, error) 14 | Remove(item int64) 15 | Size() int 16 | } 17 | 18 | type set map[int64]bool 19 | 20 | func NewSet() Set { 21 | return make(set) 22 | } 23 | 24 | func (p set) Add(item int64) { 25 | p[item] = true 26 | } 27 | 28 | func (p set) Contains(item int64) bool { 29 | return p[item] 30 | } 31 | 32 | func (p set) First() (int64, error) { 33 | for v := range p { 34 | return v, nil 35 | } 36 | return 0, errors.New("set: First() called on empty map") 37 | } 38 | 39 | func (p set) Remove(item int64) { 40 | delete(p, item) 41 | } 42 | 43 | func (p set) Size() int { 44 | return len(p) 45 | } 46 | -------------------------------------------------------------------------------- /task1/README: -------------------------------------------------------------------------------- 1 | Specification 2 | ============= 3 | 4 | Implement a periodic counting network using pheet and C++11 atomics. 5 | Compare performance to fetch-and-increment (using pheet benchmarks). 6 | Compare sequential with relaxed consistency. 7 | 5-minute presentation with experience, performance, code, stability, pitfalls. 8 | 9 | Dependencies 10 | ============ 11 | 12 | * Pheet (www.pheet.org) 13 | 14 | For this task, we used revision 420. After pulling pheet itself, make sure 15 | to point CMake to the correct directory. 16 | 17 | To integrate the PCN into pheet's benchmarks: 18 | 19 | * Include our pcn.h in test/count_bench/CountBench.cpp 20 | * Add a new run_bench() call to run_test() 21 | * Activate the count benchmark in test/settings.h 22 | * Add the include path in settings.mk 23 | * make test && bin/pheet_test 24 | * Optionally use csvheet to convert the output into a usable CSV format 25 | -------------------------------------------------------------------------------- /task2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6.4) 2 | 3 | project(task2) 4 | 5 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/../CMakeModules/") 6 | 7 | if(NOT PHEET_PATH) 8 | set(PHEET_PATH "${CMAKE_SOURCE_DIR}/../../pheet") 9 | endif() 10 | 11 | include(FindPkgConfig) 12 | pkg_search_module(HWLOC REQUIRED hwloc) 13 | 14 | find_path(PHEET_INCLUDE_DIR pheet/pheet.h PATHS ${PHEET_PATH}) 15 | if(PHEET_INCLUDE_DIR) 16 | message(STATUS "Pheet found in ${PHEET_INCLUDE_DIR}") 17 | else() 18 | message(FATAL_ERROR "Pheet not found") 19 | endif() 20 | 21 | find_package(Check REQUIRED) 22 | find_package(Threads REQUIRED) 23 | 24 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 25 | add_definitions("-Wall -Wextra -pedantic -std=gnu++11 -O3") 26 | endif() 27 | 28 | enable_testing() 29 | 30 | add_subdirectory(src) 31 | add_subdirectory(test) 32 | -------------------------------------------------------------------------------- /task2/src/probeset.cpp: -------------------------------------------------------------------------------- 1 | #include "probeset.hpp" 2 | 3 | template 4 | void 5 | ProbeSet::add(const T &item) 6 | { 7 | the_set.insert(item); 8 | } 9 | 10 | template 11 | T 12 | ProbeSet::first() const 13 | { 14 | return *the_set.begin(); 15 | } 16 | 17 | template 18 | bool 19 | ProbeSet::contains(const T &item) const 20 | { 21 | return (the_set.find(item) != the_set.end()); 22 | } 23 | 24 | template 25 | void 26 | ProbeSet::remove(const T &item) 27 | { 28 | the_set.erase(item); 29 | } 30 | 31 | template 32 | size_t 33 | ProbeSet::size() const 34 | { 35 | return the_set.size(); 36 | } 37 | 38 | template class ProbeSet< 39 | unsigned long, 40 | std::less>; 41 | -------------------------------------------------------------------------------- /task1/src/block.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __BLOCK_H 2 | #define __BLOCK_H 3 | 4 | #include "layer.hpp" 5 | 6 | class Block 7 | { 8 | public: 9 | Block(const int width); 10 | virtual ~Block(); 11 | 12 | int traverse(const int input); 13 | 14 | private: 15 | const int width; 16 | Block *north, *south; 17 | Layer layer; 18 | }; 19 | 20 | Block::Block(const int width) : 21 | width(width), 22 | layer(width) 23 | { 24 | if (width > 2) { 25 | north = new Block(width >> 1); 26 | south = new Block(width >> 1); 27 | } else { 28 | north = south = NULL; 29 | } 30 | } 31 | 32 | Block::~Block() 33 | { 34 | delete north; 35 | delete south; 36 | } 37 | 38 | int 39 | Block::traverse(const int input) 40 | { 41 | const int wire = layer.traverse(input); 42 | 43 | if (width <= 2) { 44 | return wire; 45 | } 46 | 47 | if (wire < width / 2) { 48 | return north->traverse(wire); 49 | } else { 50 | return width / 2 + south->traverse(wire - (width / 2)); 51 | } 52 | } 53 | 54 | #endif /* __BLOCK_H */ 55 | -------------------------------------------------------------------------------- /task1/src/layer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __LAYER_H 2 | #define __LAYER_H 3 | 4 | #include "balancer.hpp" 5 | 6 | class Layer 7 | { 8 | public: 9 | Layer(const int width); 10 | virtual ~Layer(); 11 | 12 | int traverse(const int input); 13 | 14 | private: 15 | const int width; 16 | Balancer **layer; 17 | }; 18 | 19 | Layer::Layer(const int width) : 20 | width(width) 21 | { 22 | layer = new Balancer*[width]; 23 | for (int i = 0; i < width / 2; i++) { 24 | layer[i] = layer[width - i - 1] = new Balancer(); 25 | } 26 | } 27 | 28 | Layer::~Layer() 29 | { 30 | for (int i = 0; i < width / 2; i++) { 31 | delete layer[i]; 32 | } 33 | delete[] layer; 34 | } 35 | 36 | int 37 | Layer::traverse(const int input) 38 | { 39 | const int toggle = layer[input]->traverse(); 40 | 41 | int hi, lo; 42 | if (input < width / 2) { 43 | lo = input; 44 | hi = width - input - 1; 45 | } else { 46 | lo = width - input - 1; 47 | hi = input; 48 | } 49 | 50 | return (toggle == 0) ? lo : hi; 51 | } 52 | 53 | #endif /* __LAYER_H */ 54 | -------------------------------------------------------------------------------- /task1/src/periodic.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __PERIODIC_H 2 | #define __PERIODIC_H 3 | 4 | #include "block.hpp" 5 | 6 | class Periodic 7 | { 8 | public: 9 | Periodic(const int width); 10 | virtual ~Periodic(); 11 | 12 | int traverse(const int input); 13 | 14 | private: 15 | const int width; 16 | int block_count; 17 | Block **blocks; 18 | }; 19 | 20 | static int log2(const int in) 21 | { 22 | int out = 0; 23 | int w = in; 24 | while (w >>= 1) { 25 | out++; 26 | } 27 | return out; 28 | } 29 | 30 | Periodic::Periodic(const int width) : 31 | width(width) 32 | { 33 | block_count = log2(width); 34 | blocks = new Block*[block_count]; 35 | for (int i = 0; i < block_count; i++) { 36 | blocks[i] = new Block(width); 37 | } 38 | } 39 | 40 | Periodic::~Periodic() 41 | { 42 | for (int i = 0; i < block_count; i++) { 43 | delete blocks[i]; 44 | } 45 | delete[] blocks; 46 | } 47 | 48 | int 49 | Periodic::traverse(const int input) 50 | { 51 | int wire = input; 52 | for (int i = 0; i < block_count; i++) { 53 | wire = blocks[i]->traverse(wire); 54 | } 55 | return wire; 56 | } 57 | 58 | #endif /* __PERIODIC_H */ 59 | -------------------------------------------------------------------------------- /task2/src/hash.cpp: -------------------------------------------------------------------------------- 1 | #include "hash.hpp" 2 | 3 | /* Hash functions taken from 4 | * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ 5 | 6 | static unsigned long 7 | oat_hash(const void *key, 8 | const int len) 9 | { 10 | unsigned char *p = (unsigned char *)key; 11 | unsigned long h = 0; 12 | int i; 13 | 14 | for (i = 0; i < len; i++) { 15 | h += p[i]; 16 | h += (h << 10); 17 | h ^= (h >> 6); 18 | } 19 | 20 | h += (h << 3); 21 | h ^= (h >> 11); 22 | h += (h << 15); 23 | 24 | return h; 25 | } 26 | 27 | static unsigned 28 | elf_hash(const void *key, 29 | const int len) 30 | { 31 | unsigned char *p = (unsigned char *)key; 32 | unsigned long h = 0, g; 33 | int i; 34 | for (i = 0; i < len; i++) { 35 | h = (h << 4) + p[i]; 36 | g = h & 0xf0000000L; 37 | 38 | if (g != 0) { 39 | h ^= g >> 24; 40 | } 41 | 42 | h &= ~g; 43 | } 44 | 45 | return h; 46 | } 47 | 48 | template <> 49 | size_t 50 | h0(const unsigned long &item) 51 | { 52 | return oat_hash(&item, sizeof(item)); 53 | } 54 | 55 | template <> 56 | size_t 57 | h1(const unsigned long &item) 58 | { 59 | return elf_hash(&item, sizeof(item)); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /task2/README: -------------------------------------------------------------------------------- 1 | Specification 2 | ============= 3 | 4 | Implement a parallel cuckoo hash table using pheet and C++11 atomics. 5 | 6 | Expectations 7 | ============ 8 | 9 | * Efficient and correct implementation. 10 | * Good theoretical analysis (invariants, linearizability, progress guarantees). 11 | * Good benchmark analysis. 12 | * Short document: 2-4 pages excluding plots and sourcecode. Description of data 13 | structure. Theoretical analysis. Benchmark (results, process). 14 | 15 | Dependencies 16 | ============ 17 | 18 | * Pheet (www.pheet.org) 19 | 20 | For this task, we used revision 420. After pulling pheet itself, make sure 21 | to point CMake to the correct directory. 22 | 23 | To integrate the cuckoo set into pheet's benchmarks: 24 | 25 | * Include our cuckooset.hpp in test/set_bench/SetBench.cpp 26 | * Add a new run_bench() call to run_test() 27 | * Set ACTIVE_TEST to "test_variants/amp/set.h" in test/settings.h 28 | * In settings.mk, set the: 29 | * Include path: INCLUDE_PATH = -I. -I../path/to/task2/src 30 | * Library search path as well as link libraries: 31 | TEST_LIBS = -L../path/to/task2/build/src/ -lcuckooset 32 | * make test && LD_LIBRARY_PATH=../path/to/task2/build/src/ bin/pheet_test 33 | * Optionally use csvheet to convert the output into a usable CSV format 34 | -------------------------------------------------------------------------------- /task2/src/atomicmarkablereference.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __ATOMIC_MARKABLE_REFERENCE_H 2 | #define __ATOMIC_MARKABLE_REFERENCE_H 3 | 4 | #include 5 | #include 6 | 7 | /** 8 | * A reference and a boolean value wrapped up as one atomic value. 9 | * 10 | * Note: Only works for systems using <=63 bits for addressing, since the boolean value is mapped into the reference 11 | */ 12 | 13 | class AtomicMarkableReference { 14 | public: 15 | AtomicMarkableReference(); 16 | AtomicMarkableReference(std::thread::id reference, 17 | bool mark); 18 | virtual ~AtomicMarkableReference() {} 19 | 20 | bool compareAndSet(const std::thread::id expectedReference, 21 | const std::thread::id newReference, 22 | const bool expectedMark, 23 | const bool newMark); 24 | bool attemptMark(const std::thread::id newReference, 25 | const bool newMark); 26 | void reset(); 27 | std::thread::id get(bool *mark); 28 | 29 | private: 30 | bool compareAndSet(const uint64_t expectedReference, 31 | const uint64_t newReference, 32 | const bool expectedMark, 33 | const bool newMark); 34 | 35 | private: 36 | std::atomic the_value; 37 | }; 38 | 39 | #endif /* __ATOMIC_MARKABLE_REFERENCE_H */ 40 | -------------------------------------------------------------------------------- /task2/src/stdset.cpp: -------------------------------------------------------------------------------- 1 | #include "stdset.hpp" 2 | 3 | #include 4 | 5 | template 6 | void 7 | StdSet::put(const TT &item) 8 | { 9 | std::lock_guard lock(the_mutex); 10 | the_set.insert(item); 11 | } 12 | 13 | template 14 | bool 15 | StdSet::contains(const TT &item) 16 | { 17 | std::lock_guard lock(the_mutex); 18 | return (the_set.find(item) != the_set.end()); 19 | } 20 | 21 | template 22 | bool 23 | StdSet::remove(const TT &item) 24 | { 25 | std::lock_guard lock(the_mutex); 26 | return (the_set.erase(item) > 0); 27 | } 28 | 29 | template 30 | bool 31 | StdSet::is_empty() 32 | { 33 | std::lock_guard lock(the_mutex); 34 | return the_set.empty(); 35 | } 36 | 37 | template 38 | size_t 39 | StdSet::size() 40 | { 41 | std::lock_guard lock(the_mutex); 42 | return the_set.size(); 43 | } 44 | 45 | template 46 | void 47 | StdSet::print_name() 48 | { 49 | std::cout << "StdSet"; 50 | } 51 | 52 | template class StdSet< 53 | pheet::PheetEnv< 54 | pheet::BStrategyScheduler, 55 | pheet::SystemModel, 56 | pheet::Primitives, 57 | pheet::DataStructures, 58 | pheet::ConcurrentDataStructures>, 59 | unsigned long, 60 | std::less>; 61 | -------------------------------------------------------------------------------- /task2/src/cuckoolock.cpp: -------------------------------------------------------------------------------- 1 | #include "cuckoolock.hpp" 2 | 3 | #include 4 | 5 | #include "hash.hpp" 6 | 7 | template 8 | CuckooLock::CuckooLock(const size_t capacity) 9 | : the_capacity(capacity) 10 | { 11 | the_lock[0] = new std::recursive_mutex[the_capacity]; 12 | the_lock[1] = new std::recursive_mutex[the_capacity]; 13 | } 14 | 15 | template 16 | CuckooLock::~CuckooLock() 17 | { 18 | delete[] the_lock[0]; 19 | delete[] the_lock[1]; 20 | } 21 | 22 | template 23 | void 24 | CuckooLock::lock(const TT &item) 25 | { 26 | const size_t hash0 = h0(item) % the_capacity; 27 | const size_t hash1 = h1(item) % the_capacity; 28 | the_lock[0][hash0].lock(); 29 | the_lock[1][hash1].lock(); 30 | } 31 | 32 | template 33 | void 34 | CuckooLock::unlock(const TT &item) 35 | { 36 | const size_t hash0 = h0(item) % the_capacity; 37 | const size_t hash1 = h1(item) % the_capacity; 38 | the_lock[0][hash0].unlock(); 39 | the_lock[1][hash1].unlock(); 40 | } 41 | 42 | template 43 | void 44 | CuckooLock::lockAll() 45 | { 46 | for (size_t i = 0; i < the_capacity; i++) { 47 | the_lock[0][i].lock(); 48 | } 49 | } 50 | 51 | template 52 | void 53 | CuckooLock::unlockAll() 54 | { 55 | for (size_t i = 0; i < the_capacity; i++) { 56 | the_lock[0][i].unlock(); 57 | } 58 | } 59 | 60 | template 61 | void 62 | CuckooLock::quiesce() 63 | { 64 | for (size_t i = 0; i < the_capacity; i++) { 65 | the_lock[0][i].lock(); 66 | the_lock[0][i].unlock(); 67 | } 68 | } 69 | 70 | template class CuckooLock; 71 | -------------------------------------------------------------------------------- /CMakeModules/FindCheck.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find the CHECK libraries 2 | # Once done this will define 3 | # 4 | # CHECK_FOUND - system has check 5 | # CHECK_INCLUDE_DIRS - the check include directory 6 | # CHECK_LIBRARIES - check library 7 | # 8 | # Copyright (c) 2007 Daniel Gollub 9 | # Copyright (c) 2007-2009 Bjoern Ricks 10 | # 11 | # Redistribution and use is allowed according to the terms of the New 12 | # BSD license. 13 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 14 | 15 | 16 | INCLUDE( FindPkgConfig ) 17 | 18 | IF ( Check_FIND_REQUIRED ) 19 | SET( _pkgconfig_REQUIRED "REQUIRED" ) 20 | ELSE( Check_FIND_REQUIRED ) 21 | SET( _pkgconfig_REQUIRED "" ) 22 | ENDIF ( Check_FIND_REQUIRED ) 23 | 24 | IF ( CHECK_MIN_VERSION ) 25 | PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check>=${CHECK_MIN_VERSION} ) 26 | ELSE ( CHECK_MIN_VERSION ) 27 | PKG_SEARCH_MODULE( CHECK ${_pkgconfig_REQUIRED} check ) 28 | ENDIF ( CHECK_MIN_VERSION ) 29 | 30 | # Look for CHECK include dir and libraries 31 | IF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND ) 32 | 33 | FIND_PATH( CHECK_INCLUDE_DIRS check.h ) 34 | 35 | FIND_LIBRARY( CHECK_LIBRARIES NAMES check ) 36 | 37 | IF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) 38 | SET( CHECK_FOUND 1 ) 39 | IF ( NOT Check_FIND_QUIETLY ) 40 | MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" ) 41 | ENDIF ( NOT Check_FIND_QUIETLY ) 42 | ELSE ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) 43 | IF ( Check_FIND_REQUIRED ) 44 | MESSAGE( FATAL_ERROR "Could NOT find CHECK" ) 45 | ELSE ( Check_FIND_REQUIRED ) 46 | IF ( NOT Check_FIND_QUIETLY ) 47 | MESSAGE( STATUS "Could NOT find CHECK" ) 48 | ENDIF ( NOT Check_FIND_QUIETLY ) 49 | ENDIF ( Check_FIND_REQUIRED ) 50 | ENDIF ( CHECK_INCLUDE_DIRS AND CHECK_LIBRARIES ) 51 | ENDIF( NOT CHECK_FOUND AND NOT PKG_CONFIG_FOUND ) 52 | 53 | # Hide advanced variables from CMake GUIs 54 | MARK_AS_ADVANCED( CHECK_INCLUDE_DIRS CHECK_LIBRARIES ) 55 | 56 | -------------------------------------------------------------------------------- /task2/src/cuckooset.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __CUCKOOSET_H 2 | #define __CUCKOOSET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "atomicmarkablereference.hpp" 10 | #include "cuckoolock.hpp" 11 | #include "probeset.hpp" 12 | 13 | /** 14 | * A set implemented using cuckoo hashing. 15 | */ 16 | 17 | template > 20 | class CuckooSet { 21 | public: 22 | CuckooSet(); 23 | virtual ~CuckooSet(); 24 | 25 | void put(const TT &item); 26 | bool contains(const TT &item); 27 | bool remove(const TT &item); 28 | 29 | bool is_empty(); 30 | size_t size(); 31 | 32 | static void print_name(); 33 | 34 | private: 35 | void acquire(const TT &item); 36 | void release(const TT &item); 37 | void resize(const size_t capacity); 38 | bool relocate(const int k, const size_t h); 39 | 40 | /** Checks if the item is contained in this set. 41 | * A lock must have been acquired before this function is called. */ 42 | bool contains_nolock(const TT &item); 43 | void quiesce(); 44 | 45 | 46 | private: 47 | ProbeSet *the_table[2]; 48 | std::atomic the_size; 49 | std::atomic the_capacity; 50 | CuckooLock *the_lock; 51 | std::vector *> old_locks; 52 | AtomicMarkableReference the_owner; 53 | 54 | private: 55 | class LockGuard { 56 | public: 57 | LockGuard(CuckooSet *set, const TT &item); 58 | ~LockGuard(); 59 | void release(); 60 | 61 | private: 62 | CuckooSet *set; 63 | const TT &item; 64 | bool is_released; 65 | }; 66 | 67 | class GlobalLockGuard { 68 | public: 69 | GlobalLockGuard(CuckooSet *set); 70 | ~GlobalLockGuard(); 71 | void release(); 72 | 73 | private: 74 | CuckooSet *set; 75 | bool is_released; 76 | }; 77 | 78 | }; 79 | 80 | #endif /* __CUCKOOSET_H */ 81 | -------------------------------------------------------------------------------- /task1/src/pcn.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __PCN_H 2 | #define __PCN_H 3 | 4 | #include 5 | #include 6 | 7 | #include "periodic.hpp" 8 | 9 | template 10 | class PeriodicCountingNetwork 11 | { 12 | public: 13 | PeriodicCountingNetwork(); 14 | virtual ~PeriodicCountingNetwork(); 15 | 16 | void incr(); 17 | T get_sum(); 18 | 19 | static void print_name(); 20 | 21 | private: 22 | Periodic *periodic; 23 | std::atomic *out; 24 | 25 | int pcn_width; 26 | }; 27 | 28 | /** 29 | * What's the point of the counting network if the sum is not returned 30 | * from incr()? If we need to sum up all values, why not just use one 31 | * atomic per thread and sum those up? Less processing, better locality. 32 | */ 33 | 34 | template 35 | PeriodicCountingNetwork::PeriodicCountingNetwork() 36 | { 37 | typename Pheet::MachineModel mm; 38 | int thread_count = std::min(mm.get_num_leaves(), Pheet::Environment::max_cpus); 39 | 40 | pcn_width = 1; 41 | while (pcn_width < thread_count) { 42 | pcn_width <<= 1; 43 | } 44 | 45 | periodic = new Periodic(pcn_width); 46 | out = new std::atomic[pcn_width]; 47 | 48 | for (int i = 0; i < pcn_width; i++) { 49 | out[i] = i - pcn_width + 1; 50 | } 51 | } 52 | 53 | template 54 | PeriodicCountingNetwork::~PeriodicCountingNetwork() 55 | { 56 | delete periodic; 57 | } 58 | 59 | template 60 | void 61 | PeriodicCountingNetwork::incr() 62 | { 63 | const int id = Pheet::get_place_id(); 64 | out[periodic->traverse(id)].fetch_add(pcn_width, std::memory_order_relaxed); 65 | } 66 | 67 | template 68 | T 69 | PeriodicCountingNetwork::get_sum() 70 | { 71 | T max = 0; 72 | for (int i = 0; i < pcn_width; i++) { 73 | const T next = out[i].load(std::memory_order_relaxed); 74 | if (next > max) { 75 | max = next; 76 | } 77 | } 78 | return max; 79 | } 80 | 81 | template 82 | void 83 | PeriodicCountingNetwork::print_name() 84 | { 85 | std::cout << "PeriodicCountingNetwork"; 86 | } 87 | 88 | #endif /* __PCN_H */ 89 | -------------------------------------------------------------------------------- /task2/src/atomicmarkablereference.cpp: -------------------------------------------------------------------------------- 1 | #include "atomicmarkablereference.hpp" 2 | 3 | #define TID(id) *((uint64_t *)&id) 4 | 5 | AtomicMarkableReference:: 6 | AtomicMarkableReference() 7 | { 8 | static_assert(sizeof(uint64_t) == sizeof(std::thread::id), 9 | "This class heavily relies on std::thread::id being " 10 | "of equal size as uint64_t"); 11 | the_value = 0; 12 | } 13 | 14 | AtomicMarkableReference:: 15 | AtomicMarkableReference(std::thread::id reference, 16 | bool mark) 17 | { 18 | static_assert(sizeof(uint64_t) == sizeof(std::thread::id), 19 | "This class heavily relies on std::thread::id being " 20 | "of equal size as uint64_t"); 21 | the_value = (uint64_t)mark | TID(reference) << 1; 22 | } 23 | 24 | bool 25 | AtomicMarkableReference:: 26 | compareAndSet(const std::thread::id expectedReference, 27 | const std::thread::id newReference, 28 | const bool expectedMark, 29 | const bool newMark) 30 | { 31 | return compareAndSet(TID(expectedReference), 32 | TID(newReference), 33 | expectedMark, 34 | newMark); 35 | } 36 | 37 | bool 38 | AtomicMarkableReference:: 39 | attemptMark(const std::thread::id newReference, 40 | const bool newMark) 41 | { 42 | return compareAndSet(0, TID(newReference), false, newMark); 43 | } 44 | 45 | void 46 | AtomicMarkableReference:: 47 | reset() 48 | { 49 | the_value = 0; 50 | } 51 | 52 | std::thread::id 53 | AtomicMarkableReference:: 54 | get(bool *mark) 55 | { 56 | *mark = the_value & 1; 57 | uint64_t val = (the_value >> 1); 58 | return ((std::thread::id)val); 59 | } 60 | 61 | bool 62 | AtomicMarkableReference:: 63 | compareAndSet(const uint64_t expectedReference, 64 | const uint64_t newReference, 65 | const bool expectedMark, 66 | const bool newMark) 67 | { 68 | /* TODO: casting std::thread::id to uint64_t might be dangerous!! 69 | * std::thread::id does not give any guarantees except for it to 70 | * be unique for each thread. */ 71 | uint64_t expected = (uint64_t)expectedMark | expectedReference << 1; 72 | const uint64_t update = (uint64_t)newMark | newReference << 1; 73 | 74 | return the_value.compare_exchange_strong(expected, update); 75 | } 76 | -------------------------------------------------------------------------------- /task2/data/striped_8locks.dat: -------------------------------------------------------------------------------- 1 | make: Nothing to be done for `test'. 2 | ---- 3 | test set scheduler range blocks contains_p add_p seed cpus total_time 4 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 17.0639 5 | test set scheduler range blocks contains_p add_p seed cpus total_time 6 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 27.3843 7 | test set scheduler range blocks contains_p add_p seed cpus total_time 8 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 55.959 9 | test set scheduler range blocks contains_p add_p seed cpus total_time 10 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 67.9859 11 | test set scheduler range blocks contains_p add_p seed cpus total_time 12 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 137.608 13 | test set scheduler range blocks contains_p add_p seed cpus total_time 14 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 223.717 15 | test set scheduler range blocks contains_p add_p seed cpus total_time 16 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 282.758 17 | test set scheduler range blocks contains_p add_p seed cpus total_time 18 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.1768 19 | test set scheduler range blocks contains_p add_p seed cpus total_time 20 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 51.0492 21 | test set scheduler range blocks contains_p add_p seed cpus total_time 22 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 63.6165 23 | test set scheduler range blocks contains_p add_p seed cpus total_time 24 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 80.9278 25 | test set scheduler range blocks contains_p add_p seed cpus total_time 26 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 167.1 27 | test set scheduler range blocks contains_p add_p seed cpus total_time 28 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 247.33 29 | -------------------------------------------------------------------------------- /task2/go/src/cuckoo/cuckoo_test.go: -------------------------------------------------------------------------------- 1 | package cuckoo 2 | 3 | import ( 4 | "runtime" 5 | "sync" 6 | "testing" 7 | ) 8 | 9 | func Test_Empty(t *testing.T) { 10 | s := NewSet() 11 | if !s.IsEmpty() { 12 | t.Fail() 13 | } 14 | } 15 | 16 | func Test_Put(t *testing.T) { 17 | s := NewSet() 18 | s.Put(42) 19 | if s.Size() != 1 { 20 | t.Fail() 21 | } 22 | if !s.Contains(42) { 23 | t.Fail() 24 | } 25 | if s.Contains(41) { 26 | t.Fail() 27 | } 28 | } 29 | 30 | func Test_PutDuplicate(t *testing.T) { 31 | s := NewSet() 32 | s.Put(42) 33 | s.Put(42) 34 | if s.Size() != 1 { 35 | t.Fail() 36 | } 37 | if !s.Contains(42) { 38 | t.Fail() 39 | } 40 | if s.Contains(41) { 41 | t.Fail() 42 | } 43 | } 44 | 45 | func Test_Remove(t *testing.T) { 46 | s := NewSet() 47 | s.Put(42) 48 | s.Put(43) 49 | s.Remove(42) 50 | if s.Size() != 1 { 51 | t.Fail() 52 | } 53 | if !s.Contains(43) { 54 | t.Fail() 55 | } 56 | if s.Contains(42) { 57 | t.Fail() 58 | } 59 | } 60 | 61 | func Test_Smoke1000(t *testing.T) { 62 | test_Smoke(t, 1000) 63 | } 64 | 65 | func Test_Smoke10000(t *testing.T) { 66 | test_Smoke(t, 10000) 67 | } 68 | 69 | func Test_Smoke123456(t *testing.T) { 70 | test_Smoke(t, 123456) 71 | } 72 | 73 | func test_Smoke(t *testing.T, n int) { 74 | threads := runtime.NumCPU() 75 | runtime.GOMAXPROCS(threads) 76 | s := NewSet() 77 | step := n / threads 78 | 79 | var wg sync.WaitGroup 80 | wg.Add(threads * 2) 81 | 82 | for i := 0; i < threads; i++ { 83 | go func(i int) { 84 | defer wg.Done() 85 | for j := i * step; j < (i + 1) * step; j++ { 86 | s.Put(int64(j)) 87 | } 88 | }(i) 89 | go func(i int) { 90 | defer wg.Done() 91 | for j := i * step; j < (i + 1) * step; j++ { 92 | s.Contains(int64(j)) 93 | } 94 | }(i) 95 | } 96 | 97 | wg.Wait() 98 | 99 | if s.Size() != step * threads { 100 | t.Errorf("Unexpected Size(): %d != %d\n", s.Size(), step * threads) 101 | } 102 | 103 | wg.Add(threads) 104 | 105 | for i := 0; i < threads; i++ { 106 | go func(i int) { 107 | defer wg.Done() 108 | for j := i * step; j < (i + 1) * step; j++ { 109 | s.Remove(int64(j)) 110 | } 111 | }(i) 112 | } 113 | 114 | wg.Wait() 115 | 116 | if s.Size() != 0 { 117 | t.Errorf("Unexpected Size(): %d != %d\n", s.Size(), step * threads) 118 | } 119 | 120 | wg.Add(threads * 2) 121 | 122 | for i := 0; i < threads; i++ { 123 | go func(i int) { 124 | defer wg.Done() 125 | for j := i * step; j < (i + 1) * step; j++ { 126 | s.Put(int64(j)) 127 | } 128 | }(i) 129 | go func(i int) { 130 | defer wg.Done() 131 | for j := i * step; j < (i + 1) * step; j++ { 132 | s.Remove(int64(j)) 133 | } 134 | }(i) 135 | } 136 | 137 | wg.Wait() 138 | } 139 | 140 | func Benchmark_1Thread(b *testing.B) { 141 | s := NewSet() 142 | 143 | threads := runtime.NumCPU() 144 | step := b.N / threads 145 | 146 | var wg sync.WaitGroup 147 | wg.Add(threads) 148 | 149 | b.ResetTimer() 150 | for i := 0; i < threads; i++ { 151 | go func(i int) { 152 | defer wg.Done() 153 | for j := i * step; j < (i + 1) * step; j++ { 154 | s.Put(int64(j)) 155 | } 156 | }(i) 157 | } 158 | 159 | wg.Wait() 160 | } 161 | -------------------------------------------------------------------------------- /task2/test/cuckooset.cpp: -------------------------------------------------------------------------------- 1 | #include "cuckooset.hpp" 2 | 3 | #include 4 | 5 | #define ITERS (123456) 6 | 7 | START_TEST(test_sanity) 8 | { 9 | CuckooSet set; 10 | fail_unless(1 == 1); 11 | } 12 | END_TEST 13 | 14 | START_TEST(empty_is_empty) 15 | { 16 | CuckooSet set; 17 | fail_unless(set.is_empty()); 18 | } 19 | END_TEST 20 | 21 | START_TEST(empty_is_size_0) 22 | { 23 | CuckooSet set; 24 | fail_unless(set.size() == 0); 25 | } 26 | END_TEST 27 | 28 | START_TEST(contains_1) 29 | { 30 | CuckooSet set; 31 | fail_unless(!set.contains(1)); 32 | } 33 | END_TEST 34 | 35 | START_TEST(contains_2) 36 | { 37 | CuckooSet set; 38 | set.put(1); 39 | fail_unless(set.contains(1)); 40 | } 41 | END_TEST 42 | 43 | START_TEST(contains_3) 44 | { 45 | CuckooSet set; 46 | set.put(1); 47 | set.remove(1); 48 | fail_unless(!set.contains(1)); 49 | } 50 | END_TEST 51 | 52 | START_TEST(contains_4) 53 | { 54 | CuckooSet set; 55 | set.put(1); 56 | fail_unless(set.contains(1)); 57 | fail_unless(!set.contains(2)); 58 | } 59 | END_TEST 60 | 61 | START_TEST(put_1) 62 | { 63 | CuckooSet set; 64 | set.put(1); 65 | set.put(1); 66 | set.put(1); 67 | fail_unless(set.contains(1)); 68 | } 69 | END_TEST 70 | 71 | START_TEST(put_2) 72 | { 73 | CuckooSet set; 74 | 75 | srand(42); 76 | 77 | unsigned int size = 0; 78 | for (int i = 0; i < ITERS; i++) { 79 | const int v = rand(); 80 | if (!set.contains(v)) { 81 | size++; 82 | } 83 | set.put(v); 84 | } 85 | fail_unless(set.size() == size); 86 | } 87 | END_TEST 88 | 89 | START_TEST(remove_1) 90 | { 91 | CuckooSet set; 92 | 93 | srand(42); 94 | 95 | unsigned int size = 0; 96 | for (int i = 0; i < ITERS; i++) { 97 | const int v = rand(); 98 | if (!set.contains(v)) { 99 | size++; 100 | } 101 | set.put(v); 102 | } 103 | fail_unless(set.size() == size); 104 | 105 | /* The following element is part of the random sequence, but 106 | * got lost somehow. Ensure it's actually in the set. */ 107 | fail_unless(set.contains(424036140)); 108 | 109 | srand(42); 110 | 111 | for (int i = 0; i < ITERS; i++) { 112 | set.remove(rand()); 113 | } 114 | fail_unless(set.size() == 0); 115 | } 116 | END_TEST 117 | 118 | static void 119 | put_wrapper(CuckooSet *set, 120 | const unsigned long v) 121 | { 122 | set->put(v); 123 | } 124 | 125 | static void 126 | contains_wrapper(CuckooSet *set, 127 | const unsigned long v) 128 | { 129 | set->contains(v); 130 | } 131 | 132 | static void 133 | remove_wrapper(CuckooSet *set, 134 | const unsigned long v) 135 | { 136 | set->remove(v); 137 | } 138 | 139 | START_TEST(smoke_1) 140 | { 141 | CuckooSet set; 142 | 143 | { 144 | pheet::Pheet::Environment env; 145 | 146 | for (int i = 0; i < ITERS; i++) { 147 | pheet::Pheet::spawn(put_wrapper, &set, i); 148 | } 149 | } 150 | 151 | fail_unless(set.size() == ITERS); 152 | } 153 | END_TEST 154 | 155 | START_TEST(smoke_2) 156 | { 157 | CuckooSet set; 158 | 159 | { 160 | pheet::Pheet::Environment env; 161 | 162 | for (int i = 0; i < ITERS; i++) { 163 | pheet::Pheet::spawn(put_wrapper, &set, i); 164 | pheet::Pheet::spawn(contains_wrapper, &set, (i + 12345) % ITERS); 165 | } 166 | } 167 | 168 | fail_unless(set.size() == ITERS); 169 | } 170 | END_TEST 171 | 172 | START_TEST(smoke_3) 173 | { 174 | CuckooSet set; 175 | 176 | { 177 | pheet::Pheet::Environment env; 178 | 179 | for (int i = 0; i < ITERS; i++) { 180 | pheet::Pheet::spawn(put_wrapper, &set, i); 181 | } 182 | } 183 | 184 | { 185 | pheet::Pheet::Environment env; 186 | 187 | for (int i = 0; i < ITERS; i++) { 188 | pheet::Pheet::spawn(remove_wrapper, &set, i); 189 | } 190 | } 191 | 192 | fail_unless(set.size() == 0); 193 | } 194 | END_TEST 195 | 196 | static Suite * 197 | create_suite(void) 198 | { 199 | Suite *s = suite_create(__FILE__); 200 | TCase *tc_core = tcase_create("core"); 201 | 202 | tcase_add_test(tc_core, test_sanity); 203 | tcase_add_test(tc_core, empty_is_empty); 204 | tcase_add_test(tc_core, empty_is_size_0); 205 | tcase_add_test(tc_core, contains_1); 206 | tcase_add_test(tc_core, contains_2); 207 | tcase_add_test(tc_core, contains_3); 208 | tcase_add_test(tc_core, contains_4); 209 | tcase_add_test(tc_core, put_1); 210 | tcase_add_test(tc_core, put_2); 211 | tcase_add_test(tc_core, remove_1); 212 | 213 | TCase *tc_smoke = tcase_create("parallel_smoke"); 214 | 215 | tcase_add_test(tc_core, smoke_1); 216 | tcase_add_test(tc_core, smoke_2); 217 | tcase_add_test(tc_core, smoke_3); 218 | 219 | suite_add_tcase(s, tc_core); 220 | suite_add_tcase(s, tc_smoke); 221 | 222 | return s; 223 | } 224 | 225 | int 226 | main(int argc __attribute__ ((unused)), 227 | char **argv __attribute__ ((unused))) 228 | { 229 | int number_failed; 230 | Suite *s = create_suite(); 231 | SRunner *sr = srunner_create(s); 232 | srunner_run_all(sr, CK_NORMAL); 233 | number_failed = srunner_ntests_failed(sr); 234 | srunner_free(sr); 235 | 236 | return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 237 | } 238 | -------------------------------------------------------------------------------- /task1/presentation/presentation.tex: -------------------------------------------------------------------------------- 1 | \documentclass[notes=show]{beamer} 2 | 3 | \usepackage{comment} 4 | \usepackage{default} 5 | \usepackage[utf8]{inputenc} 6 | \usepackage{listings} 7 | 8 | \definecolor{OliveGreen}{cmyk}{0.64,0,0.95,0.40} 9 | \definecolor{Gray}{gray}{0.5} 10 | 11 | \lstset{ 12 | language=C, 13 | basicstyle=\ttfamily\scriptsize, 14 | keywordstyle=\color{OliveGreen}, 15 | commentstyle=\color{Gray}, 16 | captionpos=b, 17 | breaklines=true, 18 | breakatwhitespace=false, 19 | showspaces=false, 20 | showtabs=false, 21 | numbers=left, 22 | } 23 | 24 | \begin{document} 25 | 26 | \begin{frame} 27 | \frametitle{Periodic Counting Network} 28 | \begin{itemize} 29 | \item A parallel way of counting. 30 | \item Replaces one bottleneck (the counter) with multiple bottlenecks. 31 | \item Maximum throughput when the number of tokens is roughly equal to the number of 32 | balancers in the network. 33 | \end{itemize} 34 | \end{frame} 35 | \note{A note} % TODO 36 | 37 | \begin{frame} 38 | \frametitle{Periodic Counting Network} 39 | \begin{itemize} 40 | \item Principle: Given a a number of inputs $x_i$ and outputs $y_i$ and a network width $w$, 41 | transform an unpredictable sequence of inputs ($x_3, x_2, x_2, x_0, x_1$) into a sequential 42 | output sequence ($y_0, y_1, y_2, y_3, y_0$). 43 | \item Each thread can tell its result without consulting other counters. 44 | \item A periodic counting network consists of a sequence of identical subnetworks. 45 | \end{itemize} 46 | \end{frame} 47 | 48 | \begin{frame} 49 | \frametitle{Experience} 50 | \begin{itemize} 51 | \item Not much contact with pheet. 52 | \item Difficult to integrate into my usual project setup (git, automated 53 | hand-in and unit tests). 54 | \item Saturn is partly outdated, 55 | missing CMake files, and has components installed in odd locations. 56 | \item Template programming requires headers-only or explicitly instantiating all 57 | required template instances before use. 58 | \end{itemize} 59 | \end{frame} 60 | \note{ 61 | First of all, I didn't actually have much contact with pheet, so there's not too 62 | much to say about that. \\ 63 | Integration was somewhat harder than usual because pheet doesn't use git and 64 | I didn't want to copy the entire source tree into my repository. \\ 65 | With template programming, there was a choice of writing everything in headers only, 66 | or instantiating the required template types somewhere. And I went with headers, simply 67 | because it was less work to set up. 68 | } 69 | 70 | \begin{frame}[fragile] 71 | \frametitle{Code} 72 | \framesubtitle{incr()} 73 | \begin{lstlisting} 74 | template 75 | void 76 | PeriodicCountingNetwork::incr() 77 | { 78 | const int id = Pheet::get_place_id(); 79 | out[periodic->traverse(id)].fetch_add(pcn_width, std::memory_order_relaxed); 80 | } 81 | \end{lstlisting} 82 | \end{frame} 83 | \note{This is the code; 84 | Again, there's not much to be said about this, because it's simply the algorithm from the 85 | book ported to C++. This slide shows the how a counter is incremented by the network width 86 | after traversing the network.} 87 | 88 | \begin{frame}[fragile] 89 | \frametitle{Code} 90 | \framesubtitle{get\_sum()} 91 | \begin{lstlisting} 92 | int 93 | Block::traverse(const int input) 94 | { 95 | const int wire = layer.traverse(input); 96 | 97 | if (width <= 2) { 98 | return wire; 99 | } 100 | 101 | if (wire < width / 2) { 102 | return north->traverse(wire); 103 | } else { 104 | return width / 2 + south->traverse(wire - (width / 2)); 105 | } 106 | } 107 | \end{lstlisting} 108 | \end{frame} 109 | \note{Here's the recursive traversal of a single block.} 110 | 111 | \begin{frame} 112 | \frametitle{Results - Intel i5 760 Quad @ 2.80 GHz} 113 | 114 | \begin{itemize} 115 | \item Compiled with g++-4.8, \lstinline|-std=gnu++11 -O3| 116 | \item 4 inputs and outputs 117 | \end{itemize} 118 | 119 | \includegraphics[width=\textwidth]{core_i5} 120 | \end{frame} 121 | \note{Here are some results from my own desktop compiled with GCC 4.8, and with 4 inputs and 122 | outputs. 123 | And as you can see the \lstinline|fetch_add| implementation actually scales fairly well, 124 | and performs better than the counting network by around a factor of two. 125 | I also tested sequential vs relaxed consistency but it made no noticeable difference.} 126 | 127 | 128 | \begin{frame} 129 | \frametitle{Results - Saturn} 130 | \begin{itemize} 131 | \item Compiled with g++-4.7, \lstinline|-std=gnu++11 -O3| 132 | \item 48 inputs and outputs 133 | \end{itemize} 134 | 135 | \includegraphics[width=\textwidth]{saturn} 136 | \end{frame} 137 | \note{I also benchmarked on the saturn system, this time with GCC 4.7 and 48 inputs and outputs. 138 | There were a couple of differences; for instance, \lstinline|fetch_add| did not scale at all, with 139 | times staying more or less constant. 140 | The counting network was also much slower. Interestingy, the sequential implementation 141 | was four times faster than using two threads. The best performance at around 24 142 | processes was still ten times slower than the \lstinline|fetch_add| implementation.} 143 | 144 | \begin{frame} 145 | \frametitle{Reasons?} 146 | \begin{itemize} 147 | \item Valgrind shows nothing interesting, code seems to be sane. 148 | \item Counting networks unsuited for this task (we don't return count after inc, thus 149 | losing a major advantage). 150 | \item Many! more instructions instead of a single \lstinline|fetch_add|. 151 | \item No thread locality. 152 | \end{itemize} 153 | \end{frame} 154 | \note{So what are the reasons for these results? Valgrind did not turn up any problems, so 155 | the implementation seems to be sane. 156 | 157 | One of the major advantages of counting networks is that each thread can arrive at the current count 158 | at the end of an \lstinline|incr()| operation. Since these are not needed here, we could have just 159 | created a single counter per thread instead of using a counting network. 160 | 161 | Of course traversing a network uses many more instructions than simply doing a \lstinline|fetch_add|. 162 | 163 | Finally, a counting network has very bad thread locality; most balancers could be used by 164 | every thread at once. 165 | } 166 | 167 | \begin{frame} 168 | \frametitle{THE END} 169 | \end{frame} 170 | 171 | \end{document} 172 | -------------------------------------------------------------------------------- /task2/go/src/cuckoo/cuckoo.go: -------------------------------------------------------------------------------- 1 | package cuckoo 2 | 3 | import ( 4 | "encoding/binary" 5 | "probe" 6 | "sync" 7 | "sync/atomic" 8 | "time" 9 | ) 10 | 11 | type itemLocker interface { 12 | Lock(item int64) 13 | LockAll() bool 14 | Unlock(item int64) 15 | UnlockAll() 16 | } 17 | 18 | type itemLock struct { 19 | s *set 20 | } 21 | 22 | func (i *itemLock) Lock(item int64) { 23 | for { 24 | for atomic.LoadInt32(&i.s.resizing) == 1 { 25 | /* Spin. */ 26 | time.Sleep(50 * time.Nanosecond) 27 | } 28 | 29 | oldMutex := i.s.mutex 30 | 31 | oldMutex0 := &oldMutex[0][h0(item) % uint(len(oldMutex[0]))] 32 | oldMutex1 := &oldMutex[1][h1(item) % uint(len(oldMutex[1]))] 33 | 34 | oldMutex0.Lock() 35 | oldMutex1.Lock() 36 | 37 | if atomic.LoadInt32(&i.s.resizing) == 0 && oldMutex == i.s.mutex { 38 | return 39 | } else { 40 | oldMutex0.Unlock() 41 | oldMutex1.Unlock() 42 | } 43 | } 44 | } 45 | 46 | func (i *itemLock) Unlock(item int64) { 47 | i.s.mutex[0][h0(item) % uint(len(i.s.mutex[0]))].Unlock() 48 | i.s.mutex[1][h1(item) % uint(len(i.s.mutex[1]))].Unlock() 49 | } 50 | 51 | func (i *itemLock) LockAll() bool { 52 | if !atomic.CompareAndSwapInt32(&i.s.resizing, 0, 1) { 53 | return false 54 | } 55 | 56 | for j := 0; j < len(i.s.mutex[0]); j++ { 57 | i.s.mutex[0][j].Lock() 58 | i.s.mutex[0][j].Unlock() 59 | } 60 | 61 | return true 62 | } 63 | 64 | func (i *itemLock) UnlockAll() { 65 | atomic.StoreInt32(&i.s.resizing, 0) 66 | } 67 | 68 | func newItemLock(s *set) *itemLock { 69 | i := new(itemLock) 70 | i.s = s 71 | return i 72 | } 73 | 74 | type noopLock int8 75 | 76 | func (i noopLock) Lock(item int64) { 77 | /* Nothing */ 78 | } 79 | 80 | func (i noopLock) Unlock(item int64) { 81 | /* Nothing */ 82 | } 83 | 84 | func (i noopLock) LockAll() bool { 85 | return true 86 | } 87 | 88 | func (i noopLock) UnlockAll() { 89 | /* Nothing */ 90 | } 91 | 92 | func newNoopLock() *noopLock { 93 | var lock noopLock 94 | return &lock 95 | } 96 | 97 | type Set interface { 98 | Put(item int64) 99 | Contains(item int64) bool 100 | Remove(item int64) bool 101 | 102 | IsEmpty() bool 103 | Size() int 104 | } 105 | 106 | const INITIAL_CAPACITY int64 = 1024 107 | 108 | type set struct { 109 | size, capacity int64 110 | table [2][]probe.Set 111 | mutex *[2][]sync.Mutex 112 | resizing int32 113 | } 114 | 115 | func NewSet() Set { 116 | s := new(set) 117 | s.capacity = INITIAL_CAPACITY; 118 | s.initSets(int(INITIAL_CAPACITY)) 119 | return s 120 | } 121 | 122 | func (s *set) putStep1(item int64) (i, h int, mustResize bool) { 123 | i = -1 124 | 125 | lock := newNoopLock() 126 | if s.contains(item, lock) { 127 | return 128 | } 129 | 130 | hash0, hash1 := s.h0(item), s.h1(item) 131 | p0, p1 := s.table[0][hash0], s.table[1][hash1] 132 | 133 | switch { 134 | case p0.Size() < probe.THRESHOLD: 135 | p0.Add(item) 136 | atomic.AddInt64(&s.size, 1) 137 | return 138 | case p0.Size() < probe.THRESHOLD: 139 | p1.Add(item) 140 | atomic.AddInt64(&s.size, 1) 141 | return 142 | case p0.Size() < probe.SIZE: 143 | p0.Add(item) 144 | atomic.AddInt64(&s.size, 1) 145 | i = 0 146 | h = hash0 147 | return 148 | case p1.Size() < probe.SIZE: 149 | p1.Add(item) 150 | atomic.AddInt64(&s.size, 1) 151 | i = 1 152 | h = hash1 153 | return 154 | default: 155 | mustResize = true 156 | } 157 | return 158 | } 159 | 160 | func (s *set) Put(item int64) { 161 | s.put(item, newItemLock(s)) 162 | } 163 | 164 | func (s *set) put(item int64, lock itemLocker) { 165 | lock.Lock(item) 166 | capacity := s.capacity 167 | i, h, mustResize := s.putStep1(item) 168 | lock.Unlock(item) 169 | 170 | if mustResize { 171 | s.resize(capacity, lock) 172 | s.Put(item) 173 | } else if i != -1 && !s.relocate(i, h, lock) { 174 | s.resize(capacity, lock) 175 | } 176 | } 177 | 178 | func (s *set) Contains(item int64) bool { 179 | lock := newItemLock(s) 180 | return s.contains(item, lock) 181 | } 182 | 183 | func (s *set) contains(item int64, lock itemLocker) bool { 184 | lock.Lock(item) 185 | defer lock.Unlock(item) 186 | 187 | p0, p1 := s.table[0][s.h0(item)], s.table[1][s.h1(item)] 188 | return p0.Contains(item) || p1.Contains(item) 189 | } 190 | 191 | func (s *set) Remove(item int64) bool { 192 | lock := newItemLock(s) 193 | lock.Lock(item) 194 | defer lock.Unlock(item) 195 | 196 | p0, p1 := s.table[0][s.h0(item)], s.table[1][s.h1(item)] 197 | for _, p := range []probe.Set{p0, p1} { 198 | if p.Contains(item) { 199 | p.Remove(item) 200 | atomic.AddInt64(&s.size, -1) 201 | return true 202 | } 203 | } 204 | 205 | return false 206 | } 207 | 208 | func (s *set) IsEmpty() bool { 209 | return s.Size() == 0 210 | } 211 | 212 | func (s *set) Size() int { 213 | u := uint64(s.size) 214 | return int(atomic.LoadUint64(&u)) 215 | } 216 | 217 | func (s *set) resize(capacity int64, lock itemLocker) { 218 | if capacity != s.capacity { 219 | return 220 | } 221 | 222 | if !lock.LockAll() { 223 | return 224 | } 225 | defer lock.UnlockAll() 226 | 227 | prevCapacity := s.capacity 228 | s.capacity *= 2 229 | 230 | ps0, ps1 := s.table[0], s.table[1] 231 | 232 | s.initSets(int(s.capacity)) 233 | 234 | noopLock := newNoopLock() 235 | for i := 0; i < int(prevCapacity); i++ { 236 | ps := [...]probe.Set{ps0[i], ps1[i]} 237 | for _, p := range ps { 238 | for p.Size() > 0 { 239 | if elem, err := p.First(); err != nil { 240 | panic(err) 241 | } else { 242 | p.Remove(elem) 243 | s.put(elem, noopLock) 244 | } 245 | } 246 | } 247 | } 248 | } 249 | 250 | func (s *set) initSets(capacity int) { 251 | s.table[0] = make([]probe.Set, capacity) 252 | s.table[1] = make([]probe.Set, capacity) 253 | for i := 0; i < int(capacity); i++ { 254 | s.table[0][i] = probe.NewSet() 255 | s.table[1][i] = probe.NewSet() 256 | } 257 | 258 | s.mutex = new([2][]sync.Mutex) 259 | s.mutex[0] = make([]sync.Mutex, capacity) 260 | s.mutex[1] = make([]sync.Mutex, capacity) 261 | 262 | s.size = 0 263 | } 264 | 265 | func (s *set) relocate(k, h int, lock itemLocker) bool { 266 | const RELOCATE_LIMIT int = 512 267 | 268 | hi, hj, i, j := h, 0, k, 1 - k 269 | 270 | for round := 0; round < RELOCATE_LIMIT; round++ { 271 | if ret, keepGoing := s.relocateOne(&hi, &hj, &i, &j, lock); !keepGoing { 272 | return ret 273 | } 274 | } 275 | 276 | return false 277 | } 278 | 279 | func (s *set) relocateOne(hi, hj, i, j *int, lock itemLocker) (retCode, keepGoing bool) { 280 | pi := s.table[*i][*hi] 281 | if pi == nil { 282 | return false, false 283 | } 284 | 285 | y, ok := pi.First() 286 | if ok != nil { 287 | return true, true 288 | } 289 | 290 | lock.Lock(y) 291 | defer lock.Unlock(y) 292 | 293 | if *i == 0 { 294 | *hj = s.h1(y) 295 | } else { 296 | *hj = s.h0(y) 297 | } 298 | 299 | pj := s.table[*j][*hj] 300 | 301 | switch { 302 | case pi.Contains(y): 303 | pi.Remove(y) 304 | switch { 305 | case pj.Size() < probe.THRESHOLD: 306 | pj.Add(y) 307 | return true, false 308 | case pj.Size() < probe.SIZE: 309 | pj.Add(y) 310 | *j = *i 311 | *i = 1 - *i 312 | hi = hj 313 | default: 314 | pi.Add(y) 315 | return false, false 316 | } 317 | case pi.Size() >= probe.THRESHOLD: 318 | return true, true 319 | } 320 | return true, false 321 | } 322 | 323 | func (s *set) h0(key int64) int { 324 | return int(h0(key) % uint(s.capacity)) 325 | } 326 | 327 | func (s *set) h1(key int64) int { 328 | return int(h1(key) % uint(s.capacity)) 329 | } 330 | 331 | func h0(key int64) uint { 332 | buf := make([]byte, 8) 333 | bytes := binary.PutVarint(buf, key) 334 | var h uint = 0 335 | 336 | for i := 0; i < bytes; i++ { 337 | h += uint(buf[i]) 338 | h += (h << 10) 339 | h ^= (h >> 6) 340 | } 341 | 342 | h += (h << 3); 343 | h ^= (h >> 11); 344 | h += (h << 15); 345 | 346 | return h 347 | } 348 | 349 | func h1(key int64) uint { 350 | buf := make([]byte, 8) 351 | bytes := binary.PutVarint(buf, key) 352 | var h, g uint = 0, 0 353 | 354 | for i := 0; i < bytes; i++ { 355 | h = (h << 4) + uint(buf[i]) 356 | g = h & 0xf0000000 357 | if g != 0 { 358 | h ^= (g >> 24) 359 | } 360 | h &= ^g 361 | } 362 | 363 | return h 364 | } 365 | -------------------------------------------------------------------------------- /task2/src/cuckooset.cpp: -------------------------------------------------------------------------------- 1 | #include "cuckooset.hpp" 2 | 3 | #include 4 | 5 | #include "hash.hpp" 6 | 7 | #define INITIAL_CAPACITY (1024) 8 | #define RELOCATE_LIMIT (512) 9 | 10 | template 11 | CuckooSet::CuckooSet() 12 | { 13 | the_capacity = INITIAL_CAPACITY; 14 | the_size = 0; 15 | the_table[0] = new ProbeSet[the_capacity]; 16 | the_table[1] = new ProbeSet[the_capacity]; 17 | 18 | the_lock = new CuckooLock(the_capacity); 19 | } 20 | 21 | template 22 | CuckooSet::~CuckooSet() 23 | { 24 | delete[] the_table[0]; 25 | delete[] the_table[1]; 26 | delete the_lock; 27 | for (auto it : old_locks) { 28 | delete it; 29 | } 30 | } 31 | 32 | template 33 | void 34 | CuckooSet::put(const TT &item) 35 | { 36 | LockGuard lock(this, item); 37 | 38 | if (contains_nolock(item)) { 39 | return; 40 | } 41 | 42 | const size_t capacity = the_capacity; 43 | 44 | const size_t hash0 = h0(item); 45 | const size_t hash1 = h1(item); 46 | 47 | ProbeSet *set0 = the_table[0] + hash0 % the_capacity; 48 | ProbeSet *set1 = the_table[1] + hash1 % the_capacity; 49 | 50 | int i = -1; 51 | size_t h; 52 | bool must_resize = false; 53 | 54 | if (set0->size() < PROBE_THRESHOLD) { 55 | set0->add(item); 56 | the_size++; 57 | return; 58 | } else if (set1->size() < PROBE_THRESHOLD) { 59 | set1->add(item); 60 | the_size++; 61 | return; 62 | } else if (set0->size() < PROBE_SIZE) { 63 | set0->add(item); 64 | the_size++; 65 | i = 0; 66 | h = hash0; 67 | } else if (set1->size() < PROBE_SIZE) { 68 | set1->add(item); 69 | the_size++; 70 | i = 1; 71 | h = hash1; 72 | } else { 73 | must_resize = true; 74 | } 75 | 76 | lock.release(); 77 | 78 | if (must_resize) { 79 | resize(capacity); 80 | put(item); 81 | } else if (i != -1 && !relocate(i, h)) { 82 | resize(capacity); 83 | } 84 | } 85 | 86 | template 87 | bool 88 | CuckooSet::contains(const TT &item) 89 | { 90 | LockGuard lock(this, item); 91 | return contains_nolock(item); 92 | } 93 | 94 | template 95 | bool 96 | CuckooSet::contains_nolock(const TT &item) 97 | { 98 | const size_t hash0 = h0(item) % the_capacity; 99 | ProbeSet *set0 = the_table[0] + hash0; 100 | 101 | const size_t hash1 = h1(item) % the_capacity; 102 | ProbeSet *set1 = the_table[1] + hash1; 103 | 104 | return (set0->contains(item) || set1->contains(item)); 105 | } 106 | 107 | template 108 | bool 109 | CuckooSet::remove(const TT &item) 110 | { 111 | LockGuard lock(this, item); 112 | 113 | const size_t hash0 = h0(item) % the_capacity; 114 | ProbeSet *set0 = the_table[0] + hash0; 115 | 116 | if (set0->contains(item)) { 117 | set0->remove(item); 118 | the_size--; 119 | return true; 120 | } 121 | 122 | const size_t hash1 = h1(item) % the_capacity; 123 | ProbeSet *set1 = the_table[1] + hash1; 124 | 125 | if (set1->contains(item)) { 126 | set1->remove(item); 127 | the_size--; 128 | return true; 129 | } 130 | 131 | return false; 132 | } 133 | 134 | template 135 | bool 136 | CuckooSet::is_empty() 137 | { 138 | return size() == 0; 139 | } 140 | 141 | template 142 | size_t 143 | CuckooSet::size() 144 | { 145 | return the_size.load(); 146 | } 147 | 148 | template 149 | void 150 | CuckooSet::acquire(const TT &item) 151 | { 152 | bool mark; 153 | std::thread::id who; 154 | const std::thread::id me = std::this_thread::get_id(); 155 | 156 | while (true) { 157 | do { 158 | who = the_owner.get(&mark); 159 | } while (mark && who != me); 160 | 161 | CuckooLock *prev_lock = the_lock; 162 | prev_lock->lock(item); 163 | 164 | who = the_owner.get(&mark); 165 | if((!mark || who == me) && the_lock == prev_lock) { 166 | return; 167 | } else { 168 | prev_lock->unlock(item); 169 | } 170 | } 171 | } 172 | 173 | template 174 | void 175 | CuckooSet::release(const TT &item) 176 | { 177 | the_lock->unlock(item); 178 | } 179 | 180 | template 181 | void 182 | CuckooSet::resize(const size_t capacity) 183 | { 184 | if (capacity != the_capacity) { 185 | return; 186 | } 187 | 188 | const size_t prev_capacity = the_capacity; 189 | const std::thread::id me = std::this_thread::get_id(); 190 | 191 | if (the_owner.attemptMark(me, true)) { 192 | if (the_capacity != prev_capacity) { 193 | the_owner.reset(); 194 | return; 195 | } 196 | 197 | the_lock->quiesce(); 198 | 199 | ProbeSet *prev0 = the_table[0]; 200 | ProbeSet *prev1 = the_table[1]; 201 | 202 | the_capacity = prev_capacity * 2; 203 | the_size = 0; 204 | 205 | the_table[0] = new ProbeSet[the_capacity]; 206 | the_table[1] = new ProbeSet[the_capacity]; 207 | 208 | old_locks.push_back(the_lock); 209 | the_lock = new CuckooLock(the_capacity); 210 | 211 | for (size_t i = 0; i < prev_capacity; i++) { 212 | ProbeSet *p = prev0 + i; 213 | while (p->size() > 0) { 214 | TT elem = p->first(); 215 | p->remove(elem); 216 | put(elem); 217 | } 218 | p = prev1 + i; 219 | while (p->size() > 0) { 220 | TT elem = p->first(); 221 | p->remove(elem); 222 | put(elem); 223 | } 224 | } 225 | 226 | delete[] prev0; 227 | delete[] prev1; 228 | 229 | the_owner.reset(); 230 | } 231 | } 232 | 233 | template 234 | bool 235 | CuckooSet::relocate(const int k, const size_t h) 236 | { 237 | assert(k == 0 || k == 1); 238 | 239 | GlobalLockGuard lock(this); 240 | 241 | size_t hi = h, hj; 242 | int i = k; 243 | int j = 1 - i; 244 | 245 | for (int round = 0; round < RELOCATE_LIMIT; round++) { 246 | ProbeSet *set_i = the_table[i] + hi % the_capacity; 247 | if (set_i->size() == 0) { 248 | return false; 249 | } 250 | 251 | const TT y = set_i->first(); 252 | hj = (i == 0) ? h1(y) : h0(y); 253 | 254 | set_i = the_table[i] + hi % the_capacity; 255 | ProbeSet *set_j = the_table[j] + hj % the_capacity; 256 | 257 | if (set_i->contains(y)) { 258 | set_i->remove(y); 259 | if (set_j->size() < PROBE_THRESHOLD) { 260 | set_j->add(y); 261 | return true; 262 | } else if (set_j->size() < PROBE_SIZE) { 263 | set_j->add(y); 264 | j = i; 265 | i = 1 - i; 266 | hi = hj; 267 | } else { 268 | set_i->add(y); 269 | return false; 270 | } 271 | } else if (set_i->size() >= PROBE_THRESHOLD) { 272 | continue; 273 | } else { 274 | return true; 275 | } 276 | } 277 | return false; 278 | } 279 | 280 | template 281 | void 282 | CuckooSet::print_name() 283 | { 284 | std::cout << "CuckooSet"; 285 | } 286 | 287 | template 288 | CuckooSet:: 289 | LockGuard::LockGuard(CuckooSet *set, 290 | const TT &item) 291 | : set(set), item(item), is_released(false) 292 | { 293 | set->acquire(item); 294 | } 295 | 296 | template 297 | CuckooSet:: 298 | LockGuard::~LockGuard() 299 | { 300 | if (!is_released) { 301 | set->release(item); 302 | } 303 | } 304 | 305 | template 306 | void 307 | CuckooSet:: 308 | LockGuard::release() 309 | { 310 | set->release(item); 311 | is_released = true; 312 | } 313 | 314 | template 315 | CuckooSet:: 316 | GlobalLockGuard::GlobalLockGuard(CuckooSet *set) 317 | : set(set), is_released(false) 318 | { 319 | set->the_lock->lockAll(); 320 | } 321 | 322 | template 323 | CuckooSet:: 324 | GlobalLockGuard::~GlobalLockGuard() 325 | { 326 | if (!is_released) { 327 | set->the_lock->unlockAll(); 328 | } 329 | } 330 | 331 | template 332 | void 333 | CuckooSet:: 334 | GlobalLockGuard::release() 335 | { 336 | set->the_lock->unlockAll(); 337 | is_released = true; 338 | } 339 | 340 | template class CuckooSet< 341 | pheet::PheetEnv< 342 | pheet::BStrategyScheduler, 343 | pheet::SystemModel, 344 | pheet::Primitives, 345 | pheet::DataStructures, 346 | pheet::ConcurrentDataStructures>, 347 | unsigned long, 348 | std::less>; 349 | -------------------------------------------------------------------------------- /task2/protocol/protocol.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,10pt]{article} 2 | 3 | \usepackage{amsmath} 4 | \usepackage{amssymb} 5 | \usepackage[usenames,dvipsnames]{color} 6 | \usepackage{comment} 7 | \usepackage[utf8]{inputenc} 8 | \usepackage{listings} 9 | \usepackage{algorithm} 10 | \usepackage{algpseudocode} 11 | \usepackage{graphicx} 12 | \usepackage{epstopdf} 13 | \usepackage[top=3cm, bottom=3cm, left=2cm, right=2cm]{geometry} 14 | \usepackage{caption} 15 | \usepackage{color} 16 | \usepackage[lofdepth,lotdepth]{subfig} 17 | \usepackage[pdfborder={0 0 0}]{hyperref} 18 | \usepackage[parfill]{parskip} 19 | \usepackage{booktabs} 20 | 21 | \definecolor{OliveGreen}{cmyk}{0.64,0,0.95,0.40} 22 | \definecolor{Gray}{gray}{0.5} 23 | 24 | \lstset{ 25 | language=Java, 26 | basicstyle=\ttfamily, 27 | keywordstyle=\color{OliveGreen}, 28 | commentstyle=\color{Gray}, 29 | captionpos=b, 30 | breaklines=true, 31 | breakatwhitespace=false, 32 | showspaces=false, 33 | showtabs=false, 34 | numbers=left, 35 | } 36 | 37 | \title{VU Advanced Multiprocessor Programming \\ 38 | SS 2013 \\ 39 | Task 2: Concurrent Cuckoo Hash Set} 40 | \author{Jakob Gruber, 0203440 \\ 41 | Martin Kalany, 0825673} 42 | 43 | \begin{document} 44 | 45 | \maketitle 46 | 47 | \section{Introduction} 48 | 49 | Our task was to implement the \emph{Concurrent Cuckoo Hash Set} as presented 50 | in \cite{herlihy}, pages 316-325. 51 | 52 | We benchmarked and compared two versions: The \emph{Striped Cuckoo Hash Set} 53 | uses a fixed 2-by-L array of reentrant locks, where \lstinline|lock[i][j]| 54 | guards the element at \lstinline|table[i][k]| with $k \mod L = j$. This variant 55 | has the obvious disadvantage that the array of locks does not grow with the 56 | number of elements $n$ stored in the set. Thus, we expect the performance to 57 | decrease significantly for large $n$ and a small number of locks. 58 | 59 | The \emph{Refined Cuckoo Hash Set} avoids this issue by letting the number of 60 | locks grow with the the size of the set. This requires some additional 61 | synchronization, the performance impact of which will be studied in Section 62 | \ref{sec:performance}. 63 | 64 | \section{Cuckoo Hash Set} 65 | 66 | The foundation of of the presented data structure is \emph{Cuckoo Hashing}, 67 | an \textit{open-addressed} sequential hash set. This means that at each 68 | location determined by a hash function, only one element can reside at any 69 | given time\footnote{Or, as in this case, a fixed number of elements.}. In 70 | contrast, a \emph{closed-addressed} hash set provides a bucket able to hold 71 | multiple items at each location. 72 | 73 | Cuckoo hashing uses two tables with different hash functions 74 | \lstinline|h0(), h1()|. If \lstinline|h0(x)| maps a given element \lstinline|x| 75 | to a location that is not occupied, \lstinline|x| is simply put there. If this 76 | location happens to be already occupied, the currently stored element 77 | \lstinline|y| is kicked out to make room for \lstinline|x|. \lstinline|y| is 78 | relocated to \lstinline|h1(y)| using the same principle. This may of course 79 | create long chains of relocations with circular dependencies. Thus, relocations 80 | are limited to a fixed number of iterations before the capacity of the set and 81 | thus the two tables is increased, prompting all elements to be re-added to the 82 | set. Figure \ref{alg:cuckooHashing} shows this algorithm. 83 | 84 | The sets as implemented during this project use a slight variation of this 85 | basic procedure. Each table address points to a data structure called probe sets 86 | which can store a fixed number of items (\lstinline|PROBE_SIZE|), but prefer 87 | to store \lstinline|PROBE_THRESHOLD| items or less. Relocation is triggered 88 | by exceeding the \lstinline|PROBE_THRESHOLD| limit. Again, the set is resized 89 | if no space is found for a particular item after a fixed number of relocation 90 | iterations. 91 | 92 | To allow concurrent access to the set, the \emph{Striped Cuckoo Hash Set} 93 | adds a 2-by-L array of locks, with each protecting one or more probe sets. 94 | This array of locks does not grow along with the set size, and thus turns into 95 | a performance bottleneck as the number of threads and probe sets grow. 96 | 97 | This limitation is avoided in the \emph{Refined Cuckoo Hash Set} by letting 98 | the size lock array always equal the size of the corresponding array of probe 99 | sets. Special care must be taken when acquiring locks while 100 | \lstinline|resize()| is executing concurrently. 101 | 102 | \begin{algorithm} 103 | \caption{Cuckoo Hashing} 104 | \label{alg:cuckooHashing} 105 | \begin{algorithmic}[5] 106 | \Function {put}{T x} 107 | \If{contains(x)} 108 | \State \Return false 109 | \EndIf 110 | \For{i = 0; i $<$ LIMIT; i++} 111 | \If {(x = swap(0, h0(x), x) == NULL} 112 | \State \Return true 113 | \ElsIf {(x = swap(1, h1(x), x) == NULL} 114 | \State \Return true 115 | \EndIf 116 | \EndFor 117 | \State resize() 118 | \State put(x) 119 | \EndFunction 120 | \end{algorithmic} 121 | \end{algorithm} 122 | 123 | \section{Implementation Details} 124 | \label{sec:implDetails} 125 | 126 | The Java code as presented in \cite{herlihy} posed several challenges for 127 | a C++ implementation since it relies heavily on garbage collection (which C++ 128 | does not have). We were able to solve most of these and circumvented the rest 129 | as follows: 130 | 131 | \begin{itemize} 132 | \item In \lstinline|relocate()|, a probe set is accessed without the 133 | protection of a lock. This causes two problems: 134 | 135 | On the one hand, this probe set might be accessed concurrently 136 | by another thread. This implies that all probe set functions must be 137 | thread-safe. Furthermore, the following code must be able to handle a 138 | situation in which all elements of the set have been removed before the 139 | thread running \lstinline|relocate| is able to call 140 | \lstinline|ProbeSet::get()|\footnote{The code in the book does not do 141 | this.} 142 | 143 | On the other hand, the probe set tables might be deleted by a concurrent 144 | call to \lstinline|resize()|. In Java, this is not an issue because an 145 | object is only garbage-collected when no more valid references to it exist. 146 | In C++ however, deletion is immediate and can result in segfaults if other 147 | threads dereference a pointer to the deleted object. 148 | 149 | Both of these problems were avoided by requiring all locks to be held during 150 | a call to \lstinline|relocate()|. This (somewhat drastic) measure had to be 151 | taken for the lack of better alternatives; smart pointers would have been 152 | an option, but introduce a bottleneck whenever a probe set is accessed. 153 | Testing also showed that this global lock did not have a large effect on runtimes. 154 | 155 | \item Locking in the \emph{Refined Cuckoo Hash Set} again relies on garbage collection, and 156 | in fact cannot be easily implemented without it. Specifically, there is no point 157 | in \lstinline|resize()| at which the locks may be deleted without possibly leaving 158 | other threads with invalid pointers. Keeping the locks in a reference-counted pointer 159 | solves this issue, but results in a single bottleneck affecting every method of the 160 | hash set. 161 | 162 | We implemented the following solution: locks are never deleted, but simply added 163 | to a delete list which is processed in the hash set destructor. This results in 164 | some memory overhead, but preserves high performance without leaking memory. 165 | \end{itemize} 166 | 167 | \section{Progress Guarantees} 168 | \label{sec:progressGuarantees} 169 | 170 | We show that each public method of the class \lstinline|CuckooSet| in its 171 | refined variant is deadlock-free\footnote{Unfortunately, \lstinline|acquire()| 172 | is not starvation-free. We think this could be improved with some further 173 | work.}. 174 | 175 | Note that it is assumed that \lstinline|std::set| is 176 | starvation-free if at no time the same element is accessed by more than one 177 | thread. We ensure this by holding a lock for the item whenever it is accessed 178 | to ensure mutual exclusion. 179 | 180 | \begin{itemize} 181 | \item For methods \lstinline|size()| and \lstinline|is_empty()| this is 182 | trivially true, since they only require an atomic load operation and no 183 | synchronisation whatsoever. They are thus starvation-free. 184 | \end{itemize} 185 | 186 | For the rest of the public methods, we need to have a closer look at methods of 187 | other classes first: 188 | 189 | \begin{itemize} 190 | \item In class \lstinline|CuckooLock|, all methods are deadlock-free. 191 | Synchronization is handled by locking and unlocking mutexes. Since locks 192 | are accessed in the same order at all points (and the used 193 | \lstinline|std::recursive_lock| implementation is reentrant), deadlock may 194 | not occur. It is assumed that the callers ensure a correct sequence of 195 | calls to methods \lstinline|lock()| and \lstinline|unlock()| and that no 196 | thread stalls between calling \lstinline|lock()| and \lstinline|unlock()|. 197 | 198 | Since the standard for C++ \cite{cppstandard} does not address the issue of 199 | fairness or starvation (relevant sections: 30.2.5 "Requirements for Lockable 200 | types" and 30.4 "Mutual exclusion"), we can not claim starvation-freedom for 201 | methods in class \lstinline|CuckooLock|. This is of little consequence for this 202 | paper, as we will show when analysing method \lstinline|acquire()|. 203 | 204 | \item All methods in class \lstinline|AtomicMarkableReference| are trivially 205 | starvation-free since they consist solely of basic arithmetic and check-and-set 206 | operations. 207 | \end{itemize} 208 | 209 | In class \lstinline|CuckooSet|: 210 | 211 | \begin{itemize} 212 | \item In \lstinline|acquire()|, the caller loops until no \textit{other} thread 213 | has marked the set for resizing. Additionally, the caller will continue 214 | looping if another thread marked the set for resizing or the array of locks 215 | was recreated while the caller attempted to acquire the lock. This implies 216 | that the method is not starvation-free. It is deadlock-free: since we need 217 | to acquire only one lock and do not hold any other shared resources while 218 | attempting to do so. Note that this is sufficient for the method to not be 219 | starvation-free. If \lstinline|std::mutex| would give any guarantees about 220 | fairness, it would not have an influence here. 221 | 222 | \item \lstinline|release()| is deadlock-free, since we only unlock a mutex. 223 | \end{itemize} 224 | 225 | Note that class \lstinline|GlobalLockGuard| is only a RAII-wrapper, which 226 | acquires all locks in it's constructor by using \lstinline|CuckooLock|. It 227 | further provides a method to release all locks and does so automatically upon 228 | destruction. Thus, it's methods are deadlock-free. \lstinline|LockGuard| is 229 | analogous, except for handling one lock for a specific item only. 230 | 231 | \begin{itemize} 232 | \item \lstinline|contains()| simply acquires the necessary lock and is 233 | deadlock- free if the constructor and destructor of class 234 | \lstinline|LockGuard| are (which we already proved). 235 | 236 | \item \lstinline|remove()| obtains the required lock and then calls 237 | \lstinline|contains()|, which again acquires the same lock. Since we use 238 | recursive mutexes, this is deadlock-free. 239 | 240 | \item Trusting that \lstinline|contains()| and \lstinline|remove()| are 241 | deadlock-free and assuming that \lstinline|put()| is as well (which will be 242 | proved immediately), it can be shown that \lstinline|relocate()| is too: 243 | The maximum number of iterations of the loop is limited by a constant and 244 | we only call starvation-free methods. Thus this method is deadlock-free. 245 | 246 | \item \lstinline|resize()| and is similar to the above, except that the loop is 247 | bounded by a variable finite value. 248 | 249 | \item \lstinline|put()| is trivially deadlock-free if \lstinline|resize()| and 250 | \lstinline|relocate()| are, since we have a simple sequence of statements. 251 | \end{itemize} 252 | 253 | \section{Linearizability} 254 | \label{sec:linearizability} 255 | 256 | Most public functions in the cuckoo set variants consist of a single critical 257 | section which is protected by calls to \lstinline|acquire()| and 258 | \lstinline|release()|. The linearization point of these functions is simply 259 | the point at which \lstinline|acquire()| returns. 260 | 261 | Both \lstinline|size()| and the derived function \lstinline|is_empty()| can be 262 | linearized when the atomic load of \lstinline|the_size| completes. 263 | 264 | \lstinline|put()| can contain three or more critical sections, each of which 265 | may change parts of the set which other threads can access. Since there can not 266 | be any single point at which the effects of the method seems to take place 267 | instantaneously, \lstinline|put()| has no linearization point. Only be 268 | restricting ourselves to calls which do not trigger either relocation or set 269 | growth can we again place the linearization point at the conclusion of 270 | \lstinline|acquire()|. 271 | 272 | \section{Performance Analysis} 273 | \label{sec:performance} 274 | 275 | Benchmarking was performed on the saturn system. Pheet was compiled using 276 | \verb|g++-4.7| and its default makeflags. The cuckoo set used the same 277 | compiler as well as makeflags \verb|-Wall -Wextra -pedantic -std=gnu++11 -O3|. 278 | 279 | Benchmarks were assembled by selecting the minimum execution time of 10 runs 280 | for each value\footnote{With the exception of the \emph{Striped 281 | Cuckoo Set} with only 8 locks, which exhibited very long execution times}. 282 | 283 | Figures \ref{fig:plot1} and \ref{fig:plot2} show the performance for the 284 | default set implementation provided by pheet using a global lock, our 285 | \emph{Striped Cuckoo Set} implementation with 2x1024 locks and our 286 | \emph{Refined Cuckoo Set}, both with an initial capacity of 2x1024 elements 287 | and a limit of 512 relocate operations. Figure \ref{fig:plot1} shows the 288 | performance when 99\% of all operations on the set are calls to 289 | \lstinline|contains()| and 0.5\% are calls to \lstinline|add()|. Figure 290 | \ref{fig:plot2} shows the same for a benchmark where 50\% of all operations on 291 | the set are calls to \lstinline|contains()| and 25\% are calls to 292 | \lstinline|add()|. 293 | 294 | Note that the x-axis is scaled with the binary logarithm in all diagrams. The 295 | y-axis in Figure \ref{fig:plot3} is scaled with the decadic logarithm. 296 | 297 | \begin{figure}[H] 298 | \begin{center} 299 | \includegraphics{099contains_005add.eps} 300 | \end{center} 301 | \caption{Performance comparison of different set implementations: 99\% contains 302 | and 0.5\% add operations} 303 | \label{fig:plot1} 304 | \end{figure} 305 | 306 | \begin{figure}[H] 307 | \begin{center} 308 | \includegraphics{05contains_025add.eps} 309 | \end{center} 310 | \caption{Performance comparison of different set implementations: 50\% contains 311 | and 25\% add operations} 312 | \label{fig:plot2} 313 | \end{figure} 314 | 315 | We expected both the striped and refined hash set variants to exhibit some 316 | overhead in contrast to the global lock set for low thread counts. With rising 317 | thread counts, the striped variant should scale very well up until a certain 318 | point at which the number of locks (which does not increase with the number of 319 | probe sets) becomes a bottleneck. The refined variant is expected to perform 320 | well for all multi-threaded usage. 321 | 322 | Results show these expectations to be justified. For single-threaded operation, 323 | the global lock set performs best by a factor of 4. For two processors, all 324 | implementations are roughly equal; all higher thread counts clearly favor 325 | our concurrent set versions. 326 | 327 | The striped variant has a small runtime advantage at smaller thread counts but 328 | is superceded by the refined version at around 8 threads. We believe that 329 | Figure \ref{fig:plot2} 330 | exhibits a larger discrepancy between these variants because the set becomes 331 | less efficient once the the number of probe sets exceeds the number of locks, 332 | and this set of benchmarks contains many more \lstinline|add()| calls - consequently the set contains more elements. 333 | 334 | Surprising for us was how much performance was affected by using 335 | reference counting (through \lstinline|std::shared_ptr|) to hold our locks. 336 | Even though the implementation of the pointer is lock-free, peak performance was 337 | reached at only 6 threads and decreased with increasing thread counts. 338 | 339 | \begin{figure}[H] 340 | \begin{center} 341 | \includegraphics{refined.eps} 342 | \end{center} 343 | \caption{Performance comparison: \emph{Refined Cuckoo Set} (final implementation) vs. \emph{Refined Cuckoo Set} (reference counting)} 344 | \label{fig:plot4} 345 | \end{figure} 346 | 347 | 348 | However, the performance of the \emph{Striped Cuckoo Hash Set} strongly 349 | depends on the fixed number of locks. Although this variant performs well 350 | with an array of locks of size 2x1024, performance decreases drastically with 351 | less locks. This is illustrated in Figure \ref{fig:plot3}. Providing a larger 352 | number of locks, on the other hand, increases memory overhead for applications 353 | that require the set to hold comparatively few elements. 354 | 355 | \begin{figure}[H] 356 | \begin{center} 357 | \includegraphics{striped.eps} 358 | \end{center} 359 | \caption{Performance comparison: \emph{Striped Cuckoo Set} with different amount of locks} 360 | \label{fig:plot3} 361 | \end{figure} 362 | 363 | \section{Running the code} 364 | \begin{itemize} 365 | \item Our implementation is based on pheet revision 420. 366 | \item In \verb|CMakeLists.txt|, make sure to set \lstinline|PHEET_PATH| correctly. 367 | \item Include our \verb|cuckooset.hpp| in \verb|test/set_bench/SetBench.cpp|. 368 | \item Add a new \lstinline|run_bench()| call to \lstinline|run_test()|. 369 | \item Set \lstinline|ACTIVE_TEST| to \verb|test_variants/amp/set.h| in \verb|test/settings.h|. 370 | \item In \verb|settings.mk|, set the: 371 | \begin{itemize} 372 | \item Include path: \verb|INCLUDE_PATH = -I. -I../path/to/cuckoo_set/src|. 373 | \item Library search path as well as link libraries: \\ 374 | \verb|TEST_LIBS = -L../path/to/cuckoo_set/build/src/ -lcuckooset|. 375 | \end{itemize} 376 | \item Run \verb|make test && LD_LIBRARY_PATH=../path/to/cuckoo_set/build/src/ bin/pheet_test|. 377 | \end{itemize} 378 | 379 | \section{Addendum: Go} 380 | 381 | The \verb|go| subfolder\footnote{This was done by Jakob Gruber only} contains an implementation of the refined cuckoo hash set 382 | written in the Go language. A couple of main points shaped this implementation 383 | and made an interesting contrast to C++: 384 | 385 | \begin{itemize} 386 | \item Go has garbage collection. Therefore, most of the problems detailed in 387 | section \ref{sec:implDetails} were not an issue in Go. 388 | \item Go does \emph{not} (yet) have generics. We have not found a way to 389 | decently implement containers without the use of generics\footnote{Of 390 | course, this doesn't mean that such a way does not exist.}. Go's built-in 391 | array, slice, and map containers all require compiler support. 392 | \item The standard library has no reentrant lock (and discourages its use). 393 | We modified all functions to work with standard locks by passing the 394 | lock object into the function itself. If a lock had already been acquired, 395 | we simply passed a NOP lock. 396 | \item It is not possible to retrieve a goroutine id (similar to a thread id in 397 | C++) in Go. Luckily, the modifications made in the previous point make 398 | goroutine ids redundant as well. 399 | \end{itemize} 400 | 401 | Further conveniences included the \lstinline|defer| statement (which executes 402 | functions at the end of the current function) and integrated unit-test and 403 | benchmark support. Unfortunately, we weren't able to use goroutines in this 404 | project. 405 | 406 | The following table shows the results of a single benchmarking run on a 407 | quad core Intel i5 760 @ 2.80 GHz using Go version 1.1.1. 408 | 409 | \begin{figure}[H] 410 | \centering 411 | \begin{tabular}{lll} 412 | \toprule 413 | Threads & \lstinline|add()| count & Runtime (ns/op) \\ 414 | \midrule 415 | 1 & 2000000 & 4958 ns/op \\ 416 | 2 & 5000000 & 3172 ns/op \\ 417 | 4 & 5000000 & 2723 ns/op \\ 418 | 8 & 5000000 & 2759 ns/op \\ 419 | 16 & 5000000 & 2723 ns/op \\ 420 | \bottomrule 421 | \end{tabular} 422 | \caption{Runtimes in nanoseconds per add() operation on 4 cores.} 423 | \label{fig:go} 424 | \end{figure} 425 | 426 | \begin{thebibliography}{9} 427 | \bibitem{herlihy} 428 | M. Herlihy, N. Shavit: 429 | \emph{The Art of Multiprocessor Programming} 430 | \bibitem{cppstandard} 431 | \emph{Working Draft, Standard for Programming Language C++}, 432 | document number N3337, obtained on July $8^{th}$, 2013. 433 | \url{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf} 434 | \footnote{The standard is not available for free and not provided in the 435 | university's library. The quoted draft is the first published after the 436 | C++11 standard, which it contains.} 437 | 438 | \end{thebibliography} 439 | 440 | \end{document} 441 | -------------------------------------------------------------------------------- /exercises_batch_2/exercises.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,10pt]{article} 2 | 3 | \usepackage{amsmath} 4 | \usepackage{amssymb} 5 | \usepackage[usenames,dvipsnames]{color} 6 | \usepackage{comment} 7 | \usepackage[utf8]{inputenc} 8 | \usepackage{listings} 9 | \usepackage[pdfborder={0 0 0}]{hyperref} 10 | 11 | \definecolor{OliveGreen}{cmyk}{0.64,0,0.95,0.40} 12 | \definecolor{Gray}{gray}{0.5} 13 | 14 | \lstset{ 15 | language=Java, 16 | basicstyle=\ttfamily, 17 | keywordstyle=\color{OliveGreen}, 18 | commentstyle=\color{Gray}, 19 | captionpos=b, 20 | breaklines=true, 21 | breakatwhitespace=false, 22 | showspaces=false, 23 | showtabs=false, 24 | numbers=left, 25 | } 26 | 27 | \newcommand{\Sp}{$s^{'}$} 28 | \newcommand{\Spp}{$s^{''}$} 29 | 30 | \title{VU Advanced Multiprocessor Programming \\ 31 | SS 2013 \\ 32 | Exercises Batch 2} 33 | \author{Jakob Gruber, 0203440} 34 | 35 | \begin{document} 36 | 37 | \maketitle 38 | 39 | \tableofcontents 40 | 41 | \pagebreak 42 | 43 | \section{Specifications} 44 | 45 | Select any 10 of $\{21, 22, 23, 24, 27, 32, 51, 52, 53, 54, 58, 62, 65, 68\}$ 46 | from \emph{Maurice Herlihy, Nir Shavit: The Art of Multiprocessor Programming. 47 | Morgan Kaufmann, 2008. Revised 1st Edition, 2012.} 48 | 49 | \section{Solutions} 50 | 51 | \subsection{Exercise 21} 52 | 53 | \emph{Explain why quiescent consistency is compositional.} 54 | 55 | \vspace{3mm} 56 | 57 | An object is quiescent if it has no pending method calls. A method call is pending if 58 | its call event has occurred, but not its response event. 59 | 60 | Let's say an object A is composed of two quiescently consistent objects B and C. 61 | By definition, method calls to B and C appear to take effect in real-time order when 62 | separated by a period of quiescence. Since B and C are only accessed during method calls of 63 | A, any period of quiescence for A is also a period of quiescence for B and C. Therefore, 64 | the property of quiescent consistency is preserved for object A as well. 65 | 66 | \subsection{Exercise 32} 67 | 68 | {\itshape 69 | This exercise examines a queue implementation (Fig. \ref{fig:nonlinearizablequeue}) whose 70 | \lstinline|enq()| method does not have a linearization point. 71 | 72 | The queue stores its items in an items array, which for simplicity we will 73 | assume is unbounded. The tail field is an \lstinline|AtomicInteger|, initially zero. The 74 | \lstinline|enq()| method reserves a slot by incrementing tail, and then stores the item at 75 | that location. Note that these two steps are not atomic: there is an interval after 76 | tail has been incremented but before the item has been stored in the array. 77 | 78 | The \lstinline|deq()| method reads the value of tail, and then traverses the array in 79 | ascending order from slot zero to the tail. For each slot, it swaps null with the 80 | current contents, returning the first non-null item it finds. If all slots are null, the 81 | procedure is restarted.} 82 | 83 | \emph{Give an example execution showing that the linearization point for enq() 84 | cannot occur at Line 13. Hint: give an execution where two \lstinline|enq()| 85 | calls are not linearized in the order they execute Line 13.} 86 | 87 | \vspace{3mm} 88 | 89 | A: 13, B: 13, B: 14, C: \lstinline|deq() == B|. 90 | 91 | \vspace{3mm} 92 | 93 | \emph{Give another example execution showing that the linearization point for \lstinline|enq()| 94 | cannot occur at Line 14.} 95 | 96 | \vspace{3mm} 97 | 98 | A: 13, B: 13, B: 14, A: 14, C: \lstinline|deq() == A|. 99 | 100 | \vspace{3mm} 101 | 102 | \emph{Since these are the only two memory accesses in \lstinline|enq()|, we must conclude that 103 | enq() has no single linearization point. Does this mean \lstinline|enq()| is not linearizable?} 104 | 105 | \vspace{3mm} 106 | 107 | No. The linearization point occurs as soon as \lstinline|getAndSet()| in line 20 108 | returns a non-\lstinline|null| value. 109 | 110 | \begin{figure} 111 | \begin{lstlisting} 112 | public class HWQueue { 113 | AtomicReference[] items; 114 | AtomicInteger tail; 115 | static final int CAPACITY = 1024; 116 | public HWQueue() { 117 | items =(AtomicReference[])Array.newInstance(AtomicReference.class, CAPACITY); 118 | for (int i = 0; i < items.length; i++) { 119 | items[i] = new AtomicReference(null); 120 | } 121 | tail = new AtomicInteger(0); 122 | } 123 | public void enq(T x) { 124 | int i = tail.getAndIncrement(); 125 | items[i].set(x); 126 | } 127 | public T deq() { 128 | while (true) { 129 | int range = tail.get(); 130 | for (int i = 0; i < range; i++) { 131 | T value = items[i].getAndSet(null); 132 | if (value != null) { 133 | return value; 134 | } 135 | } 136 | } 137 | } 138 | } 139 | \end{lstlisting} 140 | \caption{The Herlihy/Wing queue used in exercise 32.} 141 | \label{fig:nonlinearizablequeue} 142 | \end{figure} 143 | 144 | \subsection{Exercise 51} 145 | 146 | \emph{Show that if binary consensus using atomic registers is impossible for 147 | $n$ threads, then so is consensus over $k$ values, where $k > 2$.} 148 | 149 | \vspace{3mm} 150 | 151 | Suppose consensus over $k > 2$ values is possible, while binary consensus 152 | is impossible. We could now construct a binary consensus protocol simply by forming 153 | the $k$-consensus and mapping $[0, \lceil \frac{k}{2} \rceil[$ to $0$ and 154 | $[\lceil \frac{k}{2} \rceil, k]$ to $1$. This contradicts the fact that binary consensus is impossible. 155 | 156 | Therefore, $k$ consensus is not possible if binary consensus is impossible. 157 | 158 | \subsection{Exercise 52} 159 | 160 | \emph{Show that with sufficiently many $n$-thread binary consensus objects 161 | and atomic registers one can implement $n$-thread consensus over $n$ values.} 162 | 163 | \vspace{3mm} 164 | 165 | The construction is equivalent to the \lstinline|StickyBit| consensus protocol from 166 | exercise 58. \lstinline|decide()| first writes its value into an array of atomic registers: \lstinline|a_values[threadID] = value|. It then marks itself as participating in the decision: \lstinline|a_participating[threadID] = 1|. Then, for each bit of the value, it calls \lstinline|decide()| on 167 | the corresponding binary consensus object. If the decision matches the bit, we continue with the next bit. 168 | Otherwise, we search all other participating threads for a value with matching bits up to the current one 169 | and try to assist that thread in writing its value. 170 | 171 | Once this is done, we reconstruct the value from the decided bits and return it. 172 | 173 | \subsection{Exercise 53} 174 | 175 | \emph{The \lstinline|Stack| class provides two methods: \lstinline|push(x)| pushes a value onto the top of the stack, and \lstinline|pop()| removes and returns the most recently pushed value. Prove that the \lstinline|Stack| class has consensus number exactly two.} 176 | 177 | \vspace{3mm} 178 | 179 | \emph{Consensus object}: provides a method \lstinline|T decide(T value)| which is called by each thread at most once. It is \emph{consistent} (all threads decide the same value) and \emph{valid} (the common decision value is some thread's input). 180 | 181 | \emph{Consensus protocol}: a solution to the consensus problem that is wait-free (and therefore also lock-free). 182 | 183 | \emph{Consensus number}: A class C solves n-thread consensus if there exists a consensus protocol using any number of objects of class C and any number of atomic registers. The consensus number is the largest n for which class C solves n-thread consensus. 184 | 185 | This proof is similar to the FIFO Queue proof in the book, pages 108 to 110. To show that the consensus number of \lstinline|Stack| is at least two, we construct a consensus protocol as in Figure \ref{fig:stackconsensus}. 186 | 187 | \begin{figure} 188 | \begin{lstlisting} 189 | class StackConsensus { 190 | Stack s; 191 | T[] proposed; 192 | StackConsensus() { 193 | s.push(LOSE); 194 | s.push(WIN); 195 | } 196 | T decide(T value) { 197 | proposed[threadID] = value; 198 | if (s.pop() == WIN) { 199 | return proposed[threadID]; 200 | } else { 201 | return proposed[1 - threadID]; 202 | } 203 | } 204 | } 205 | \end{lstlisting} 206 | \caption{A stack consensus protocol.} 207 | \label{fig:stackconsensus} 208 | \end{figure} 209 | 210 | This protocol is wait-free since \lstinline|Stack| is wait-free and \lstinline|decide()| contains no loops. If each thread returns its own input, both must have popped \lstinline|WIN|, violating the \lstinline|Stack| protocol. Likewise, both threads returning the other's value also violates the protocol. Additionally, the protocol must return one of the proposed values because the winning value is written before \lstinline|WIN| is popped. 211 | 212 | We now need to show that \lstinline|Stack| has a consensus number of exactly two. Assume we have a consensus protocol for threads A, B, and C. According to Lemma 5.1.3, there must be a critical state s. Without loss of generality, we assume that A's next move takes the protocol to a 0-valent state, and B's next move leads to a 1-valent state. We also know that these calls must be non-commutative; this implies that they need to be calls on the same object. Next, we know that these calls cannot be made to registers since registers have a consensus number of 1. Therefore, these calls must be made to the same stack object. We can now distinguish between three cases: either both A and B call \lstinline|push()|, both call \lstinline|pop()|, or A calls \lstinline|push()| while B calls \lstinline|pop()|. 213 | 214 | Suppose both A and B call \lstinline|pop()|. Let \Sp be the state if A pops, followed by B; and \Spp if the pops occur in the opposite order. Since \Sp is 0-valent while \Spp is 1-valent, and C cannot distinguish between both states, it is impossible for C to decide the correct value in both states. 215 | 216 | Suppose both A and B call \lstinline|push()|. Let \Sp equal the state after A pushes a, B pushes b, A pops b, and B pops a. Likewise, let \Spp equal the state after B pushes b, A pushes a, A pops a, and B pops b. The pops must occur because it is the only way to observe the state of the stack. Again, states \Sp and \Spp are indistinguishable for C, contradicting the fact that \Sp is 0-valent while \Spp is 1-valent. 217 | 218 | Suppose A calls \lstinline|push()| while B calls \lstinline|pop()|. Let \Sp be the state after A pushes a, B pops a, and A pops the uppermost value of the stack (if it exists). Let \Spp be the state after B pops the uppermost value (if it exists), A pushes a, and A pops a. C cannot distinguish between both states. We do not care what happens if an empty stack is popped, since that does not affect the state visible to C. 219 | 220 | \vspace{3mm} 221 | 222 | \subsection{Exercise 54} 223 | 224 | \emph{Suppose we augment the FIFO Queue class with a \lstinline|peek()| method 225 | that returns but does not remove the first element in the queue. Show that the 226 | augmented queue has infinite consensus number.} 227 | 228 | \vspace{3mm} 229 | 230 | We show this by constructing a decision protocol using a FIFO Queue with an infinite consensus number as shown in Figure \ref{fig:fifoconsensus}. 231 | 232 | \begin{figure} 233 | \begin{lstlisting} 234 | class FIFOConsensus { 235 | FIFO f; 236 | T[] proposed; 237 | T decide(T value) { 238 | proposed[threadID] = value; 239 | f.enq(threadID); 240 | return proposed[f.peek()]; 241 | } 242 | } 243 | \end{lstlisting} 244 | \caption{A consensus protocol using FIFO queues.} 245 | \label{fig:fifoconsensus} 246 | \end{figure} 247 | 248 | This protocol is wait-free since \lstinline|FIFO| is wait-free, and \lstinline|decide()| contains no loops. If two threads return different values, 249 | \lstinline|peek()| must have returned different thread ids. Since the first element is never removed, this violates the FIFO Queue protocol. Validity is ensured because each thread writes its value into \lstinline|proposed| before pushing its thread id. 250 | 251 | \lstinline|FIFOConsensus| is wait-free, consistent, valid, and works for any number of threads, and as such it is a consensus protocol with an infinite consensus number. 252 | 253 | \vspace{3mm} 254 | 255 | \subsection{Exercise 58} 256 | 257 | \emph{Objects of the \lstinline|StickyBit| class have three possible states $\bot$, 0, 1, 258 | initially $\bot$. A call to write(v), where v is 0 or 1, has the following effects: 259 | If the object’s state is $\bot$, then it becomes v. 260 | If the object’s state is 0 or 1, then it is unchanged. 261 | A call to \lstinline|read()| returns the object’s current state. 262 | 1. Show that such an object can solve wait-free binary consensus (that is, all 263 | inputs are 0 or 1) for any number of threads. 264 | 2. Show that an array of $\log_2 m$ \lstinline|StickyBit| objects with atomic registers can 265 | solve wait-free consensus for any number of threads when there are m possible inputs. (Hint: you need to give each thread one single-writer, multi-reader 266 | atomic register.)} 267 | 268 | \vspace{3mm} 269 | 270 | 1. Figure \ref{fig:binarystickyconsensus} shows a construction of a binary consensus protocol with consensus number $\infty$. 271 | 272 | \begin{figure} 273 | \begin{lstlisting} 274 | class StickyBinaryConsensus { 275 | StickyBit s; 276 | T decide(T value) { 277 | s.write(v); 278 | return s.read(); 279 | } 280 | } 281 | \end{lstlisting} 282 | \caption{The binary consensus protocol composed of a StickyBit object.} 283 | \label{fig:binarystickyconsensus} 284 | \end{figure} 285 | 286 | Validity is given because \lstinline|write()| is called before any value is read (after writing, the state of the sticky bit is equal to the first written value). Consensus is given because a sticky bit changes its value only for the first write (and each following read returns that value). Assuming \lstinline|StickyBit| itself is wait-free, then so is our consensus protocol. 287 | 288 | 2. Figure \ref{fig:stickyconsensus} shows a consensus protocol implementation for any number of threads and any number of possible values. 289 | 290 | \begin{figure} 291 | \begin{lstlisting} 292 | class StickyConsensus { 293 | int l = number of bits in value; 294 | int t = number of threads; 295 | StickyBit[] s = new StickyBit[l]; 296 | MRSWRegister[] a_reg = new MRSWRegister[2 * t]; /* Initially 0. */ 297 | T decide(T value) { 298 | T v = value; 299 | a_reg[t + threadID] = value; 300 | a_reg[threadID] = 1; 301 | for (int i = 0; i < l; i++) { 302 | b = bit i of v; 303 | s[i].write(b); 304 | if (s[i].read() != b) { 305 | for (int j = 0; j < t; j++) { 306 | if (a_reg[j] == 1 && bits [0..i] match in a_reg[t + j] and s) { 307 | v = a_reg[t + j]; 308 | } 309 | } 310 | } 311 | return booleanArrayToInt(s); 312 | } 313 | } 314 | \end{lstlisting} 315 | \caption{The consensus protocol composed of a StickyBit object.} 316 | \label{fig:stickyconsensus} 317 | \end{figure} 318 | 319 | \lstinline|decide()| first indicates that the current thread has submitted a value 320 | by setting \lstinline|a_reg[threadID]| to 1 and \lstinline|a_reg[t + threadID]| to the 321 | proposed value. It now attempts to set all sticky bits to \lstinline|v|. If it reaches 322 | a point at which the current sticky bit element is already set to another value, 323 | it looks for a thread which has proposed a value matching the already set sticky bits, 324 | and then tries to help that thread complete the sticky bit assignment. Once all 325 | sticky bits have been assigned, their value is returned. 326 | 327 | This protocol is wait-free since \lstinline|StickyBit|, the registers and 328 | \lstinline|booleanArrayToInt()| are wait-free, and because all loops are 329 | bounded. It is consistent because it returns a value derived from the sticky 330 | bit array after having attempted a write to each array element (and by 331 | definition of the sticky bit, its value never changes after being written 332 | once). 333 | 334 | It remains to show that \lstinline|StickyConsensus| is valid. Let $value_i[k]$ 335 | be the $k$'th bit of the value proposed by thread $i$. Suppose there are two 336 | threads $i, j$ and two indices $k < l$ such that $s[k] = value_i[k]$ and $s[l] 337 | = value_j[l]$ (with $value_i[k] \neq value[j[k]$ and $value_i[l] \neq 338 | value_j[l]$). This implies that thread $j$ must have had a \lstinline|v| with 339 | bits $[0..l -1]$ not matching those of $s$. This however is impossible since 340 | during each outer loop iteration, it is checked whether the bits match; if they 341 | don't, \lstinline|v| is changed to match the value of a thread with matching 342 | bits. Therefore, all threads must return the same value, and the protocol is valid. 343 | 344 | \subsection{Exercise 62} 345 | 346 | {\itshape Consider the following $2$-thread \lstinline|QuasiConsensus| problem: 347 | 348 | Two threads, A and B, are each given a binary input. If both have input \lstinline|v|, then 349 | both must decide \lstinline|v|. If they have mixed inputs, then either they must agree, or B 350 | may decide $0$ and A may decide $1$ (but not vice versa). 351 | 352 | Here are three possible exercises (only one of which works). (1) Give a 2-thread 353 | consensus protocol using QuasiConsensus showing it has consensus number 2, 354 | or (2) give a critical-state proof that this object’s consensus number is 1, or (3) 355 | give a read–write implementation of QuasiConsensus, thereby showing it has 356 | consensus number 1.} 357 | 358 | \vspace{3mm} 359 | 360 | Suppose we are in the critical state. Since we only have the \lstinline|QuasiConsensus| object, 361 | the only possible action for threads A and B is to call \lstinline|decide()| on it. 362 | For each combination of input mappings, we will now construct a situation in which it is impossible 363 | to reach consensus. 364 | 365 | $A: 0, B: 0$: For identical inputs $0$, \lstinline|QuasiConsensus| returns $0$. In this case, 366 | thread B cannot distinguish between this state and a state in which $\textit{decide}_A(1) = 1$. 367 | 368 | $A: 1, B: 1$: For identical inputs $1$, \lstinline|QuasiConsensus| returns $1$. In this case, 369 | thread A cannot distinguish between this state and a state in which $\textit{decide}_B(0) = 0$. 370 | 371 | $A: 1, B: 0$: For mixed inputs, \lstinline|QuasiConsensus| may either agree, or decide $1$ for A and $0$ for B. 372 | If $\textit{decide}_B(0) = 0$ and $\textit{decide}_A(1) = 1$, A does not know if B called $\textit{decide}_B(1) = 1$. 373 | 374 | $A: 0, B: 1$: For mixed inputs, \lstinline|QuasiConsensus| may either agree, or decide $1$ for A and $0$ for B. 375 | If $\textit{decide}_A(0) = 1$, A cannot distinguish between states a) in which B receives $1$ as the decision (and A should also decide 1), and b) in which B receives $0$ as the decision. 376 | 377 | QuasiConsensus therefore has a consensus number of 1. 378 | 379 | \subsection{Exercise 65} 380 | 381 | {\itshape 382 | A team consensus object provides the same propose() and decide() 383 | methods as consensus. A team consensus object solves consensus as long as no 384 | more than two distinct values are ever proposed. (If more than two are proposed, 385 | the results are undefined.) 386 | 387 | Show how to solve n-thread consensus, with up to n distinct input values, from 388 | a supply of team consensus objects.} 389 | 390 | \vspace{3mm} 391 | 392 | We simply construct a complete binary tree of team consensus objects with the smallest number 393 | of leaf nodes $l = 2^k$ such that $l \geq n$. The remaining consensus protocol is shown in figure \ref{fig:teamconsensus}. This protocol is correct since every team consensus object receives 394 | at most two distinct input values, namely either the raw inputs (at the leaf level), or the 395 | decisions of its two children. 396 | 397 | \begin{figure} 398 | \begin{lstlisting} 399 | class TeamConsensus { 400 | TreeNode leafs[n]; 401 | T decide(T value) { 402 | T v = value; 403 | TreeNode node = leafs[threadID]; 404 | 405 | while (node != null) { 406 | v = node.decide(v); 407 | node = node.parent; 408 | } 409 | 410 | return v; 411 | } 412 | } 413 | \end{lstlisting} 414 | \caption{The consensus protocol composed of a tree of team consensus object.} 415 | \label{fig:teamconsensus} 416 | \end{figure} 417 | 418 | \subsection{Exercise 68} 419 | 420 | {\itshape Fig. 5.17\footnote{In the book. The implementation is not relevant to this exercise.} 421 | shows a FIFO queue implemented with read, write, 422 | \lstinline|getAndSet()| (that is, swap) and \lstinline|getAndIncrement()| methods. You may assume this queue is linearizable, and wait-free as long as \lstinline|deq()| is never applied to an 423 | empty queue. Consider the following sequence of statements. 424 | 425 | \begin{itemize} 426 | \item Both \lstinline|getAndSet()| and \lstinline|getAndIncrement()| methods have consensus number 2. 427 | \item We can add a \lstinline|peek()| simply by taking a snapshot of the queue (using the methods studied earlier in the course) and returning the item at the head of the 428 | queue. 429 | \item Using the protocol devised for Exercise 54, we can use the resulting queue to 430 | solve n-consensus for any n. 431 | \end{itemize} 432 | 433 | We have just constructed an n-thread consensus protocol using only objects with 434 | consensus number 2. Identify the faulty step in this chain of reasoning, and 435 | explain what went wrong.} 436 | 437 | \vspace{3mm} 438 | 439 | The second step is incorrect. The mechanism explained in Chapter 4.3 takes a snapshot 440 | of a number of atomic readers of disjunct registers. The mechanism required for this 441 | exercise would be an atomic snapshot of a single, multi-reader, multi-writer object, which 442 | is a different problem altogether. 443 | 444 | If in fact we did have a way to create such a copy of the FIFO queue, the reasoning would be sound. 445 | 446 | \begin{comment} 447 | 448 | Exercise 51: p139 449 | 450 | \subsection{Exercise } 451 | 452 | \emph{} 453 | 454 | \vspace{3mm} 455 | 456 | \vspace{3mm} 457 | 458 | \begin{align} 459 | S(p) &= \frac{s}{s'} = \frac{2s(p - 1)}{s(p - 1) - 1} \\ 460 | &= \frac{2 \cdot \frac{3}{10} \cdot (p - 1)}{\frac{3}{10} \cdot (p - 1) - 1} 461 | \end{align} 462 | 463 | \begin{figure} 464 | \begin{lstlisting} 465 | 466 | \end{lstlisting} 467 | \caption{The Flaky lock used in Exercise 11.} 468 | \label{fig:flaky} 469 | \end{figure} 470 | 471 | \end{comment} 472 | 473 | \end{document} 474 | -------------------------------------------------------------------------------- /task2/data/stdset.dat: -------------------------------------------------------------------------------- 1 | make: Nothing to be done for `test'. 2 | ---- 3 | test set scheduler range blocks contains_p add_p seed cpus total_time 4 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.29531 5 | test set scheduler range blocks contains_p add_p seed cpus total_time 6 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.92953 7 | test set scheduler range blocks contains_p add_p seed cpus total_time 8 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 21.0706 9 | test set scheduler range blocks contains_p add_p seed cpus total_time 10 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 35.8877 11 | test set scheduler range blocks contains_p add_p seed cpus total_time 12 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.7747 13 | test set scheduler range blocks contains_p add_p seed cpus total_time 14 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.6212 15 | test set scheduler range blocks contains_p add_p seed cpus total_time 16 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 22.1295 17 | test set scheduler range blocks contains_p add_p seed cpus total_time 18 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.06153 19 | test set scheduler range blocks contains_p add_p seed cpus total_time 20 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 26.0129 21 | test set scheduler range blocks contains_p add_p seed cpus total_time 22 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 41.5497 23 | test set scheduler range blocks contains_p add_p seed cpus total_time 24 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 49.2224 25 | test set scheduler range blocks contains_p add_p seed cpus total_time 26 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 30.3547 27 | test set scheduler range blocks contains_p add_p seed cpus total_time 28 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 35.5221 29 | test set scheduler range blocks contains_p add_p seed cpus total_time 30 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 58.1101 31 | ---- 32 | test set scheduler range blocks contains_p add_p seed cpus total_time 33 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.2862 34 | test set scheduler range blocks contains_p add_p seed cpus total_time 35 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.7833 36 | test set scheduler range blocks contains_p add_p seed cpus total_time 37 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 15.318 38 | test set scheduler range blocks contains_p add_p seed cpus total_time 39 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 35.8606 40 | test set scheduler range blocks contains_p add_p seed cpus total_time 41 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.5216 42 | test set scheduler range blocks contains_p add_p seed cpus total_time 43 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.2966 44 | test set scheduler range blocks contains_p add_p seed cpus total_time 45 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 21.565 46 | test set scheduler range blocks contains_p add_p seed cpus total_time 47 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.07653 48 | test set scheduler range blocks contains_p add_p seed cpus total_time 49 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 25.0491 50 | test set scheduler range blocks contains_p add_p seed cpus total_time 51 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 40.0598 52 | test set scheduler range blocks contains_p add_p seed cpus total_time 53 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 47.3169 54 | test set scheduler range blocks contains_p add_p seed cpus total_time 55 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 30.0457 56 | test set scheduler range blocks contains_p add_p seed cpus total_time 57 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 34.5172 58 | test set scheduler range blocks contains_p add_p seed cpus total_time 59 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 56.2972 60 | ---- 61 | test set scheduler range blocks contains_p add_p seed cpus total_time 62 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.28792 63 | test set scheduler range blocks contains_p add_p seed cpus total_time 64 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.93681 65 | test set scheduler range blocks contains_p add_p seed cpus total_time 66 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 22.9753 67 | test set scheduler range blocks contains_p add_p seed cpus total_time 68 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 36.2741 69 | test set scheduler range blocks contains_p add_p seed cpus total_time 70 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.5012 71 | test set scheduler range blocks contains_p add_p seed cpus total_time 72 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.0916 73 | test set scheduler range blocks contains_p add_p seed cpus total_time 74 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 21.646 75 | test set scheduler range blocks contains_p add_p seed cpus total_time 76 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.05946 77 | test set scheduler range blocks contains_p add_p seed cpus total_time 78 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 25.3342 79 | test set scheduler range blocks contains_p add_p seed cpus total_time 80 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 40.1357 81 | test set scheduler range blocks contains_p add_p seed cpus total_time 82 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 47.17 83 | test set scheduler range blocks contains_p add_p seed cpus total_time 84 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 30.7628 85 | test set scheduler range blocks contains_p add_p seed cpus total_time 86 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 34.9025 87 | test set scheduler range blocks contains_p add_p seed cpus total_time 88 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 57.7835 89 | ---- 90 | test set scheduler range blocks contains_p add_p seed cpus total_time 91 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.27363 92 | test set scheduler range blocks contains_p add_p seed cpus total_time 93 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.77099 94 | test set scheduler range blocks contains_p add_p seed cpus total_time 95 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 14.0966 96 | test set scheduler range blocks contains_p add_p seed cpus total_time 97 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 37.2751 98 | test set scheduler range blocks contains_p add_p seed cpus total_time 99 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.5439 100 | test set scheduler range blocks contains_p add_p seed cpus total_time 101 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.2881 102 | test set scheduler range blocks contains_p add_p seed cpus total_time 103 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 21.7589 104 | test set scheduler range blocks contains_p add_p seed cpus total_time 105 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.05451 106 | test set scheduler range blocks contains_p add_p seed cpus total_time 107 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 25.6326 108 | test set scheduler range blocks contains_p add_p seed cpus total_time 109 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 40.6542 110 | test set scheduler range blocks contains_p add_p seed cpus total_time 111 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 49.068 112 | test set scheduler range blocks contains_p add_p seed cpus total_time 113 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 30.5555 114 | test set scheduler range blocks contains_p add_p seed cpus total_time 115 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 35.1024 116 | test set scheduler range blocks contains_p add_p seed cpus total_time 117 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 58.0486 118 | ---- 119 | test set scheduler range blocks contains_p add_p seed cpus total_time 120 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.26201 121 | test set scheduler range blocks contains_p add_p seed cpus total_time 122 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 18.419 123 | test set scheduler range blocks contains_p add_p seed cpus total_time 124 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 27.5517 125 | test set scheduler range blocks contains_p add_p seed cpus total_time 126 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 36.8993 127 | test set scheduler range blocks contains_p add_p seed cpus total_time 128 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 13.5788 129 | test set scheduler range blocks contains_p add_p seed cpus total_time 130 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 14.7671 131 | test set scheduler range blocks contains_p add_p seed cpus total_time 132 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 22.0177 133 | test set scheduler range blocks contains_p add_p seed cpus total_time 134 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.0541 135 | test set scheduler range blocks contains_p add_p seed cpus total_time 136 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 25.8734 137 | test set scheduler range blocks contains_p add_p seed cpus total_time 138 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 43.2351 139 | test set scheduler range blocks contains_p add_p seed cpus total_time 140 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 49.7965 141 | test set scheduler range blocks contains_p add_p seed cpus total_time 142 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 30.6825 143 | test set scheduler range blocks contains_p add_p seed cpus total_time 144 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 34.2804 145 | test set scheduler range blocks contains_p add_p seed cpus total_time 146 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 56.5781 147 | ---- 148 | test set scheduler range blocks contains_p add_p seed cpus total_time 149 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.27767 150 | test set scheduler range blocks contains_p add_p seed cpus total_time 151 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.9741 152 | test set scheduler range blocks contains_p add_p seed cpus total_time 153 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 22.2904 154 | test set scheduler range blocks contains_p add_p seed cpus total_time 155 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 31.6935 156 | test set scheduler range blocks contains_p add_p seed cpus total_time 157 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.3167 158 | test set scheduler range blocks contains_p add_p seed cpus total_time 159 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.1141 160 | test set scheduler range blocks contains_p add_p seed cpus total_time 161 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 21.5375 162 | test set scheduler range blocks contains_p add_p seed cpus total_time 163 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.05299 164 | test set scheduler range blocks contains_p add_p seed cpus total_time 165 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 26.3035 166 | test set scheduler range blocks contains_p add_p seed cpus total_time 167 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 41.9502 168 | test set scheduler range blocks contains_p add_p seed cpus total_time 169 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 48.8157 170 | test set scheduler range blocks contains_p add_p seed cpus total_time 171 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 30.6421 172 | test set scheduler range blocks contains_p add_p seed cpus total_time 173 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 34.6753 174 | test set scheduler range blocks contains_p add_p seed cpus total_time 175 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 58.1844 176 | ---- 177 | test set scheduler range blocks contains_p add_p seed cpus total_time 178 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.28208 179 | test set scheduler range blocks contains_p add_p seed cpus total_time 180 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.88593 181 | test set scheduler range blocks contains_p add_p seed cpus total_time 182 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 22.5903 183 | test set scheduler range blocks contains_p add_p seed cpus total_time 184 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 33.5197 185 | test set scheduler range blocks contains_p add_p seed cpus total_time 186 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.3628 187 | test set scheduler range blocks contains_p add_p seed cpus total_time 188 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.1953 189 | test set scheduler range blocks contains_p add_p seed cpus total_time 190 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 21.4093 191 | test set scheduler range blocks contains_p add_p seed cpus total_time 192 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.09811 193 | test set scheduler range blocks contains_p add_p seed cpus total_time 194 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 26.2683 195 | test set scheduler range blocks contains_p add_p seed cpus total_time 196 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 40.6082 197 | test set scheduler range blocks contains_p add_p seed cpus total_time 198 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 48.2187 199 | test set scheduler range blocks contains_p add_p seed cpus total_time 200 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 29.4661 201 | test set scheduler range blocks contains_p add_p seed cpus total_time 202 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 35.2245 203 | test set scheduler range blocks contains_p add_p seed cpus total_time 204 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 58.379 205 | ---- 206 | test set scheduler range blocks contains_p add_p seed cpus total_time 207 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.23777 208 | test set scheduler range blocks contains_p add_p seed cpus total_time 209 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.87543 210 | test set scheduler range blocks contains_p add_p seed cpus total_time 211 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 12.3647 212 | test set scheduler range blocks contains_p add_p seed cpus total_time 213 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 31.408 214 | test set scheduler range blocks contains_p add_p seed cpus total_time 215 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.3422 216 | test set scheduler range blocks contains_p add_p seed cpus total_time 217 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.2092 218 | test set scheduler range blocks contains_p add_p seed cpus total_time 219 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 22.0265 220 | test set scheduler range blocks contains_p add_p seed cpus total_time 221 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.05603 222 | test set scheduler range blocks contains_p add_p seed cpus total_time 223 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 25.9055 224 | test set scheduler range blocks contains_p add_p seed cpus total_time 225 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 40.856 226 | test set scheduler range blocks contains_p add_p seed cpus total_time 227 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 47.2399 228 | test set scheduler range blocks contains_p add_p seed cpus total_time 229 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 29.799 230 | test set scheduler range blocks contains_p add_p seed cpus total_time 231 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 35.7865 232 | test set scheduler range blocks contains_p add_p seed cpus total_time 233 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 56.5441 234 | ---- 235 | test set scheduler range blocks contains_p add_p seed cpus total_time 236 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.27777 237 | test set scheduler range blocks contains_p add_p seed cpus total_time 238 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.57269 239 | test set scheduler range blocks contains_p add_p seed cpus total_time 240 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 25.3549 241 | test set scheduler range blocks contains_p add_p seed cpus total_time 242 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 36.1327 243 | test set scheduler range blocks contains_p add_p seed cpus total_time 244 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.5676 245 | test set scheduler range blocks contains_p add_p seed cpus total_time 246 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.2515 247 | test set scheduler range blocks contains_p add_p seed cpus total_time 248 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 21.8995 249 | test set scheduler range blocks contains_p add_p seed cpus total_time 250 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.05744 251 | test set scheduler range blocks contains_p add_p seed cpus total_time 252 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 25.7366 253 | test set scheduler range blocks contains_p add_p seed cpus total_time 254 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 41.2724 255 | test set scheduler range blocks contains_p add_p seed cpus total_time 256 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 48.2262 257 | test set scheduler range blocks contains_p add_p seed cpus total_time 258 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 31.2237 259 | test set scheduler range blocks contains_p add_p seed cpus total_time 260 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 34.7173 261 | test set scheduler range blocks contains_p add_p seed cpus total_time 262 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 58.3332 263 | ---- 264 | test set scheduler range blocks contains_p add_p seed cpus total_time 265 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 4.27707 266 | test set scheduler range blocks contains_p add_p seed cpus total_time 267 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 8.7998 268 | test set scheduler range blocks contains_p add_p seed cpus total_time 269 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 21.875 270 | test set scheduler range blocks contains_p add_p seed cpus total_time 271 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 32.4658 272 | test set scheduler range blocks contains_p add_p seed cpus total_time 273 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 14.367 274 | test set scheduler range blocks contains_p add_p seed cpus total_time 275 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 15.1647 276 | test set scheduler range blocks contains_p add_p seed cpus total_time 277 | set_bench StdSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 21.7318 278 | test set scheduler range blocks contains_p add_p seed cpus total_time 279 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 5.10202 280 | test set scheduler range blocks contains_p add_p seed cpus total_time 281 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 26.2689 282 | test set scheduler range blocks contains_p add_p seed cpus total_time 283 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 40.8932 284 | test set scheduler range blocks contains_p add_p seed cpus total_time 285 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 48.324 286 | test set scheduler range blocks contains_p add_p seed cpus total_time 287 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 30.6345 288 | test set scheduler range blocks contains_p add_p seed cpus total_time 289 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 35.4693 290 | test set scheduler range blocks contains_p add_p seed cpus total_time 291 | set_bench StdSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 58.1913 292 | -------------------------------------------------------------------------------- /task2/data/refined.dat: -------------------------------------------------------------------------------- 1 | make: Nothing to be done for `test'. 2 | ---- 3 | test set scheduler range blocks contains_p add_p seed cpus total_time 4 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.9727 5 | test set scheduler range blocks contains_p add_p seed cpus total_time 6 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.3588 7 | test set scheduler range blocks contains_p add_p seed cpus total_time 8 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.88355 9 | test set scheduler range blocks contains_p add_p seed cpus total_time 10 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.29536 11 | test set scheduler range blocks contains_p add_p seed cpus total_time 12 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.50393 13 | test set scheduler range blocks contains_p add_p seed cpus total_time 14 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.61326 15 | test set scheduler range blocks contains_p add_p seed cpus total_time 16 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.60353 17 | test set scheduler range blocks contains_p add_p seed cpus total_time 18 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.4893 19 | test set scheduler range blocks contains_p add_p seed cpus total_time 20 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.8103 21 | test set scheduler range blocks contains_p add_p seed cpus total_time 22 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.32461 23 | test set scheduler range blocks contains_p add_p seed cpus total_time 24 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.72677 25 | test set scheduler range blocks contains_p add_p seed cpus total_time 26 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.94792 27 | test set scheduler range blocks contains_p add_p seed cpus total_time 28 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 5.23191 29 | test set scheduler range blocks contains_p add_p seed cpus total_time 30 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.76476 31 | ---- 32 | test set scheduler range blocks contains_p add_p seed cpus total_time 33 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.804 34 | test set scheduler range blocks contains_p add_p seed cpus total_time 35 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.1814 36 | test set scheduler range blocks contains_p add_p seed cpus total_time 37 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.70593 38 | test set scheduler range blocks contains_p add_p seed cpus total_time 39 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.1336 40 | test set scheduler range blocks contains_p add_p seed cpus total_time 41 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.39799 42 | test set scheduler range blocks contains_p add_p seed cpus total_time 43 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.94052 44 | test set scheduler range blocks contains_p add_p seed cpus total_time 45 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.18445 46 | test set scheduler range blocks contains_p add_p seed cpus total_time 47 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.3116 48 | test set scheduler range blocks contains_p add_p seed cpus total_time 49 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.679 50 | test set scheduler range blocks contains_p add_p seed cpus total_time 51 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.22036 52 | test set scheduler range blocks contains_p add_p seed cpus total_time 53 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.66776 54 | test set scheduler range blocks contains_p add_p seed cpus total_time 55 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.82284 56 | test set scheduler range blocks contains_p add_p seed cpus total_time 57 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 4.56659 58 | test set scheduler range blocks contains_p add_p seed cpus total_time 59 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.87958 60 | ---- 61 | test set scheduler range blocks contains_p add_p seed cpus total_time 62 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.6444 63 | test set scheduler range blocks contains_p add_p seed cpus total_time 64 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.1008 65 | test set scheduler range blocks contains_p add_p seed cpus total_time 66 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.66883 67 | test set scheduler range blocks contains_p add_p seed cpus total_time 68 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.12635 69 | test set scheduler range blocks contains_p add_p seed cpus total_time 70 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.37696 71 | test set scheduler range blocks contains_p add_p seed cpus total_time 72 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.13151 73 | test set scheduler range blocks contains_p add_p seed cpus total_time 74 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.0011 75 | test set scheduler range blocks contains_p add_p seed cpus total_time 76 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.1739 77 | test set scheduler range blocks contains_p add_p seed cpus total_time 78 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.6162 79 | test set scheduler range blocks contains_p add_p seed cpus total_time 80 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.11255 81 | test set scheduler range blocks contains_p add_p seed cpus total_time 82 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.33508 83 | test set scheduler range blocks contains_p add_p seed cpus total_time 84 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 3.55186 85 | test set scheduler range blocks contains_p add_p seed cpus total_time 86 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 3.54797 87 | test set scheduler range blocks contains_p add_p seed cpus total_time 88 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 4.50992 89 | ---- 90 | test set scheduler range blocks contains_p add_p seed cpus total_time 91 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.5573 92 | test set scheduler range blocks contains_p add_p seed cpus total_time 93 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.1301 94 | test set scheduler range blocks contains_p add_p seed cpus total_time 95 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.77475 96 | test set scheduler range blocks contains_p add_p seed cpus total_time 97 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.13093 98 | test set scheduler range blocks contains_p add_p seed cpus total_time 99 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.38766 100 | test set scheduler range blocks contains_p add_p seed cpus total_time 101 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.22664 102 | test set scheduler range blocks contains_p add_p seed cpus total_time 103 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.32575 104 | test set scheduler range blocks contains_p add_p seed cpus total_time 105 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.3381 106 | test set scheduler range blocks contains_p add_p seed cpus total_time 107 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.7061 108 | test set scheduler range blocks contains_p add_p seed cpus total_time 109 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.25356 110 | test set scheduler range blocks contains_p add_p seed cpus total_time 111 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.73796 112 | test set scheduler range blocks contains_p add_p seed cpus total_time 113 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.76332 114 | test set scheduler range blocks contains_p add_p seed cpus total_time 115 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 4.60134 116 | test set scheduler range blocks contains_p add_p seed cpus total_time 117 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.36479 118 | ---- 119 | test set scheduler range blocks contains_p add_p seed cpus total_time 120 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.7331 121 | test set scheduler range blocks contains_p add_p seed cpus total_time 122 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.1484 123 | test set scheduler range blocks contains_p add_p seed cpus total_time 124 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.70954 125 | test set scheduler range blocks contains_p add_p seed cpus total_time 126 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.14953 127 | test set scheduler range blocks contains_p add_p seed cpus total_time 128 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.41965 129 | test set scheduler range blocks contains_p add_p seed cpus total_time 130 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 1.97622 131 | test set scheduler range blocks contains_p add_p seed cpus total_time 132 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.22859 133 | test set scheduler range blocks contains_p add_p seed cpus total_time 134 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.362 135 | test set scheduler range blocks contains_p add_p seed cpus total_time 136 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.7891 137 | test set scheduler range blocks contains_p add_p seed cpus total_time 138 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.21807 139 | test set scheduler range blocks contains_p add_p seed cpus total_time 140 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.59775 141 | test set scheduler range blocks contains_p add_p seed cpus total_time 142 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.86205 143 | test set scheduler range blocks contains_p add_p seed cpus total_time 144 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 4.40952 145 | test set scheduler range blocks contains_p add_p seed cpus total_time 146 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.08767 147 | ---- 148 | test set scheduler range blocks contains_p add_p seed cpus total_time 149 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.5871 150 | test set scheduler range blocks contains_p add_p seed cpus total_time 151 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.1183 152 | test set scheduler range blocks contains_p add_p seed cpus total_time 153 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.68976 154 | test set scheduler range blocks contains_p add_p seed cpus total_time 155 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.17326 156 | test set scheduler range blocks contains_p add_p seed cpus total_time 157 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.39091 158 | test set scheduler range blocks contains_p add_p seed cpus total_time 159 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.62071 160 | test set scheduler range blocks contains_p add_p seed cpus total_time 161 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.12704 162 | test set scheduler range blocks contains_p add_p seed cpus total_time 163 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.2114 164 | test set scheduler range blocks contains_p add_p seed cpus total_time 165 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.7316 166 | test set scheduler range blocks contains_p add_p seed cpus total_time 167 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.16857 168 | test set scheduler range blocks contains_p add_p seed cpus total_time 169 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.63326 170 | test set scheduler range blocks contains_p add_p seed cpus total_time 171 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.73087 172 | test set scheduler range blocks contains_p add_p seed cpus total_time 173 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 4.45623 174 | test set scheduler range blocks contains_p add_p seed cpus total_time 175 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.53962 176 | ---- 177 | test set scheduler range blocks contains_p add_p seed cpus total_time 178 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.7377 179 | test set scheduler range blocks contains_p add_p seed cpus total_time 180 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.1226 181 | test set scheduler range blocks contains_p add_p seed cpus total_time 182 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.76539 183 | test set scheduler range blocks contains_p add_p seed cpus total_time 184 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.10535 185 | test set scheduler range blocks contains_p add_p seed cpus total_time 186 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.44967 187 | test set scheduler range blocks contains_p add_p seed cpus total_time 188 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 1.94313 189 | test set scheduler range blocks contains_p add_p seed cpus total_time 190 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.37166 191 | test set scheduler range blocks contains_p add_p seed cpus total_time 192 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.1681 193 | test set scheduler range blocks contains_p add_p seed cpus total_time 194 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.681 195 | test set scheduler range blocks contains_p add_p seed cpus total_time 196 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.21414 197 | test set scheduler range blocks contains_p add_p seed cpus total_time 198 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.65052 199 | test set scheduler range blocks contains_p add_p seed cpus total_time 200 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.97193 201 | test set scheduler range blocks contains_p add_p seed cpus total_time 202 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 4.53271 203 | test set scheduler range blocks contains_p add_p seed cpus total_time 204 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.86608 205 | ---- 206 | test set scheduler range blocks contains_p add_p seed cpus total_time 207 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.7574 208 | test set scheduler range blocks contains_p add_p seed cpus total_time 209 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.1839 210 | test set scheduler range blocks contains_p add_p seed cpus total_time 211 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.76712 212 | test set scheduler range blocks contains_p add_p seed cpus total_time 213 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.15253 214 | test set scheduler range blocks contains_p add_p seed cpus total_time 215 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.43203 216 | test set scheduler range blocks contains_p add_p seed cpus total_time 217 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.03873 218 | test set scheduler range blocks contains_p add_p seed cpus total_time 219 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.69196 220 | test set scheduler range blocks contains_p add_p seed cpus total_time 221 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.28 222 | test set scheduler range blocks contains_p add_p seed cpus total_time 223 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.7982 224 | test set scheduler range blocks contains_p add_p seed cpus total_time 225 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.22271 226 | test set scheduler range blocks contains_p add_p seed cpus total_time 227 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.61985 228 | test set scheduler range blocks contains_p add_p seed cpus total_time 229 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.80851 230 | test set scheduler range blocks contains_p add_p seed cpus total_time 231 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 4.34198 232 | test set scheduler range blocks contains_p add_p seed cpus total_time 233 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.26972 234 | ---- 235 | test set scheduler range blocks contains_p add_p seed cpus total_time 236 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.721 237 | test set scheduler range blocks contains_p add_p seed cpus total_time 238 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 11.1293 239 | test set scheduler range blocks contains_p add_p seed cpus total_time 240 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 7.75631 241 | test set scheduler range blocks contains_p add_p seed cpus total_time 242 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 4.20069 243 | test set scheduler range blocks contains_p add_p seed cpus total_time 244 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.47629 245 | test set scheduler range blocks contains_p add_p seed cpus total_time 246 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.69547 247 | test set scheduler range blocks contains_p add_p seed cpus total_time 248 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.27216 249 | test set scheduler range blocks contains_p add_p seed cpus total_time 250 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.3196 251 | test set scheduler range blocks contains_p add_p seed cpus total_time 252 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 22.6198 253 | test set scheduler range blocks contains_p add_p seed cpus total_time 254 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 15.6233 255 | test set scheduler range blocks contains_p add_p seed cpus total_time 256 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 9.77857 257 | test set scheduler range blocks contains_p add_p seed cpus total_time 258 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 6.21449 259 | test set scheduler range blocks contains_p add_p seed cpus total_time 260 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 4.86811 261 | test set scheduler range blocks contains_p add_p seed cpus total_time 262 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.49606 263 | ---- 264 | test set scheduler range blocks contains_p add_p seed cpus total_time 265 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 18.9165 266 | test set scheduler range blocks contains_p add_p seed cpus total_time 267 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 18.2631 268 | test set scheduler range blocks contains_p add_p seed cpus total_time 269 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 12.9229 270 | test set scheduler range blocks contains_p add_p seed cpus total_time 271 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 7.13464 272 | test set scheduler range blocks contains_p add_p seed cpus total_time 273 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 4.55543 274 | test set scheduler range blocks contains_p add_p seed cpus total_time 275 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 1.77581 276 | test set scheduler range blocks contains_p add_p seed cpus total_time 277 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.56863 278 | test set scheduler range blocks contains_p add_p seed cpus total_time 279 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 19.5832 280 | test set scheduler range blocks contains_p add_p seed cpus total_time 281 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 12.5457 282 | test set scheduler range blocks contains_p add_p seed cpus total_time 283 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.10073 284 | test set scheduler range blocks contains_p add_p seed cpus total_time 285 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.65806 286 | test set scheduler range blocks contains_p add_p seed cpus total_time 287 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.88671 288 | test set scheduler range blocks contains_p add_p seed cpus total_time 289 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 4.74529 290 | test set scheduler range blocks contains_p add_p seed cpus total_time 291 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.87124 292 | -------------------------------------------------------------------------------- /task2/data/striped.dat: -------------------------------------------------------------------------------- 1 | make: Nothing to be done for `test'. 2 | ---- 3 | test set scheduler range blocks contains_p add_p seed cpus total_time 4 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 17.0298 5 | test set scheduler range blocks contains_p add_p seed cpus total_time 6 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.68746 7 | test set scheduler range blocks contains_p add_p seed cpus total_time 8 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.74102 9 | test set scheduler range blocks contains_p add_p seed cpus total_time 10 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.67167 11 | test set scheduler range blocks contains_p add_p seed cpus total_time 12 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.21147 13 | test set scheduler range blocks contains_p add_p seed cpus total_time 14 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.56574 15 | test set scheduler range blocks contains_p add_p seed cpus total_time 16 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.42057 17 | test set scheduler range blocks contains_p add_p seed cpus total_time 18 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.4752 19 | test set scheduler range blocks contains_p add_p seed cpus total_time 20 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.1265 21 | test set scheduler range blocks contains_p add_p seed cpus total_time 22 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.27023 23 | test set scheduler range blocks contains_p add_p seed cpus total_time 24 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.30815 25 | test set scheduler range blocks contains_p add_p seed cpus total_time 26 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.71284 27 | test set scheduler range blocks contains_p add_p seed cpus total_time 28 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.72642 29 | test set scheduler range blocks contains_p add_p seed cpus total_time 30 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.07289 31 | ---- 32 | test set scheduler range blocks contains_p add_p seed cpus total_time 33 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 16.9103 34 | test set scheduler range blocks contains_p add_p seed cpus total_time 35 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.67739 36 | test set scheduler range blocks contains_p add_p seed cpus total_time 37 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.74652 38 | test set scheduler range blocks contains_p add_p seed cpus total_time 39 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.7258 40 | test set scheduler range blocks contains_p add_p seed cpus total_time 41 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.29991 42 | test set scheduler range blocks contains_p add_p seed cpus total_time 43 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.8752 44 | test set scheduler range blocks contains_p add_p seed cpus total_time 45 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.64633 46 | test set scheduler range blocks contains_p add_p seed cpus total_time 47 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.4058 48 | test set scheduler range blocks contains_p add_p seed cpus total_time 49 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.2591 50 | test set scheduler range blocks contains_p add_p seed cpus total_time 51 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.25543 52 | test set scheduler range blocks contains_p add_p seed cpus total_time 53 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.28839 54 | test set scheduler range blocks contains_p add_p seed cpus total_time 55 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.70922 56 | test set scheduler range blocks contains_p add_p seed cpus total_time 57 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.94705 58 | test set scheduler range blocks contains_p add_p seed cpus total_time 59 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.39207 60 | ---- 61 | test set scheduler range blocks contains_p add_p seed cpus total_time 62 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 16.9334 63 | test set scheduler range blocks contains_p add_p seed cpus total_time 64 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.67985 65 | test set scheduler range blocks contains_p add_p seed cpus total_time 66 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.73584 67 | test set scheduler range blocks contains_p add_p seed cpus total_time 68 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.73859 69 | test set scheduler range blocks contains_p add_p seed cpus total_time 70 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.26326 71 | test set scheduler range blocks contains_p add_p seed cpus total_time 72 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.23354 73 | test set scheduler range blocks contains_p add_p seed cpus total_time 74 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.4821 75 | test set scheduler range blocks contains_p add_p seed cpus total_time 76 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.4511 77 | test set scheduler range blocks contains_p add_p seed cpus total_time 78 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.2663 79 | test set scheduler range blocks contains_p add_p seed cpus total_time 80 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.26388 81 | test set scheduler range blocks contains_p add_p seed cpus total_time 82 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.35213 83 | test set scheduler range blocks contains_p add_p seed cpus total_time 84 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.66736 85 | test set scheduler range blocks contains_p add_p seed cpus total_time 86 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.7824 87 | test set scheduler range blocks contains_p add_p seed cpus total_time 88 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.36436 89 | ---- 90 | test set scheduler range blocks contains_p add_p seed cpus total_time 91 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 16.8876 92 | test set scheduler range blocks contains_p add_p seed cpus total_time 93 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.67515 94 | test set scheduler range blocks contains_p add_p seed cpus total_time 95 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.71544 96 | test set scheduler range blocks contains_p add_p seed cpus total_time 97 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.70798 98 | test set scheduler range blocks contains_p add_p seed cpus total_time 99 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.25639 100 | test set scheduler range blocks contains_p add_p seed cpus total_time 101 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.48873 102 | test set scheduler range blocks contains_p add_p seed cpus total_time 103 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.44992 104 | test set scheduler range blocks contains_p add_p seed cpus total_time 105 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.383 106 | test set scheduler range blocks contains_p add_p seed cpus total_time 107 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.1381 108 | test set scheduler range blocks contains_p add_p seed cpus total_time 109 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.24133 110 | test set scheduler range blocks contains_p add_p seed cpus total_time 111 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.35133 112 | test set scheduler range blocks contains_p add_p seed cpus total_time 113 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.76879 114 | test set scheduler range blocks contains_p add_p seed cpus total_time 115 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.91174 116 | test set scheduler range blocks contains_p add_p seed cpus total_time 117 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.10467 118 | ---- 119 | test set scheduler range blocks contains_p add_p seed cpus total_time 120 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 17.0913 121 | test set scheduler range blocks contains_p add_p seed cpus total_time 122 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.72622 123 | test set scheduler range blocks contains_p add_p seed cpus total_time 124 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.7816 125 | test set scheduler range blocks contains_p add_p seed cpus total_time 126 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.69603 127 | test set scheduler range blocks contains_p add_p seed cpus total_time 128 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.29442 129 | test set scheduler range blocks contains_p add_p seed cpus total_time 130 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.29415 131 | test set scheduler range blocks contains_p add_p seed cpus total_time 132 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.43034 133 | test set scheduler range blocks contains_p add_p seed cpus total_time 134 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.5559 135 | test set scheduler range blocks contains_p add_p seed cpus total_time 136 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.2991 137 | test set scheduler range blocks contains_p add_p seed cpus total_time 138 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.33634 139 | test set scheduler range blocks contains_p add_p seed cpus total_time 140 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.32894 141 | test set scheduler range blocks contains_p add_p seed cpus total_time 142 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.78229 143 | test set scheduler range blocks contains_p add_p seed cpus total_time 144 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.80985 145 | test set scheduler range blocks contains_p add_p seed cpus total_time 146 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.15887 147 | ---- 148 | test set scheduler range blocks contains_p add_p seed cpus total_time 149 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 17.0177 150 | test set scheduler range blocks contains_p add_p seed cpus total_time 151 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.66826 152 | test set scheduler range blocks contains_p add_p seed cpus total_time 153 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.71872 154 | test set scheduler range blocks contains_p add_p seed cpus total_time 155 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.66463 156 | test set scheduler range blocks contains_p add_p seed cpus total_time 157 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.22231 158 | test set scheduler range blocks contains_p add_p seed cpus total_time 159 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.40294 160 | test set scheduler range blocks contains_p add_p seed cpus total_time 161 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.52237 162 | test set scheduler range blocks contains_p add_p seed cpus total_time 163 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.4394 164 | test set scheduler range blocks contains_p add_p seed cpus total_time 165 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.1889 166 | test set scheduler range blocks contains_p add_p seed cpus total_time 167 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.29452 168 | test set scheduler range blocks contains_p add_p seed cpus total_time 169 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.38896 170 | test set scheduler range blocks contains_p add_p seed cpus total_time 171 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.85304 172 | test set scheduler range blocks contains_p add_p seed cpus total_time 173 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 7.17436 174 | test set scheduler range blocks contains_p add_p seed cpus total_time 175 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.53831 176 | ---- 177 | test set scheduler range blocks contains_p add_p seed cpus total_time 178 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 16.8277 179 | test set scheduler range blocks contains_p add_p seed cpus total_time 180 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.66252 181 | test set scheduler range blocks contains_p add_p seed cpus total_time 182 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.70623 183 | test set scheduler range blocks contains_p add_p seed cpus total_time 184 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.69037 185 | test set scheduler range blocks contains_p add_p seed cpus total_time 186 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.22907 187 | test set scheduler range blocks contains_p add_p seed cpus total_time 188 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.94066 189 | test set scheduler range blocks contains_p add_p seed cpus total_time 190 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.51082 191 | test set scheduler range blocks contains_p add_p seed cpus total_time 192 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.3695 193 | test set scheduler range blocks contains_p add_p seed cpus total_time 194 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.1811 195 | test set scheduler range blocks contains_p add_p seed cpus total_time 196 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.26941 197 | test set scheduler range blocks contains_p add_p seed cpus total_time 198 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.38383 199 | test set scheduler range blocks contains_p add_p seed cpus total_time 200 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.82893 201 | test set scheduler range blocks contains_p add_p seed cpus total_time 202 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 7.28047 203 | test set scheduler range blocks contains_p add_p seed cpus total_time 204 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.53684 205 | ---- 206 | test set scheduler range blocks contains_p add_p seed cpus total_time 207 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 17.0483 208 | test set scheduler range blocks contains_p add_p seed cpus total_time 209 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.6723 210 | test set scheduler range blocks contains_p add_p seed cpus total_time 211 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.72008 212 | test set scheduler range blocks contains_p add_p seed cpus total_time 213 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.66526 214 | test set scheduler range blocks contains_p add_p seed cpus total_time 215 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.29438 216 | test set scheduler range blocks contains_p add_p seed cpus total_time 217 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.78999 218 | test set scheduler range blocks contains_p add_p seed cpus total_time 219 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.49133 220 | test set scheduler range blocks contains_p add_p seed cpus total_time 221 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.4622 222 | test set scheduler range blocks contains_p add_p seed cpus total_time 223 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.3283 224 | test set scheduler range blocks contains_p add_p seed cpus total_time 225 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.3246 226 | test set scheduler range blocks contains_p add_p seed cpus total_time 227 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.35437 228 | test set scheduler range blocks contains_p add_p seed cpus total_time 229 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.79698 230 | test set scheduler range blocks contains_p add_p seed cpus total_time 231 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 7.00903 232 | test set scheduler range blocks contains_p add_p seed cpus total_time 233 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.20857 234 | ---- 235 | test set scheduler range blocks contains_p add_p seed cpus total_time 236 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 16.9206 237 | test set scheduler range blocks contains_p add_p seed cpus total_time 238 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.67044 239 | test set scheduler range blocks contains_p add_p seed cpus total_time 240 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.71701 241 | test set scheduler range blocks contains_p add_p seed cpus total_time 242 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.6823 243 | test set scheduler range blocks contains_p add_p seed cpus total_time 244 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.23834 245 | test set scheduler range blocks contains_p add_p seed cpus total_time 246 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 1.96988 247 | test set scheduler range blocks contains_p add_p seed cpus total_time 248 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.62761 249 | test set scheduler range blocks contains_p add_p seed cpus total_time 250 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.4522 251 | test set scheduler range blocks contains_p add_p seed cpus total_time 252 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.186 253 | test set scheduler range blocks contains_p add_p seed cpus total_time 254 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.24871 255 | test set scheduler range blocks contains_p add_p seed cpus total_time 256 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.33024 257 | test set scheduler range blocks contains_p add_p seed cpus total_time 258 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.80087 259 | test set scheduler range blocks contains_p add_p seed cpus total_time 260 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 7.02968 261 | test set scheduler range blocks contains_p add_p seed cpus total_time 262 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.49592 263 | ---- 264 | test set scheduler range blocks contains_p add_p seed cpus total_time 265 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 16.9626 266 | test set scheduler range blocks contains_p add_p seed cpus total_time 267 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 9.67313 268 | test set scheduler range blocks contains_p add_p seed cpus total_time 269 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 6.72361 270 | test set scheduler range blocks contains_p add_p seed cpus total_time 271 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 3.68302 272 | test set scheduler range blocks contains_p add_p seed cpus total_time 273 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 2.22433 274 | test set scheduler range blocks contains_p add_p seed cpus total_time 275 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 2.81077 276 | test set scheduler range blocks contains_p add_p seed cpus total_time 277 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 2.57905 278 | test set scheduler range blocks contains_p add_p seed cpus total_time 279 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 17.3753 280 | test set scheduler range blocks contains_p add_p seed cpus total_time 281 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 11.2239 282 | test set scheduler range blocks contains_p add_p seed cpus total_time 283 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 8.26507 284 | test set scheduler range blocks contains_p add_p seed cpus total_time 285 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 5.35639 286 | test set scheduler range blocks contains_p add_p seed cpus total_time 287 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 4.79221 288 | test set scheduler range blocks contains_p add_p seed cpus total_time 289 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.92778 290 | test set scheduler range blocks contains_p add_p seed cpus total_time 291 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 7.36322 292 | -------------------------------------------------------------------------------- /task2/data/refined_refCounting.dat: -------------------------------------------------------------------------------- 1 | make: Nothing to be done for `test'. 2 | ---- 3 | test set scheduler range blocks contains_p add_p seed cpus total_time 4 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.8937 5 | test set scheduler range blocks contains_p add_p seed cpus total_time 6 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 12.3799 7 | test set scheduler range blocks contains_p add_p seed cpus total_time 8 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 10.6691 9 | test set scheduler range blocks contains_p add_p seed cpus total_time 10 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 6.90724 11 | test set scheduler range blocks contains_p add_p seed cpus total_time 12 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 4.36284 13 | test set scheduler range blocks contains_p add_p seed cpus total_time 14 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 5.20079 15 | test set scheduler range blocks contains_p add_p seed cpus total_time 16 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 6.07924 17 | test set scheduler range blocks contains_p add_p seed cpus total_time 18 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.2972 19 | test set scheduler range blocks contains_p add_p seed cpus total_time 20 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 14.3836 21 | test set scheduler range blocks contains_p add_p seed cpus total_time 22 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 11.4862 23 | test set scheduler range blocks contains_p add_p seed cpus total_time 24 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 8.22809 25 | test set scheduler range blocks contains_p add_p seed cpus total_time 26 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 8.03438 27 | test set scheduler range blocks contains_p add_p seed cpus total_time 28 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 9.92438 29 | test set scheduler range blocks contains_p add_p seed cpus total_time 30 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 6.44691 31 | ---- 32 | test set scheduler range blocks contains_p add_p seed cpus total_time 33 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.8762 34 | test set scheduler range blocks contains_p add_p seed cpus total_time 35 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 13.2381 36 | test set scheduler range blocks contains_p add_p seed cpus total_time 37 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 10.0903 38 | test set scheduler range blocks contains_p add_p seed cpus total_time 39 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 5.66445 40 | test set scheduler range blocks contains_p add_p seed cpus total_time 41 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 7.17671 42 | test set scheduler range blocks contains_p add_p seed cpus total_time 43 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 9.2254 44 | test set scheduler range blocks contains_p add_p seed cpus total_time 45 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 9.2349 46 | test set scheduler range blocks contains_p add_p seed cpus total_time 47 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.3766 48 | test set scheduler range blocks contains_p add_p seed cpus total_time 49 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 14.8313 50 | test set scheduler range blocks contains_p add_p seed cpus total_time 51 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 12.6128 52 | test set scheduler range blocks contains_p add_p seed cpus total_time 53 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 8.73473 54 | test set scheduler range blocks contains_p add_p seed cpus total_time 55 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 6.64945 56 | test set scheduler range blocks contains_p add_p seed cpus total_time 57 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.34999 58 | test set scheduler range blocks contains_p add_p seed cpus total_time 59 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 8.4979 60 | ---- 61 | test set scheduler range blocks contains_p add_p seed cpus total_time 62 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.8868 63 | test set scheduler range blocks contains_p add_p seed cpus total_time 64 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 13.3269 65 | test set scheduler range blocks contains_p add_p seed cpus total_time 66 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 10.3981 67 | test set scheduler range blocks contains_p add_p seed cpus total_time 68 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 5.60637 69 | test set scheduler range blocks contains_p add_p seed cpus total_time 70 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 4.10205 71 | test set scheduler range blocks contains_p add_p seed cpus total_time 72 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 5.68043 73 | test set scheduler range blocks contains_p add_p seed cpus total_time 74 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 13.7973 75 | test set scheduler range blocks contains_p add_p seed cpus total_time 76 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.4055 77 | test set scheduler range blocks contains_p add_p seed cpus total_time 78 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 15.6131 79 | test set scheduler range blocks contains_p add_p seed cpus total_time 80 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 10.6744 81 | test set scheduler range blocks contains_p add_p seed cpus total_time 82 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 6.44759 83 | test set scheduler range blocks contains_p add_p seed cpus total_time 84 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 5.98084 85 | test set scheduler range blocks contains_p add_p seed cpus total_time 86 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 10.0032 87 | test set scheduler range blocks contains_p add_p seed cpus total_time 88 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 14.7693 89 | ---- 90 | test set scheduler range blocks contains_p add_p seed cpus total_time 91 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 20.0206 92 | test set scheduler range blocks contains_p add_p seed cpus total_time 93 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 13.3641 94 | test set scheduler range blocks contains_p add_p seed cpus total_time 95 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 9.8851 96 | test set scheduler range blocks contains_p add_p seed cpus total_time 97 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 6.47986 98 | test set scheduler range blocks contains_p add_p seed cpus total_time 99 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 7.66038 100 | test set scheduler range blocks contains_p add_p seed cpus total_time 101 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 9.11892 102 | test set scheduler range blocks contains_p add_p seed cpus total_time 103 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 8.80881 104 | test set scheduler range blocks contains_p add_p seed cpus total_time 105 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.3189 106 | test set scheduler range blocks contains_p add_p seed cpus total_time 107 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 14.9537 108 | test set scheduler range blocks contains_p add_p seed cpus total_time 109 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 12.6826 110 | test set scheduler range blocks contains_p add_p seed cpus total_time 111 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 6.15601 112 | test set scheduler range blocks contains_p add_p seed cpus total_time 113 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 10.3575 114 | test set scheduler range blocks contains_p add_p seed cpus total_time 115 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 11.3218 116 | test set scheduler range blocks contains_p add_p seed cpus total_time 117 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 13.6649 118 | ---- 119 | test set scheduler range blocks contains_p add_p seed cpus total_time 120 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 20.1051 121 | test set scheduler range blocks contains_p add_p seed cpus total_time 122 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 12.457 123 | test set scheduler range blocks contains_p add_p seed cpus total_time 124 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 11.4304 125 | test set scheduler range blocks contains_p add_p seed cpus total_time 126 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 5.85145 127 | test set scheduler range blocks contains_p add_p seed cpus total_time 128 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 5.70018 129 | test set scheduler range blocks contains_p add_p seed cpus total_time 130 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 8.81427 131 | test set scheduler range blocks contains_p add_p seed cpus total_time 132 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 9.61702 133 | test set scheduler range blocks contains_p add_p seed cpus total_time 134 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.659 135 | test set scheduler range blocks contains_p add_p seed cpus total_time 136 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 13.5783 137 | test set scheduler range blocks contains_p add_p seed cpus total_time 138 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 10.8077 139 | test set scheduler range blocks contains_p add_p seed cpus total_time 140 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 8.06603 141 | test set scheduler range blocks contains_p add_p seed cpus total_time 142 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 9.00108 143 | test set scheduler range blocks contains_p add_p seed cpus total_time 144 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 10.0781 145 | test set scheduler range blocks contains_p add_p seed cpus total_time 146 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 14.1545 147 | ---- 148 | test set scheduler range blocks contains_p add_p seed cpus total_time 149 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.865 150 | test set scheduler range blocks contains_p add_p seed cpus total_time 151 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 13.3392 152 | test set scheduler range blocks contains_p add_p seed cpus total_time 153 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 11.4509 154 | test set scheduler range blocks contains_p add_p seed cpus total_time 155 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 5.57445 156 | test set scheduler range blocks contains_p add_p seed cpus total_time 157 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 5.23648 158 | test set scheduler range blocks contains_p add_p seed cpus total_time 159 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 9.14598 160 | test set scheduler range blocks contains_p add_p seed cpus total_time 161 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 13.5432 162 | test set scheduler range blocks contains_p add_p seed cpus total_time 163 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.294 164 | test set scheduler range blocks contains_p add_p seed cpus total_time 165 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 15.3194 166 | test set scheduler range blocks contains_p add_p seed cpus total_time 167 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 10.0325 168 | test set scheduler range blocks contains_p add_p seed cpus total_time 169 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 8.47047 170 | test set scheduler range blocks contains_p add_p seed cpus total_time 171 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 5.70925 172 | test set scheduler range blocks contains_p add_p seed cpus total_time 173 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 5.96378 174 | test set scheduler range blocks contains_p add_p seed cpus total_time 175 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 13.2518 176 | ---- 177 | test set scheduler range blocks contains_p add_p seed cpus total_time 178 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.9261 179 | test set scheduler range blocks contains_p add_p seed cpus total_time 180 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 13.2632 181 | test set scheduler range blocks contains_p add_p seed cpus total_time 182 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 11.3172 183 | test set scheduler range blocks contains_p add_p seed cpus total_time 184 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 7.81673 185 | test set scheduler range blocks contains_p add_p seed cpus total_time 186 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 3.9317 187 | test set scheduler range blocks contains_p add_p seed cpus total_time 188 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 10.2069 189 | test set scheduler range blocks contains_p add_p seed cpus total_time 190 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 8.28244 191 | test set scheduler range blocks contains_p add_p seed cpus total_time 192 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.6263 193 | test set scheduler range blocks contains_p add_p seed cpus total_time 194 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 14.2322 195 | test set scheduler range blocks contains_p add_p seed cpus total_time 196 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 12.7337 197 | test set scheduler range blocks contains_p add_p seed cpus total_time 198 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 8.0064 199 | test set scheduler range blocks contains_p add_p seed cpus total_time 200 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 6.11902 201 | test set scheduler range blocks contains_p add_p seed cpus total_time 202 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 5.90392 203 | test set scheduler range blocks contains_p add_p seed cpus total_time 204 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 8.51217 205 | ---- 206 | test set scheduler range blocks contains_p add_p seed cpus total_time 207 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.4914 208 | test set scheduler range blocks contains_p add_p seed cpus total_time 209 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 13.3461 210 | test set scheduler range blocks contains_p add_p seed cpus total_time 211 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 10.8968 212 | test set scheduler range blocks contains_p add_p seed cpus total_time 213 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 6.82029 214 | test set scheduler range blocks contains_p add_p seed cpus total_time 215 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 9.00833 216 | test set scheduler range blocks contains_p add_p seed cpus total_time 217 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 5.57277 218 | test set scheduler range blocks contains_p add_p seed cpus total_time 219 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 9.68409 220 | test set scheduler range blocks contains_p add_p seed cpus total_time 221 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.2044 222 | test set scheduler range blocks contains_p add_p seed cpus total_time 223 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 14.3025 224 | test set scheduler range blocks contains_p add_p seed cpus total_time 225 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 11.6299 226 | test set scheduler range blocks contains_p add_p seed cpus total_time 227 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 8.39414 228 | test set scheduler range blocks contains_p add_p seed cpus total_time 229 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 10.0422 230 | test set scheduler range blocks contains_p add_p seed cpus total_time 231 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.22872 232 | test set scheduler range blocks contains_p add_p seed cpus total_time 233 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 15.3513 234 | ---- 235 | test set scheduler range blocks contains_p add_p seed cpus total_time 236 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.9284 237 | test set scheduler range blocks contains_p add_p seed cpus total_time 238 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 12.9249 239 | test set scheduler range blocks contains_p add_p seed cpus total_time 240 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 10.285 241 | test set scheduler range blocks contains_p add_p seed cpus total_time 242 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 6.87747 243 | test set scheduler range blocks contains_p add_p seed cpus total_time 244 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 7.46201 245 | test set scheduler range blocks contains_p add_p seed cpus total_time 246 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 5.3739 247 | test set scheduler range blocks contains_p add_p seed cpus total_time 248 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 11.897 249 | test set scheduler range blocks contains_p add_p seed cpus total_time 250 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.6348 251 | test set scheduler range blocks contains_p add_p seed cpus total_time 252 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 15.1499 253 | test set scheduler range blocks contains_p add_p seed cpus total_time 254 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 12.9081 255 | test set scheduler range blocks contains_p add_p seed cpus total_time 256 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 10.0603 257 | test set scheduler range blocks contains_p add_p seed cpus total_time 258 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 6.21861 259 | test set scheduler range blocks contains_p add_p seed cpus total_time 260 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 9.92088 261 | test set scheduler range blocks contains_p add_p seed cpus total_time 262 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 8.36281 263 | ---- 264 | test set scheduler range blocks contains_p add_p seed cpus total_time 265 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 1 19.9922 266 | test set scheduler range blocks contains_p add_p seed cpus total_time 267 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 2 12.3839 268 | test set scheduler range blocks contains_p add_p seed cpus total_time 269 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 3 10.4604 270 | test set scheduler range blocks contains_p add_p seed cpus total_time 271 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 6 5.53672 272 | test set scheduler range blocks contains_p add_p seed cpus total_time 273 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 12 9.01032 274 | test set scheduler range blocks contains_p add_p seed cpus total_time 275 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 24 5.95057 276 | test set scheduler range blocks contains_p add_p seed cpus total_time 277 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.99 0.005 0 48 8.6888 278 | test set scheduler range blocks contains_p add_p seed cpus total_time 279 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 1 20.492 280 | test set scheduler range blocks contains_p add_p seed cpus total_time 281 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 2 15.0886 282 | test set scheduler range blocks contains_p add_p seed cpus total_time 283 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 3 9.92973 284 | test set scheduler range blocks contains_p add_p seed cpus total_time 285 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 6 6.57471 286 | test set scheduler range blocks contains_p add_p seed cpus total_time 287 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 12 6.20719 288 | test set scheduler range blocks contains_p add_p seed cpus total_time 289 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 24 6.21097 290 | test set scheduler range blocks contains_p add_p seed cpus total_time 291 | set_bench CuckooSet BStrategyScheduler> 10000 1000 0.5 0.25 0 48 13.5574 292 | --------------------------------------------------------------------------------