├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── bmarks ├── .gitignore ├── math_cache.c ├── noise.c ├── snap_stress.c ├── test.c ├── test_mem.c └── test_ro.c ├── external ├── .gitignore └── include │ ├── .gitignore │ └── utils.h ├── include ├── .gitignore ├── atomic_ops.h ├── clht.h ├── clht_lb.h ├── clht_lb_linked.h ├── clht_lb_lock_ins.h ├── clht_lb_packed.h ├── clht_lb_res.h ├── clht_lf.h ├── clht_lf_only_map_rem.h ├── clht_lf_res.h ├── common.h ├── latency.h ├── measurements.h └── prand.h ├── scripts ├── .gitignore ├── bins_add_suffix.sh ├── build_microbench.sh ├── config ├── create_plots.sh ├── create_plots_ll_sl_ht.sh ├── events_all ├── lock-free.gp ├── lock_exec ├── make_all.sh ├── make_all_locks.sh ├── make_dependencies.sh ├── o.sh ├── perf.list ├── repeat.sh ├── run.sh ├── run_2.sh ├── run_all_hts.sh ├── run_all_hts_real.sh ├── run_avg.sh ├── run_compare.sh ├── run_compare_ht.sh ├── run_compare_hy_pre.sh ├── run_compare_lf_hy_noise.sh ├── run_compare_locks.sh ├── run_ht_short_buckets.sh ├── run_lf.sh ├── run_lf_ll.sh ├── run_lf_socket.sh ├── run_lf_socket_short.sh ├── run_lf_step.sh ├── run_lf_vs_lb_all_short.sh ├── run_lf_vs_lb_socket_short.sh ├── run_ll_sl_ht.sh ├── run_mp.sh ├── run_normal.sh ├── run_rep.sh ├── run_spinlocks.sh ├── run_throughput.sh ├── scalability.sh ├── scalability10.sh ├── scalability2.sh ├── scalability3.sh ├── scalability4.sh ├── scalability5.sh ├── scalability6.sh ├── scalability7.sh ├── scalability8.sh ├── scalability9.sh ├── test.sh ├── test_correctness.sh ├── test_hy_correctness.sh ├── test_mp.sh └── unlock_exec └── src ├── .gitignore ├── clht_gc.c ├── clht_lb.c ├── clht_lb_linked.c ├── clht_lb_lock_ins.c ├── clht_lb_packed.c ├── clht_lb_res.c ├── clht_lb_res_no_next.c ├── clht_lf.c ├── clht_lf_only_map_rem.c ├── clht_lf_res.c └── measurements.c /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | /#*eshell*# 3 | /#main_lock.c# 4 | /#main_lock_res.c# 5 | /*eshell* 6 | /.#main_lock.c 7 | /.#main_lock_res.c 8 | /.gitignore~ 9 | /.nfs00000000083a09c60000001a 10 | /.nfs00000000084a00130000001b 11 | /.nfs00000000084a0ac40000008e 12 | /.nfs00000000084a104700000024 13 | /.nfs00000000084a10480000000e 14 | /.nfs00000000084a10480000001e 15 | /.nfs00000000084a104800000021 16 | /.nfs00000000084a10c300000011 17 | /.nfs00000000084a10ce0000008d 18 | /.nfs00000000084a15a900000003 19 | /.nfs00000000084a15fe0000001e 20 | /.nfs00000000084a164900000027 21 | /.nfs00000000084a16620000002a 22 | /.nfs00000000084a17610000000f 23 | /.nfs00000000084a176200000010 24 | /Makefile~ 25 | /alock.o 26 | /clht_gc.o 27 | /clht_gc_linked.o 28 | /clht_lb 29 | /clht_lb.o 30 | /clht_lb_linked 31 | /clht_lb_linked.o 32 | /clht_lb_lock_ins 33 | /clht_lb_lock_ins.o 34 | /clht_lb_nn 35 | /clht_lb_packed 36 | /clht_lb_packed.o 37 | /clht_lb_res 38 | /clht_lb_res.o 39 | /clht_lb_res_no_next.o 40 | /clht_lb_ro 41 | /clht_lbp 42 | /clht_lf 43 | /clht_lf.o 44 | /clht_lf_only_map_rem 45 | /clht_lf_only_map_rem.o 46 | /clht_lf_res 47 | /clht_lf_res.o 48 | /core 49 | /cscope.files 50 | /cscope.out 51 | /data 52 | /dht_mp.o 53 | /events_all 54 | /external/lib 55 | /full_stress_lf 56 | /h 57 | /hclh.o 58 | /hl 59 | /htlock.o 60 | /hyht 61 | /hyht_gc 62 | /hyht_h 63 | /hyht_help 64 | /hyht_help_no 65 | /hyht_lat 66 | /hyht_lat_lock 67 | /hyht_lat_rtm 68 | /hyht_latm 69 | /hyht_linked 70 | /hyht_linked_lat 71 | /hyht_lock 72 | /hyht_lock_ins 73 | /hyht_lock_lat 74 | /hyht_mt 75 | /hyht_nh 76 | /hyht_nn 77 | /hyht_no_val 78 | /hyht_res 79 | /hyht_res1 80 | /hyht_res1opt 81 | /hyht_res_help 82 | /hyht_res_help_no 83 | /hyht_res_lat 84 | /hyht_res_lat1 85 | /hyht_res_lat_1 86 | /hyht_res_lat_help 87 | /hyht_res_lat_help_no 88 | /hyht_res_lat_no_help 89 | /hyht_ro 90 | /hyht_rtm 91 | /hyht_simple 92 | /hyht_sm 93 | /hyht_wrapper 94 | /hyhtl 95 | /hyhtm 96 | /hyhtp 97 | /hyhtp_lat 98 | /hylzht 99 | /latency_array 100 | /latency_clh 101 | /latency_hclh 102 | /latency_hticket 103 | /latency_mcs 104 | /latency_mutex 105 | /latency_spinlock 106 | /latency_ticket 107 | /latency_ttas 108 | /lf-ht 109 | /lfht 110 | /lfht.s 111 | /lfht3 112 | /lfht4 113 | /lfht6 114 | /lfht_dup 115 | /lfht_only_map_rem 116 | /lfht_res 117 | /lfht_res1 118 | /lfht_res_lat 119 | /lfht_s 120 | /lfhtm 121 | /libclht.a 122 | /main_lock.c~ 123 | /math_cache 124 | /math_cache_lat 125 | /math_cache_lb 126 | /math_cache_lf 127 | /math_cache_lf_dup 128 | /math_cache_lock_ins 129 | /math_cache_nogc_lf 130 | /mcore_malloc.o 131 | /mcore_malloc_mp.o 132 | /mcs.o 133 | /noise 134 | /o 135 | /perf.sh 136 | /perf.sh~ 137 | /plot 138 | /plot_sparc 139 | /pseudo 140 | /run 141 | /run_2.sh~ 142 | /run_avg.sh~ 143 | /run_stat 144 | /run_stat~ 145 | /run_throughput.sh~ 146 | /run~ 147 | /rw_ttas.o 148 | /sequential 149 | /snap_stress 150 | /test 151 | /throughput_array 152 | /throughput_clh 153 | /throughput_hclh 154 | /throughput_hticket 155 | /throughput_mcs 156 | /throughput_mp 157 | /throughput_mutex 158 | /throughput_spinlock 159 | /throughput_ticke_no_pre 160 | /throughput_ticket 161 | /throughput_ticket_fai 162 | /throughput_ticket_lf 163 | /throughput_ticket_no_pre 164 | /throughput_ticket_tas 165 | /throughput_ttas 166 | /ticket.o 167 | /top.sh 168 | /top.sh~ 169 | /ttas.o 170 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Vasileios Trigonakis 4 | Distributed Programming Lab (LPD), EPFL 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ################################# 2 | # Architecture dependent settings 3 | ################################# 4 | 5 | CFLAGS = -D_GNU_SOURCE 6 | 7 | ifeq ($(DEBUG),1) 8 | DEBUG_FLAGS=-Wall -ggdb -g -DDEBUG 9 | CFLAGS += -O0 -DADD_PADDING -fno-inline 10 | else ifeq ($(DEBUG),2) 11 | DEBUG_FLAGS=-Wall 12 | CFLAGS += -O0 -DADD_PADDING -fno-inline 13 | else ifeq ($(DEBUG),3) 14 | DEBUG_FLAGS=-Wall -g -ggdb 15 | CFLAGS += -O3 -DADD_PADDING -fno-inline 16 | else 17 | DEBUG_FLAGS=-Wall 18 | CFLAGS += -O3 -DADD_PADDING 19 | endif 20 | 21 | ifeq ($(SET_CPU),0) 22 | CFLAGS += -DNO_SET_CPU 23 | endif 24 | 25 | ifeq ($(LATENCY),1) 26 | CFLAGS += -DCOMPUTE_LATENCY -DDO_TIMINGS 27 | endif 28 | 29 | ifeq ($(LATENCY),2) 30 | CFLAGS += -DCOMPUTE_LATENCY -DDO_TIMINGS -DUSE_SSPFD -DLATENCY_ALL_CORES=0 31 | LIBS += $(SSPFD) -lm 32 | endif 33 | 34 | ifeq ($(LATENCY),3) 35 | CFLAGS += -DCOMPUTE_LATENCY -DDO_TIMINGS -DUSE_SSPFD -DLATENCY_ALL_CORES=1 36 | LIBS += $(SSPFD) -lm 37 | endif 38 | 39 | ifeq ($(LATENCY),4) 40 | CFLAGS += -DCOMPUTE_LATENCY -DDO_TIMINGS -DUSE_SSPFD -DLATENCY_PARSING=1 41 | LIBS += $(SSPFD) -lm 42 | endif 43 | 44 | ifeq ($(LATENCY),5) 45 | CFLAGS += -DCOMPUTE_LATENCY -DDO_TIMINGS -DUSE_SSPFD -DLATENCY_PARSING=1 -DLATENCY_ALL_CORES=1 46 | LIBS += $(SSPFD) -lm 47 | endif 48 | 49 | TOP := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) 50 | 51 | LIBS+=-L$(TOP)/external/lib -L$(TOP) 52 | 53 | SRCPATH := $(TOP)/src 54 | MAININCLUDE := $(TOP)/include 55 | 56 | ifeq ($(M),1) 57 | LIBS += -lsspfd 58 | CFLAGS += -DUSE_SSPFD 59 | endif 60 | 61 | # default setings 62 | PLATFORM=-DDEFAULT 63 | GCC=gcc 64 | PLATFORM_NUMA=0 65 | OPTIMIZE= 66 | LIBS += -lrt -lpthread -lm -lclht -lssmem 67 | 68 | UNAME := $(shell uname -n) 69 | 70 | ifeq ($(UNAME), lpd48core) 71 | PLATFORM=-DOPTERON 72 | GCC=gcc-4.8 73 | PLATFORM_NUMA=1 74 | OPTIMIZE=-DOPTERON_OPTIMIZE 75 | PLATFORM_NUMA=1 76 | endif 77 | 78 | ifeq ($(UNAME), lpdxeon2680) 79 | PLATFORM=-DXEON2 80 | GCC=gcc 81 | PLATFORM_NUMA=1 82 | OPTIMIZE= 83 | endif 84 | 85 | ifeq ($(UNAME), lpdpc4) 86 | PLATFORM=-DCOREi7 87 | GCC=gcc 88 | PLATFORM_NUMA=0 89 | OPTIMIZE= 90 | endif 91 | 92 | ifeq ($(UNAME), lpdpc34) 93 | PLATFORM=-DCOREi7 -DRTM 94 | GCC=gcc-4.8 95 | PLATFORM_NUMA=0 96 | OPTIMIZE= 97 | LIBS += -mrtm 98 | endif 99 | 100 | ifeq ($(UNAME), diascld9) 101 | PLATFORM=-DOPTERON2 102 | GCC=gcc 103 | LIBS += 104 | endif 105 | 106 | ifeq ($(UNAME), diassrv8) 107 | PLATFORM=-DXEON 108 | GCC=gcc 109 | PLATFORM_NUMA=1 110 | LIBS += -lnuma 111 | endif 112 | 113 | ifeq ($(UNAME), diascld19) 114 | PLATFORM=-DXEON2 115 | GCC=gcc 116 | LIBS += 117 | endif 118 | 119 | ifeq ($(UNAME), maglite) 120 | PLATFORM=-DSPARC 121 | GCC:=/opt/csw/bin/gcc 122 | LIBS+= 123 | CFLAGS += -m64 -mcpu=v9 -mtune=v9 124 | endif 125 | 126 | ifeq ($(UNAME), parsasrv1.epfl.ch) 127 | PLATFORM=-DTILERA 128 | GCC=tile-gcc 129 | LIBS += -ltmc 130 | endif 131 | 132 | ifeq ($(UNAME), smal1.sics.se) 133 | PLATFORM=-DTILERA 134 | GCC=tile-gcc 135 | LIBS += -ltmc 136 | endif 137 | 138 | ifeq ($(UNAME), ol-collab1) 139 | PLATFORM=-DT44 140 | GCC=/usr/sfw/bin/gcc 141 | CFLAGS += -m64 142 | LIBS+= 143 | endif 144 | 145 | ifeq ($(PLATFORM_NUMA), 1) 146 | CFLAGS += -DNUMA 147 | LIBS += -lnuma 148 | endif 149 | 150 | CFLAGS += $(PLATFORM) 151 | CFLAGS += $(OPTIMIZE) 152 | CFLAGS += $(DEBUG_FLAGS) 153 | 154 | INCLUDES := -I$(MAININCLUDE) -I$(TOP)/external/include 155 | OBJ_FILES := clht_gc.o 156 | 157 | SRC := src 158 | 159 | BMARKS := bmarks 160 | 161 | #MAIN_BMARK := $(BMARKS)/test.c # no memory allocation 162 | #MAIN_BMARK := $(BMARKS)/test_ro.c # read-only benchmark 163 | MAIN_BMARK := $(BMARKS)/test_mem.c # memory allocation 164 | 165 | ALL = clht_lb clht_lb_res clht_lb_res_no_next clht_lb_ro clht_lb_linked clht_lb_packed \ 166 | clht_lf clht_lf_res clht_lf_only_map_rem 167 | 168 | REST = math_cache_lb math_cache_lf \ 169 | snap_stress noise 170 | 171 | default: normal 172 | 173 | dependencies: 174 | ./scripts/make_dependencies.sh 175 | 176 | rest: $(REST) 177 | 178 | all: $(ALL) 179 | 180 | .PHONY: $(ALL) \ 181 | libclht_lb.a libclht_lb_res.a libclht_lb_res_no_next.a \ 182 | libclht_lb_linked.a libclht_lb_packed.a libclht_lb_lock_ins.a \ 183 | libclht_lf.a libclht_lf_res.a libclht_lf_only_map_rem.a 184 | 185 | normal: clht_lb_res clht_lf_res 186 | 187 | 188 | %.o:: $(SRC)/%.c 189 | $(GCC) $(CFLAGS) $(INCLUDES) -o $@ -c $< 190 | 191 | clht_gc_linked.o: $(SRC)/clht_gc.c 192 | $(GCC) -DCLHT_LINKED $(CFLAGS) $(INCLUDES) -o clht_gc_linked.o -c $(SRC)/clht_gc.c 193 | 194 | ################################################################################ 195 | # library 196 | ################################################################################ 197 | 198 | TYPE = clht_lb 199 | OBJ = $(TYPE).o 200 | lib$(TYPE).a: $(OBJ_FILES) $(OBJ) 201 | @echo Archive name = libclht.a 202 | ar -d libclht.a * 203 | ar -r libclht.a clht_lb.o $(OBJ_FILES) 204 | 205 | TYPE = clht_lb_res 206 | OBJ = $(TYPE).o 207 | lib$(TYPE).a: $(OBJ_FILES) $(OBJ) 208 | @echo Archive name = libclht.a 209 | ar -d libclht.a * 210 | ar -r libclht.a clht_lb_res.o $(OBJ_FILES) 211 | 212 | TYPE = clht_lb_res_no_next 213 | OBJ = $(TYPE).o 214 | lib$(TYPE).a: $(OBJ_FILES) $(OBJ) 215 | @echo Archive name = libclht.a 216 | ar -d libclht.a * 217 | ar -r libclht.a clht_lb_res_no_next.o $(OBJ_FILES) 218 | 219 | TYPE = clht_lb_linked 220 | OBJ = $(TYPE).o 221 | lib$(TYPE).a: clht_gc_linked.o $(OBJ) 222 | @echo Archive name = libclht.a 223 | ar -d libclht.a * 224 | ar -r libclht.a clht_lb_linked.o clht_gc_linked.o 225 | 226 | TYPE = clht_lb_packed 227 | OBJ = $(TYPE).o 228 | lib$(TYPE).a: $(OBJ_FILES) $(OBJ) 229 | @echo Archive name = libclht.a 230 | ar -d libclht.a * 231 | ar -r libclht.a clht_lb_packed.o $(OBJ_FILES) 232 | 233 | TYPE = clht_lb_lock_ins 234 | OBJ = $(TYPE).o 235 | lib$(TYPE).a: $(OBJ_FILES) $(OBJ) 236 | @echo Archive name = libclht.a 237 | ar -d libclht.a * 238 | ar -r libclht.a clht_lb_lock_ins.o $(OBJ_FILES) 239 | 240 | TYPE = clht_lf 241 | OBJ = $(TYPE).o 242 | lib$(TYPE).a: $(OBJ_FILES) $(OBJ) 243 | @echo Archive name = libclht.a 244 | ar -d libclht.a * 245 | ar -r libclht.a clht_lf.o $(OBJ_FILES) 246 | 247 | TYPE = clht_lf_res 248 | OBJ = $(TYPE).o 249 | lib$(TYPE).a: $(OBJ_FILES) $(OBJ) 250 | @echo Archive name = libclht.a 251 | ar -d libclht.a * 252 | ar -r libclht.a clht_lf_res.o $(OBJ_FILES) 253 | 254 | TYPE = clht_lf_only_map_rem 255 | OBJ = $(TYPE).o 256 | lib$(TYPE).a: $(OBJ_FILES) $(OBJ) 257 | @echo Archive name = libclht.a 258 | ar -d libclht.a * 259 | ar -r libclht.a clht_lf_only_map_rem.o $(OBJ_FILES) 260 | 261 | ################################################################################ 262 | # lock-based targets 263 | ################################################################################ 264 | 265 | TYPE = clht_lb 266 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 267 | $(GCC) -DNO_RESIZE $(CFLAGS) $(INCLUDES) $(MAIN_BMARK) -o clht_lb $(LIBS) -lclht 268 | 269 | TYPE = clht_lb_res 270 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 271 | $(GCC) $(INCLUDES) $(CFLAGS) $(MAIN_BMARK) $(SRC)/clht_lb_res.c -o clht_lb_res $(LIBS) 272 | 273 | TYPE = clht_lb_res_no_next 274 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 275 | $(GCC) $(CFLAGS) $(INCLUDES) $(MAIN_BMARK) -o clht_lb_nn $(LIBS) 276 | 277 | TYPE = clht_lb_linked 278 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 279 | $(GCC) $(CFLAGS) $(INCLUDES) $(MAIN_BMARK) -o clht_lb_linked $(LIBS) 280 | 281 | TYPE = clht_lb_packed 282 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 283 | $(GCC) $(CFLAGS) $(INCLUDES) $(MAIN_BMARK) $(SRC)/clht_lb_packed.c -o clht_lb_packed $(LIBS) 284 | 285 | TYPE = clht_lb_lock_ins 286 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 287 | $(GCC) -DLOCK_INS $(CFLAGS) $(INCLUDES) $(MAIN_BMARK) -o clht_lb_lock_ins $(LIBS) 288 | 289 | ################################################################################ 290 | # lock-free targets 291 | ################################################################################ 292 | 293 | TYPE = clht_lf 294 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 295 | $(GCC) -DLOCKFREE $(CFLAGS) $(INCLUDES) $(MAIN_BMARK) -o clht_lf $(LIBS) 296 | 297 | TYPE = clht_lf_res 298 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 299 | $(GCC) -DLOCKFREE_RES $(CFLAGS) $(INCLUDES) $(MAIN_BMARK) -o clht_lf_res $(LIBS) 300 | 301 | TYPE = clht_lf_only_map_rem 302 | $(TYPE): $(MAIN_BMARK) lib$(TYPE).a 303 | $(GCC) -DLOCKFREE $(CFLAGS) $(INCLUDES) $(MAIN_BMARK) -o clht_lf_only_map_rem $(LIBS) 304 | 305 | ################################################################################ 306 | # other tests 307 | ################################################################################ 308 | 309 | math_cache_lb: $(BMARKS)/math_cache.c libclht_lb_res.a 310 | $(GCC) $(CFLAGS) $(INCLUDES) $(BMARKS)/math_cache.c -o math_cache_lb $(LIBS) 311 | 312 | math_cache_lf: $(BMARKS)/math_cache.c libclht_lf_res.a 313 | $(GCC) -DLOCKFREE $(CFLAGS) $(INCLUDES) $(BMARKS)/math_cache.c -o math_cache_lf $(LIBS) 314 | 315 | snap_stress: $(BMARKS)/snap_stress.c libclht_lf_res.a 316 | $(GCC) -DLOCKFREE $(CFLAGS) $(INCLUDES) $(BMARKS)/snap_stress.c -o snap_stress $(LIBS) 317 | 318 | noise: $(BMARKS)/noise.c $(OBJ_FILES) 319 | $(GCC) $(CFLAGS) $(INCLUDES) $(OBJ_FILES) $(BMARKS)/noise.c -o noise $(LIBS) 320 | 321 | 322 | 323 | clean: 324 | rm -f *.o *.a clht_* math_cache* snap_stress 325 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CLHT 2 | ==== 3 | 4 | CLHT is a very fast and scalable concurrent, resizable hash table. It comes in two (main) variants, a lock-based and a lock-free. 5 | The main idea behind CLHT is to, if possible, use cache-line-sized buckets so that update operations (`put` and `remove`) complete with at most one cache-line transfer. Furthermore, CLHT is based on two ideas: 6 | 1. operations parse (go through) the elements of a bucket taking a snapshot of each key/value pair, 7 | 2. `get` operations are read-only (i.e., they do not perform any stores) and are wait-free (i.e., they never have to restart), and 8 | 2. update operations perform in place updates, hence they do not require any memory allocation. 9 | 10 | The result is very low latency operations. For example, a single thread on an Intel Ivy Bridge processor achieves the following latencies (in cycles): 11 | * srch-suc: 58 12 | * srch-fal: 21 13 | * insr-suc: 74 14 | * insr-fal: 62 15 | * remv-suc: 91 16 | * remv-fal: 19 17 | 18 | This translates to more than 50 Mega-operations/sec in our benchmarks (the actual throughput of CLHT is even higher, but the benchmarking code takes a significant portion of the execution). 19 | 20 | In concurrent settings, CLHT gives more than 2 Billion-operations/sec with read-only executions on 40 threads on a 2-socket Ivy Bridge, more than 1 Billion-operations/sec with 1% updates, 900 Mega-operations/sec with 10%, and 300 Mega-operations/sec with update operations only. 21 | 22 | 23 | * Website : http://lpd.epfl.ch/site/ascylib 24 | * Author : Vasileios Trigonakis 25 | * Related Publications: CLHT was developed for: 26 | *Asynchronized Concurrency: The Secret to Scaling Concurrent Search Data Structures*, 27 | Tudor David, Rachid Guerraoui, Vasileios Trigonakis (alphabetical order), 28 | ASPLOS '15 29 | 30 | You can also find a detailed description of the algorithms and correctness sketches in the following technical report: https://infoscience.epfl.ch/record/203822 31 | 32 | CLHT-LB (Lock-based version) 33 | ---------------------------- 34 | 35 | CLHT-LB synchronizes update operations (`put` and `remove`) with locks. In short, an update first checks whether the operation can be successful (i.e., if the given key exists for a removal, or if the key is not already in there for an insertion), and if it is, it grabs the corresponding lock and performs the update. 36 | 37 | If a `put` find the bucket full, then either the bucket is expanded (linked to another bucket), or the hash table is resized (for the variants of CLHT-LB that support resizing). 38 | 39 | We have implemented the following variants of CLHT-LB: 40 | 1. `clht_lb_res`: the default version, supports resizing. 41 | 2. `clht_lb`: as (1), but w/o resizing. 42 | 3. `clht_lb_res_no_next`: as (1), but the hash table is immediately resized when there is no space for a `put`. 43 | 4. `clht_lb_packed`: as (2), but elements are "packed" in the first slots of the bucket. Removals move elements to avoid leaving any empty slots. 44 | 5. `clht_lb_linked`: as (1), but the buckets are linked to their next buckets (b0 to b1, b1 to b2, ...), so that if there is no space in a bucket, the next one is used. If the hash table is too full, it is resized. 45 | 6. `clht_lb_lock_ins`: as (2), but `remove` operations do not lock. The work using `compare-and-swap` operations. 46 | 47 | CLHT-LF (Lock-free version) 48 | --------------------------- 49 | 50 | CLHT-LF synchronizes update operations (`put` and `remove`) in a lock-free manner. Instead of locks, CLHT-LF uses the `snapshot_t` structure. `snapshot_t` is an 8-byte structure with two fields: a version number and an array of bytes (a map). The map is used to indicate whether a key/value pair in the bucket is valid, invalid, or is being inserted. The version field is used to indicate that the `snapshot_t` object has been changed by a concurrent update. 51 | 52 | We have implemented the following variants of CLHT-LF: 53 | 1. `clht_lf_res`: the default version, supports resizing. 54 | 2. `clht_lf`: as (1), but w/o resizing. NB. CLHT-LF cannot expand/link bucket, thus, if there is not enough space for a `put`, the operation might never complete. 55 | 3. `clht_lf_only_map_rem`: as (2), but `remove` operations do not increment the `snapshot_t`'s version number. 56 | 57 | 58 | Compilation 59 | ----------- 60 | 61 | You can install the dependencies of CLHT with `make dependencies`. 62 | 63 | CLHT requires the ssmem memory allocator (https://github.com/LPD-EPFL/ssmem). 64 | Clone ssmem, do `make libssmem.a` and then copy `libssmem.a` in `CLHT/external/lib` and `include/smmem.h` in `CLHT/external/include`. 65 | 66 | Additionally, the sspfd profiler library is required (https://github.com/trigonak/sspfd). 67 | Clone sspfd, do `make` and then copy `libsspfd.a` in `CLHT/external/lib` and `include/sspfd.h` in `CLHT/external/include`. 68 | 69 | You can compile the different variants of CLHT with the corresponding target. For example: 70 | `make libclht_lb_res.a` will build the `clht_lb_res` version. 71 | 72 | The compilation always produces the `libclht.a`, regardless of the variant that is built. 73 | 74 | Various parameters can be set for each variant in the corresponding header file (e.g., `include/clht_lb_res.h` for the `clht_lb_res` version). 75 | 76 | To make a debug build of CLHT, you can do `make target DEBUG=1`. 77 | 78 | Tests 79 | ----- 80 | 81 | CLHT comes with various microbenchmarks. `make all` builds a performance benchmark for each variant of CLHT. 82 | You can control which test file to be used in Makefile by changing `MAIN_BMARK` variable. 83 | You can set it to: 84 | * `test.c`: for a test w/o memory allocation for the values 85 | * `test_mem.c`: for a test with memory allocation for the values 86 | * `test_ro.c`: for a read-only test 87 | 88 | Call any of the executables with `-h` to get the available options of the tests. 89 | 90 | Additionally, you can build `make rest` that builds some correctness tests. 91 | 92 | 93 | Using CLHT 94 | ---------- 95 | 96 | To use CLHT you need to include the `clht.h` file in your source code and then link with `-lclht -lssmem` (ssmem is used in the CLHT implementation). 97 | 98 | The following functions can be used to create and use a new hash table: 99 | * `clht_t* clht_create(uint32_t num_buckets)`: creates a new CLHT instance. 100 | * `void clht_gc_thread_init(clht_t* hashtable, int id)`: initializes the GC for hash table resizing. Every thread should make this call before using the hash table. 101 | * `void clht_gc_destroy(clht_t* hashtable)`: frees up the hash table 102 | * `clht_val_t clht_get(clht_hashtable_t* hashtable, clht_addr_t key)`: gets the value for a give key, or return 0 103 | * `int clht_put(clht_t* hashtable, clht_addr_t key, clht_val_t val)`: inserts a new key/value pair (if the key is not already present) 104 | * `clht_val_t clht_remove(clht_t* hashtable, clht_addr_t key)`: removes the key from the hash table (if the key is present) 105 | * `void clht_print(clht_hashtable_t* hashtable)`: prints the hash talble 106 | * `const char* clht_type_desc()`: return the type of CLHT. For example, CLHT-LB-RESIZE. 107 | 108 | 109 | Details 110 | ------- 111 | 112 | ### Resizing 113 | 114 | Hash-table resizing is implemented in a pessimistic manner, both on CLHT-LB and CLHT-LF. Thus, CLHT-LF resizing is not lock-free. 115 | 116 | On CLHT-LB resizing is pretty straightforward: lock and then copy each bucket. Concurrent `get` operations can proceed while resizing is ongoing. CLHT-LB supports *helping* (i.e., other threads than the one starting the resizing help with the procedure). Helping is controlled by the `CLHT_HELP_RESIZE` define in the `clht_lb_res.h` file. In our experiments, helping proved beneficial only on huge hash tables. Due to the structure of CLHT-LB, copying data is very fast, as the buckets are an array in memory. 117 | 118 | On CLHT-LF resizing is implemented with a global lock. To resize a thread grabs the lock and waits for all threads to indicate that they are "aware" that a resize is in progress. This is done by a thread-local flag that indicates whether there is an ongoing update operation on the current hash table or not. 119 | -------------------------------------------------------------------------------- /bmarks/.gitignore: -------------------------------------------------------------------------------- 1 | /cscope.out 2 | /math_cache 3 | /math_cache_lf 4 | /math_cache_lf_dup 5 | /math_cache_nogc_lf 6 | -------------------------------------------------------------------------------- /bmarks/noise.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: noise.c 3 | * Author: Vasileios Trigonakis 4 | * Description: 5 | * noise.c is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #include "utils.h" 32 | #include 33 | 34 | int core = 0; 35 | int direct = 0; 36 | 37 | 38 | typedef struct thd 39 | { 40 | int id; 41 | int core; 42 | } thd_t; 43 | 44 | void* 45 | test(void* d) 46 | { 47 | thd_t* td = (thd_t*) d; 48 | int id = td->id; 49 | int my_core = the_cores[core + td->core]; 50 | if (direct) 51 | { 52 | my_core = core + td->core; 53 | } 54 | 55 | printf("[%-2d] running on core %d\n", id, my_core); 56 | set_cpu(my_core); 57 | 58 | volatile long long unsigned int i, j, k = 0; 59 | while (1) 60 | { 61 | for (i = 2; i < 2e32; i++) 62 | { 63 | for (j = 2; j < i; j++) 64 | { 65 | if (i % j == 0) 66 | { 67 | k--; 68 | break; 69 | } 70 | } 71 | k++; 72 | } 73 | } 74 | } 75 | 76 | 77 | int 78 | main(int a, char** v) 79 | { 80 | printf("//Usage: ./noise [NUM_THREADS] [THREADS_PER_CORE] [DIRECT]\n" 81 | "// where DIRECT selects whether to start with set_cpu(0), or set_cpu(the_cores[0])\n"); 82 | int num_threads = 1; 83 | int per_core = 1; 84 | 85 | if (a > 1) 86 | { 87 | num_threads = atoi(v[1]); 88 | } 89 | if (a > 2) 90 | { 91 | per_core = atoi(v[2]); 92 | } 93 | if (a > 3) 94 | { 95 | direct = 1; 96 | } 97 | 98 | printf("# num of threads: %d / threads per core: %d / direct placement: %d\n", num_threads, per_core, direct); 99 | 100 | 101 | pthread_t threads[num_threads]; 102 | pthread_attr_t attr; 103 | int rc; 104 | void *status; 105 | 106 | /* Initialize and set thread detached attribute */ 107 | pthread_attr_init(&attr); 108 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 109 | 110 | thd_t* d = (thd_t*) malloc(num_threads * sizeof(thd_t)); 111 | assert(d != NULL); 112 | 113 | int c = 0; 114 | int this = 0; 115 | 116 | long t; 117 | for(t = 0; t < num_threads; t++) 118 | { 119 | d[t].id = t; 120 | d[t].core = c; 121 | rc = pthread_create(&threads[t], &attr, test, d + t); 122 | if (rc) 123 | { 124 | printf("ERROR; return code from pthread_create() is %d\n", rc); 125 | exit(-1); 126 | } 127 | 128 | if (++this == per_core) 129 | { 130 | this = 0; 131 | c++; 132 | } 133 | 134 | } 135 | 136 | 137 | /* Free attribute and wait for the other threads */ 138 | pthread_attr_destroy(&attr); 139 | 140 | for(t = 0; t < num_threads; t++) 141 | { 142 | rc = pthread_join(threads[t], &status); 143 | if (rc) 144 | { 145 | printf("ERROR; return code from pthread_join() is %d\n", rc); 146 | exit(-1); 147 | } 148 | } 149 | 150 | free(d); 151 | 152 | return 0; 153 | } 154 | -------------------------------------------------------------------------------- /external/.gitignore: -------------------------------------------------------------------------------- 1 | /ssmem 2 | /sspfd 3 | -------------------------------------------------------------------------------- /external/include/.gitignore: -------------------------------------------------------------------------------- 1 | /alock.h 2 | /atomic_ops.h 3 | /clh.h 4 | /gl_lock.h 5 | /hclh.h 6 | /htlock.h 7 | /lock_if.h 8 | /mcs.h 9 | /rw_ttas.h 10 | /spinlock.h 11 | /ssmem.h 12 | /ssmp.h 13 | /sspfd.h 14 | /ticket.h 15 | /ttas.h 16 | -------------------------------------------------------------------------------- /include/.gitignore: -------------------------------------------------------------------------------- 1 | /.#dht.h 2 | /.gitignore~ 3 | /cscope.out 4 | /dht.h~ 5 | /hylzht.h~ 6 | /main_mp.h~ 7 | -------------------------------------------------------------------------------- /include/atomic_ops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: atomic_ops.h 3 | * Author: Tudor David 4 | * Description: 5 | * atomic_ops.h is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | /* 32 | * File: atomic_ops.h 33 | * Author: Tudor David 34 | * 35 | * Created on: December 06, 2012 36 | * 37 | * Description: 38 | * Cross-platform atomic operations 39 | */ 40 | #ifndef _ATOMIC_OPS_H_INCLUDED_ 41 | #define _ATOMIC_OPS_H_INCLUDED_ 42 | 43 | #include 44 | 45 | #ifdef __sparc__ 46 | /* 47 | * sparc code 48 | */ 49 | 50 | # include 51 | 52 | //test-and-set uint8_t 53 | static inline uint8_t tas_uint8(volatile uint8_t *addr) { 54 | uint8_t oldval; 55 | __asm__ __volatile__("ldstub %1,%0" 56 | : "=r"(oldval), "=m"(*addr) 57 | : "m"(*addr) : "memory"); 58 | return oldval; 59 | } 60 | 61 | //Compare-and-swap 62 | #define CAS_PTR(a,b,c) atomic_cas_ptr(a,b,c) 63 | #define CAS_U8(a,b,c) atomic_cas_8(a,b,c) 64 | #define CAS_U16(a,b,c) atomic_cas_16(a,b,c) 65 | #define CAS_U32(a,b,c) atomic_cas_32(a,b,c) 66 | #define CAS_U64(a,b,c) atomic_cas_64(a,b,c) 67 | //Swap 68 | #define SWAP_PTR(a,b) atomic_swap_ptr(a,b) 69 | #define SWAP_U8(a,b) atomic_swap_8(a,b) 70 | #define SWAP_U16(a,b) atomic_swap_16(a,b) 71 | #define SWAP_U32(a,b) atomic_swap_32(a,b) 72 | #define SWAP_U64(a,b) atomic_swap_64(a,b) 73 | //Fetch-and-increment 74 | #define FAI_U8(a) (atomic_inc_8_nv(a)-1) 75 | #define FAI_U16(a) (atomic_inc_16_nv(a)-1) 76 | #define FAI_U32(a) (atomic_inc_32_nv(a)-1) 77 | #define FAI_U64(a) (atomic_inc_64_nv(a)-1) 78 | //Fetch-and-decrement 79 | #define FAD_U8(a) (atomic_dec_8_nv(a,)+1) 80 | #define FAD_U16(a) (atomic_dec_16_nv(a)+1) 81 | #define FAD_U32(a) (atomic_dec_32_nv(a)+1) 82 | #define FAD_U64(a) (atomic_dec_64_nv(a)+1) 83 | //Increment-and-fetch 84 | #define IAF_U8(a) atomic_inc_8_nv(a) 85 | #define IAF_U16(a) atomic_inc_16_nv(a) 86 | #define IAF_U32(a) atomic_inc_32_nv(a) 87 | #define IAF_U64(a) atomic_inc_64_nv(a) 88 | //Decrement-and-fetch 89 | #define DAF_U8(a) atomic_dec_8_nv(a) 90 | #define DAF_U16(a) atomic_dec_16_nv(a) 91 | #define DAF_U32(a) atomic_dec_32_nv(a) 92 | #define DAF_U64(a) atomic_dec_64_nv(a) 93 | //Test-and-set 94 | #define TAS_U8(a) tas_uint8(a) 95 | //Memory barrier 96 | #define MEM_BARRIER asm volatile("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore"); 97 | //end of sparc code 98 | #elif defined(__tile__) 99 | /* 100 | * Tilera code 101 | */ 102 | #include 103 | #include 104 | //atomic operations interface 105 | //Compare-and-swap 106 | #define CAS_PTR(a,b,c) arch_atomic_val_compare_and_exchange(a,b,c) 107 | #define CAS_U8(a,b,c) arch_atomic_val_compare_and_exchange(a,b,c) 108 | #define CAS_U16(a,b,c) arch_atomic_val_compare_and_exchange(a,b,c) 109 | #define CAS_U32(a,b,c) arch_atomic_val_compare_and_exchange(a,b,c) 110 | #define CAS_U64(a,b,c) arch_atomic_val_compare_and_exchange(a,b,c) 111 | //Swap 112 | #define SWAP_PTR(a,b) arch_atomic_exchange(a,b) 113 | #define SWAP_U8(a,b) arch_atomic_exchange(a,b) 114 | #define SWAP_U16(a,b) arch_atomic_exchange(a,b) 115 | #define SWAP_U32(a,b) arch_atomic_exchange(a,b) 116 | #define SWAP_U64(a,b) arch_atomic_exchange(a,b) 117 | //Fetch-and-increment 118 | #define FAI_U8(a) arch_atomic_increment(a) 119 | #define FAI_U16(a) arch_atomic_increment(a) 120 | #define FAI_U32(a) arch_atomic_increment(a) 121 | #define FAI_U64(a) arch_atomic_increment(a) 122 | //Fetch-and-decrement 123 | #define FAD_U8(a) arch_atomic_decrement(a) 124 | #define FAD_U16(a) arch_atomic_decrement(a) 125 | #define FAD_U32(a) arch_atomic_decrement(a) 126 | #define FAD_U64(a) arch_atomic_decrement(a) 127 | //Increment-and-fetch 128 | #define IAF_U8(a) (arch_atomic_increment(a)+1) 129 | #define IAF_U16(a) (arch_atomic_increment(a)+1) 130 | #define IAF_U32(a) (arch_atomic_increment(a)+1) 131 | #define IAF_U64(a) (arch_atomic_increment(a)+1) 132 | //Decrement-and-fetch 133 | #define DAF_U8(a) (arch_atomic_decrement(a)-1) 134 | #define DAF_U16(a) (arch_atomic_decrement(a)-1) 135 | #define DAF_U32(a) (arch_atomic_decrement(a)-1) 136 | #define DAF_U64(a) (arch_atomic_decrement(a)-1) 137 | //Test-and-set 138 | #define TAS_U8(a) arch_atomic_val_compare_and_exchange(a,0,0xff) 139 | //Memory barrier 140 | #define MEM_BARRIER arch_atomic_full_barrier() 141 | //Relax CPU 142 | //define PAUSE cycle_relax() 143 | 144 | //end of tilera code 145 | #else 146 | /* 147 | * x86 code 148 | */ 149 | 150 | # include 151 | 152 | //Swap pointers 153 | static inline void* swap_pointer(volatile void* ptr, void *x) { 154 | # ifdef __i386__ 155 | __asm__ __volatile__("xchgl %0,%1" 156 | :"=r" ((unsigned) x) 157 | :"m" (*(volatile unsigned *)ptr), "0" (x) 158 | :"memory"); 159 | 160 | return x; 161 | # elif defined(__x86_64__) 162 | __asm__ __volatile__("xchgq %0,%1" 163 | :"=r" ((unsigned long long) x) 164 | :"m" (*(volatile long long *)ptr), "0" ((unsigned long long) x) 165 | :"memory"); 166 | 167 | return x; 168 | # endif 169 | } 170 | 171 | //Swap uint64_t 172 | static inline uint64_t swap_uint64(volatile uint64_t* target, uint64_t x) { 173 | __asm__ __volatile__("xchgq %0,%1" 174 | :"=r" ((uint64_t) x) 175 | :"m" (*(volatile uint64_t *)target), "0" ((uint64_t) x) 176 | :"memory"); 177 | 178 | return x; 179 | } 180 | 181 | //Swap uint32_t 182 | static inline uint32_t swap_uint32(volatile uint32_t* target, uint32_t x) { 183 | __asm__ __volatile__("xchgl %0,%1" 184 | :"=r" ((uint32_t) x) 185 | :"m" (*(volatile uint32_t *)target), "0" ((uint32_t) x) 186 | :"memory"); 187 | 188 | return x; 189 | } 190 | 191 | //Swap uint16_t 192 | static inline uint16_t swap_uint16(volatile uint16_t* target, uint16_t x) { 193 | __asm__ __volatile__("xchgw %0,%1" 194 | :"=r" ((uint16_t) x) 195 | :"m" (*(volatile uint16_t *)target), "0" ((uint16_t) x) 196 | :"memory"); 197 | 198 | return x; 199 | } 200 | 201 | //Swap uint8_t 202 | static inline uint8_t swap_uint8(volatile uint8_t* target, uint8_t x) { 203 | __asm__ __volatile__("xchgb %0,%1" 204 | :"=r" ((uint8_t) x) 205 | :"m" (*(volatile uint8_t *)target), "0" ((uint8_t) x) 206 | :"memory"); 207 | 208 | return x; 209 | } 210 | 211 | //test-and-set uint8_t 212 | static inline uint8_t tas_uint8(volatile uint8_t *addr) { 213 | uint8_t oldval; 214 | __asm__ __volatile__("xchgb %0,%1" 215 | : "=q"(oldval), "=m"(*addr) 216 | : "0"((unsigned char) 0xff), "m"(*addr) : "memory"); 217 | return (uint8_t) oldval; 218 | } 219 | 220 | //atomic operations interface 221 | //Compare-and-swap 222 | #define CAS_PTR(a,b,c) __sync_val_compare_and_swap(a,b,c) 223 | #define CAS_U8(a,b,c) __sync_val_compare_and_swap(a,b,c) 224 | #define CAS_U16(a,b,c) __sync_val_compare_and_swap(a,b,c) 225 | #define CAS_U32(a,b,c) __sync_val_compare_and_swap(a,b,c) 226 | #define CAS_U64(a,b,c) __sync_val_compare_and_swap(a,b,c) 227 | //Swap 228 | #define SWAP_PTR(a,b) swap_pointer(a,b) 229 | #define SWAP_U8(a,b) swap_uint8(a,b) 230 | #define SWAP_U16(a,b) swap_uint16(a,b) 231 | #define SWAP_U32(a,b) swap_uint32(a,b) 232 | #define SWAP_U64(a,b) swap_uint64(a,b) 233 | //Fetch-and-increment 234 | #define FAI_U8(a) __sync_fetch_and_add(a,1) 235 | #define FAI_U16(a) __sync_fetch_and_add(a,1) 236 | #define FAI_U32(a) __sync_fetch_and_add(a,1) 237 | #define FAIV_U32(a,v) __sync_fetch_and_add(a,v) 238 | #define FAI_U64(a) __sync_fetch_and_add(a,1) 239 | //Fetch-and-decrement 240 | #define FAD_U8(a) __sync_fetch_and_sub(a,1) 241 | #define FAD_U16(a) __sync_fetch_and_sub(a,1) 242 | #define FAD_U32(a) __sync_fetch_and_sub(a,1) 243 | #define FAD_U64(a) __sync_fetch_and_sub(a,1) 244 | //Increment-and-fetch 245 | #define IAF_U8(a) __sync_add_and_fetch(a,1) 246 | #define IAF_U16(a) __sync_add_and_fetch(a,1) 247 | #define IAF_U32(a) __sync_add_and_fetch(a,1) 248 | #define IAF_U64(a) __sync_add_and_fetch(a,1) 249 | //Decrement-and-fetch 250 | #define DAF_U8(a) __sync_sub_and_fetch(a,1) 251 | #define DAF_U16(a) __sync_sub_and_fetch(a,1) 252 | #define DAF_U32(a) __sync_sub_and_fetch(a,1) 253 | #define DAF_U64(a) __sync_sub_and_fetch(a,1) 254 | //Test-and-set 255 | #define TAS_U8(a) tas_uint8(a) 256 | //Memory barrier 257 | #define MEM_BARRIER __sync_synchronize() 258 | //Relax CPU 259 | //#define PAUSE _mm_pause() 260 | 261 | /*End of x86 code*/ 262 | #endif 263 | 264 | 265 | #endif 266 | 267 | 268 | 269 | -------------------------------------------------------------------------------- /include/clht.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: clht.h 3 | * Author: Vasileios Trigonakis 4 | * Description: CLHT common interface 5 | * clht.h is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #ifndef _CLHT_H_ 32 | #define _CLHT_H_ 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #define true 1 39 | #define false 0 40 | 41 | /* #define DEBUG */ 42 | 43 | #if defined(DEBUG) 44 | # define DPP(x) x++ 45 | #else 46 | # define DPP(x) 47 | #endif 48 | 49 | #define CACHE_LINE_SIZE 64 50 | 51 | #define MAP_INVLD 0 52 | #define MAP_VALID 1 53 | #define MAP_INSRT 2 54 | 55 | #define KEY_BUCKT 3 56 | #define ENTRIES_PER_BUCKET KEY_BUCKT 57 | 58 | #define CLHT_DO_GC 1 59 | #define CLHT_PERC_FULL_HALVE 2 60 | #define CLHT_PERC_FULL_DOUBLE 15 61 | #define CLHT_OCCUP_AFTER_RES 40 62 | #define CLHT_INC_EMERGENCY 2 63 | #define CLHT_NO_EMPTY_SLOT_TRIES 16 64 | #define CLHT_GC_HT_VERSION_USED(ht) clht_gc_thread_version(ht) 65 | #define LOAD_FACTOR 2 66 | 67 | #ifndef ALIGNED 68 | # if __GNUC__ && !SCC 69 | # define ALIGNED(N) __attribute__ ((aligned (N))) 70 | # else 71 | # define ALIGNED(N) 72 | # endif 73 | #endif 74 | 75 | #define likely(x) __builtin_expect((x), 1) 76 | #define unlikely(x) __builtin_expect((x), 0) 77 | 78 | #if defined(__sparc__) 79 | # define PREFETCHW(x) 80 | # define PREFETCH(x) 81 | # define PREFETCHNTA(x) 82 | # define PREFETCHT0(x) 83 | # define PREFETCHT1(x) 84 | # define PREFETCHT2(x) 85 | 86 | # define PAUSE asm volatile("rd %%ccr, %%g0\n\t" \ 87 | ::: "memory") 88 | # define _mm_pause() PAUSE 89 | # define _mm_mfence() __asm__ __volatile__("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore"); 90 | # define _mm_lfence() __asm__ __volatile__("membar #LoadLoad | #LoadStore"); 91 | # define _mm_sfence() __asm__ __volatile__("membar #StoreLoad | #StoreStore"); 92 | 93 | 94 | #elif defined(__tile__) 95 | # define _mm_lfence() arch_atomic_read_barrier() 96 | # define _mm_sfence() arch_atomic_write_barrier() 97 | # define _mm_mfence() arch_atomic_full_barrier() 98 | # define _mm_pause() cycle_relax() 99 | #endif 100 | 101 | #define CAS_U64_BOOL(a, b, c) (CAS_U64(a, b, c) == b) 102 | static inline int 103 | is_power_of_two (unsigned int x) 104 | { 105 | return ((x != 0) && !(x & (x - 1))); 106 | } 107 | 108 | 109 | typedef uintptr_t clht_addr_t; 110 | typedef volatile uintptr_t clht_val_t; 111 | typedef uint64_t clht_snapshot_all_t; 112 | 113 | typedef union 114 | { 115 | volatile uint64_t snapshot; 116 | struct 117 | { 118 | #if KEY_BUCKT == 4 119 | uint32_t version; 120 | #elif KEY_BUCKT == 6 121 | uint16_t version; 122 | #else 123 | uint32_t version; 124 | #endif 125 | uint8_t map[KEY_BUCKT]; 126 | }; 127 | } clht_snapshot_t; 128 | 129 | #if __GNUC__ > 4 && __GNUC_MINOR__ > 4 130 | _Static_assert (sizeof(clht_snapshot_t) == 8, "sizeof(clht_snapshot_t) == 8"); 131 | #endif 132 | 133 | typedef volatile struct ALIGNED(CACHE_LINE_SIZE) bucket_s 134 | { 135 | union 136 | { 137 | volatile uint64_t snapshot; 138 | struct 139 | { 140 | #if KEY_BUCKT == 4 141 | uint32_t version; 142 | #elif KEY_BUCKT == 6 143 | uint16_t version; 144 | #else 145 | uint32_t version; 146 | /* # error "KEY_BUCKT should be either 4 or 6" */ 147 | #endif 148 | uint8_t map[KEY_BUCKT]; 149 | }; 150 | }; 151 | clht_addr_t key[KEY_BUCKT]; 152 | clht_val_t val[KEY_BUCKT]; 153 | volatile struct bucket_s* padding; 154 | } bucket_t; 155 | 156 | #if __GNUC__ > 4 && __GNUC_MINOR__ > 4 157 | _Static_assert (sizeof(bucket_t) % 64 == 0, "sizeof(bucket_t) == 64"); 158 | #endif 159 | 160 | #if defined(__tile__) 161 | typedef volatile uint32_t clht_lock_t; 162 | #else 163 | typedef volatile uint8_t clht_lock_t; 164 | #endif 165 | /* typedef volatile uint64_t clht_lock_t; */ 166 | #define CLHT_LOCK_FREE 0 167 | #define CLHT_LOCK_ACQR 1 168 | 169 | #define CLHT_CHECK_RESIZE(w) \ 170 | while (unlikely(w->resize_lock == CLHT_LOCK_ACQR)) \ 171 | { \ 172 | _mm_pause(); \ 173 | CLHT_GC_HT_VERSION_USED(w->ht); \ 174 | } 175 | 176 | #define CLHT_LOCK_RESIZE(w) \ 177 | (CAS_U8(&w->resize_lock, CLHT_LOCK_FREE, CLHT_LOCK_ACQR) == CLHT_LOCK_FREE) 178 | 179 | #define CLHT_RLS_RESIZE(w) \ 180 | w->resize_lock = CLHT_LOCK_FREE 181 | 182 | #define TRYLOCK_ACQ(lock) \ 183 | TAS_U8(lock) 184 | 185 | #define TRYLOCK_RLS(lock) \ 186 | lock = CLHT_LOCK_FREE 187 | 188 | 189 | typedef struct ALIGNED(CACHE_LINE_SIZE) clht 190 | { 191 | union 192 | { 193 | struct 194 | { 195 | struct clht_hashtable_s* ht; 196 | uint8_t next_cache_line[CACHE_LINE_SIZE - (sizeof(void*))]; 197 | struct clht_hashtable_s* ht_oldest; 198 | struct ht_ts* version_list; 199 | size_t version_min; 200 | volatile clht_lock_t resize_lock; 201 | volatile clht_lock_t gc_lock; 202 | volatile clht_lock_t status_lock; 203 | }; 204 | uint8_t padding[2 * CACHE_LINE_SIZE]; 205 | }; 206 | } clht_t; 207 | 208 | typedef struct ALIGNED(CACHE_LINE_SIZE) clht_hashtable_s 209 | { 210 | union 211 | { 212 | struct 213 | { 214 | size_t num_buckets; 215 | bucket_t* table; 216 | size_t hash; 217 | size_t version; 218 | uint8_t next_cache_line[CACHE_LINE_SIZE - (3 * sizeof(size_t)) - (sizeof(void*))]; 219 | struct clht_hashtable_s* table_tmp; 220 | struct clht_hashtable_s* table_prev; 221 | struct clht_hashtable_s* table_new; 222 | volatile uint32_t num_expands; 223 | union 224 | { 225 | volatile uint32_t num_expands_threshold; 226 | uint32_t num_buckets_prev; 227 | }; 228 | volatile int32_t is_helper; 229 | volatile int32_t helper_done; 230 | size_t version_min; 231 | }; 232 | uint8_t padding[2*CACHE_LINE_SIZE]; 233 | }; 234 | } clht_hashtable_t; 235 | 236 | extern uint64_t __ac_Jenkins_hash_64(uint64_t key); 237 | 238 | /* Hash a key for a particular hashtable. */ 239 | uint64_t clht_hash(clht_hashtable_t* hashtable, clht_addr_t key); 240 | 241 | 242 | static inline int 243 | snap_get_empty_index(uint64_t snap) 244 | { 245 | clht_snapshot_t s = { .snapshot = snap }; 246 | int i; 247 | for (i = 0; i < KEY_BUCKT; i++) 248 | { 249 | if (s.map[i] == MAP_INVLD) 250 | { 251 | return i; 252 | } 253 | } 254 | return -1; 255 | } 256 | 257 | static inline int 258 | keys_get_empty_index(clht_addr_t* keys) 259 | { 260 | int i; 261 | for (i = 0; i < KEY_BUCKT; i++) 262 | { 263 | if (keys[i] == 0) 264 | { 265 | return i; 266 | } 267 | } 268 | return -1; 269 | } 270 | 271 | static inline int 272 | buck_get_empty_index(bucket_t* b, uint64_t snap) 273 | { 274 | clht_snapshot_t s = { .snapshot = snap }; 275 | 276 | int i; 277 | for (i = 0; i < KEY_BUCKT; i++) 278 | { 279 | if (b->key[i] == 0 && s.map[i] != MAP_INSRT) 280 | { 281 | return i; 282 | } 283 | } 284 | return -1; 285 | } 286 | 287 | 288 | static inline int 289 | vals_get_empty_index(clht_val_t* vals, clht_snapshot_all_t snap) 290 | { 291 | clht_snapshot_t s = { .snapshot = snap }; 292 | 293 | int i; 294 | for (i = 0; i < KEY_BUCKT; i++) 295 | { 296 | if (vals[i] == 0 && s.map[i] != MAP_INSRT) 297 | { 298 | return i; 299 | } 300 | } 301 | return -1; 302 | } 303 | 304 | 305 | static inline uint64_t 306 | snap_set_map(uint64_t s, int index, int val) 307 | { 308 | clht_snapshot_t s1 = { .snapshot = s }; 309 | s1.map[index] = val; 310 | return s1.snapshot; 311 | } 312 | 313 | static inline uint64_t 314 | snap_set_map_and_inc_version(uint64_t s, int index, int val) 315 | { 316 | clht_snapshot_t s1 = { .snapshot = s}; 317 | s1.map[index] = val; 318 | s1.version++; 319 | return s1.snapshot; 320 | } 321 | 322 | static inline void 323 | _mm_pause_rep(uint64_t w) 324 | { 325 | while (w--) 326 | { 327 | _mm_pause(); 328 | } 329 | } 330 | 331 | 332 | 333 | /* ******************************************************************************** */ 334 | /* inteface */ 335 | /* ******************************************************************************** */ 336 | 337 | #ifdef __cplusplus 338 | extern "C" 339 | { 340 | #endif 341 | 342 | /* Create a new hashtable. */ 343 | clht_t* clht_create(uint64_t num_buckets); 344 | /* initializes the necessary per-thread structures for the hash table */ 345 | void clht_gc_thread_init(clht_t* hashtable, int id); 346 | 347 | 348 | /* Insert a key-value pair into a hashtable. */ 349 | int clht_put(clht_t* hashtable, clht_addr_t key, clht_val_t val); 350 | /* Retrieve a key-value pair from a hashtable. */ 351 | clht_val_t clht_get(clht_hashtable_t* hashtable, clht_addr_t key); 352 | /* Remove a key-value pair from a hashtable. */ 353 | clht_val_t clht_remove(clht_t* hashtable, clht_addr_t key); 354 | 355 | /* returns the size of the hash table */ 356 | size_t clht_size(clht_hashtable_t* hashtable); 357 | 358 | /* frees the memory used by the hashtable */ 359 | void clht_gc_destroy(clht_t* hashtable); 360 | 361 | /* prints the contents of the hash table */ 362 | void clht_print(clht_hashtable_t* hashtable); 363 | 364 | /* string description of the type of the hash table 365 | For example, CLHT-LB-RESIZE */ 366 | const char* clht_type_desc(); 367 | 368 | #ifdef __cplusplus 369 | } 370 | #endif 371 | 372 | /* internal */ 373 | extern void clht_gc_thread_version(clht_hashtable_t* h); 374 | extern void clht_gc_thread_version_max(); 375 | extern int clht_gc_get_id(); 376 | 377 | 378 | 379 | #endif /* _CLHT_H_ */ 380 | 381 | -------------------------------------------------------------------------------- /include/clht_lb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: clht_lb.h 3 | * Author: Vasileios Trigonakis 4 | * Description: lock-based cache-line hash table with no resizing 5 | * clht_lb.h is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #ifndef _CLHT_LB_H_ 32 | #define _CLHT_LB_H_ 33 | 34 | #include 35 | #include 36 | #include 37 | #include "atomic_ops.h" 38 | #include "utils.h" 39 | 40 | #include "ssmem.h" 41 | 42 | #define true 1 43 | #define false 0 44 | 45 | #define READ_ONLY_FAIL 46 | 47 | #if defined(DEBUG) 48 | # define DPP(x) x++ 49 | #else 50 | # define DPP(x) 51 | #endif 52 | 53 | #define CACHE_LINE_SIZE 64 54 | #define ENTRIES_PER_BUCKET 3 55 | 56 | #ifndef ALIGNED 57 | # if __GNUC__ && !SCC 58 | # define ALIGNED(N) __attribute__ ((aligned (N))) 59 | # else 60 | # define ALIGNED(N) 61 | # endif 62 | #endif 63 | 64 | #if defined(__sparc__) 65 | # define PREFETCHW(x) 66 | # define PREFETCH(x) 67 | # define PREFETCHNTA(x) 68 | # define PREFETCHT0(x) 69 | # define PREFETCHT1(x) 70 | # define PREFETCHT2(x) 71 | 72 | # define PAUSE asm volatile("rd %%ccr, %%g0\n\t" \ 73 | ::: "memory") 74 | # define _mm_pause() PAUSE 75 | # define _mm_mfence() __asm__ __volatile__("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore"); 76 | # define _mm_lfence() __asm__ __volatile__("membar #LoadLoad | #LoadStore"); 77 | # define _mm_sfence() __asm__ __volatile__("membar #StoreLoad | #StoreStore"); 78 | 79 | 80 | #elif defined(__tile__) 81 | # define _mm_lfence() arch_atomic_read_barrier() 82 | # define _mm_sfence() arch_atomic_write_barrier() 83 | # define _mm_mfence() arch_atomic_full_barrier() 84 | # define _mm_pause() cycle_relax() 85 | #endif 86 | 87 | #define CAS_U64_BOOL(a, b, c) (CAS_U64(a, b, c) == b) 88 | inline int is_power_of_two(unsigned int x); 89 | 90 | typedef uintptr_t clht_addr_t; 91 | typedef volatile uintptr_t clht_val_t; 92 | 93 | typedef uint64_t clht_lock_t; 94 | 95 | typedef struct ALIGNED(CACHE_LINE_SIZE) bucket_s 96 | { 97 | clht_lock_t lock; 98 | clht_addr_t key[ENTRIES_PER_BUCKET]; 99 | clht_val_t val[ENTRIES_PER_BUCKET]; 100 | struct bucket_s* next; 101 | } bucket_t; 102 | 103 | typedef struct ALIGNED(CACHE_LINE_SIZE) clht 104 | { 105 | union 106 | { 107 | struct 108 | { 109 | struct clht_hashtable_s* ht; 110 | uint8_t next_cache_line[CACHE_LINE_SIZE - (sizeof(void*))]; 111 | }; 112 | uint8_t padding[2 * CACHE_LINE_SIZE]; 113 | }; 114 | } clht_t; 115 | 116 | typedef struct ALIGNED(CACHE_LINE_SIZE) clht_hashtable_s 117 | { 118 | union 119 | { 120 | struct 121 | { 122 | size_t num_buckets; 123 | bucket_t* table; 124 | }; 125 | uint8_t padding[1 * CACHE_LINE_SIZE]; 126 | }; 127 | } clht_hashtable_t; 128 | 129 | static inline void 130 | _mm_pause_rep(uint64_t w) 131 | { 132 | while (w--) 133 | { 134 | _mm_pause(); 135 | } 136 | } 137 | 138 | #define TAS_WITH_FAI 139 | /* #define TAS_WITH_TAS */ 140 | /* #define TAS_WITH_CAS */ 141 | /* #define TAS_WITH_SWAP */ 142 | 143 | #if defined(XEON) 144 | # define TAS_RLS_MFENCE() _mm_mfence(); 145 | #else 146 | # define TAS_RLS_MFENCE() 147 | #endif 148 | 149 | #if defined(TAS_WITH_FAI) 150 | # define LOCK_ACQ(lock) \ 151 | while (FAI_U64(lock)) \ 152 | { \ 153 | _mm_pause(); \ 154 | DPP(put_num_restarts); \ 155 | } 156 | #elif defined(TAS_WITH_TAS) 157 | # define LOCK_ACQ(lock) \ 158 | while (TAS_U8((uint8_t*) (lock))) \ 159 | { \ 160 | _mm_pause(); \ 161 | DPP(put_num_restarts); \ 162 | } 163 | #elif defined(TAS_WITH_SWAP) 164 | # define LOCK_ACQ(lock) \ 165 | while (SWAP_U64(lock, 1)) \ 166 | { \ 167 | _mm_pause(); \ 168 | DPP(put_num_restarts); \ 169 | } 170 | #endif 171 | 172 | #define LOCK_RLS(lock) \ 173 | TAS_RLS_MFENCE(); \ 174 | *lock = 0; 175 | 176 | /* Create a new hashtable. */ 177 | clht_hashtable_t* clht_hashtable_create(uint64_t num_buckets ); 178 | clht_t* clht_create(uint64_t num_buckets); 179 | 180 | /* Hash a key for a particular hashtable. */ 181 | uint64_t clht_hash(clht_hashtable_t* hashtable, clht_addr_t key ); 182 | 183 | /* Insert a key-value pair into a hashtable. */ 184 | int clht_put(clht_t* h, clht_addr_t key, clht_val_t val); 185 | 186 | /* Retrieve a key-value pair from a hashtable. */ 187 | clht_val_t clht_get(clht_hashtable_t* hashtable, clht_addr_t key); 188 | 189 | /* Remove a key-value pair from a hashtable. */ 190 | clht_val_t clht_remove(clht_t* hashtable, clht_addr_t key); 191 | 192 | /* Dealloc the hashtable */ 193 | void clht_destroy(clht_hashtable_t* hashtable); 194 | 195 | size_t clht_size(clht_hashtable_t* hashtable); 196 | 197 | void clht_print(clht_hashtable_t* hashtable); 198 | 199 | bucket_t* clht_bucket_create(); 200 | 201 | const char* clht_type_desc(); 202 | 203 | #endif /* _CLHT_LB_H_ */ 204 | -------------------------------------------------------------------------------- /include/clht_lb_packed.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: clht_lb_packed.h 3 | * Author: Vasileios Trigonakis 4 | * Description: lock-based cache-line hash table with no resizing. All elements 5 | * are "packed" in the first slots of the bucket. Removals move elements to 6 | * avoid leaving any empty slots. 7 | * clht_lb_packed.h is part of ASCYLIB 8 | * 9 | * The MIT License (MIT) 10 | * 11 | * Copyright (c) 2014 Vasileios Trigonakis 12 | * Distributed Programming Lab (LPD), EPFL 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 15 | * this software and associated documentation files (the "Software"), to deal in 16 | * the Software without restriction, including without limitation the rights to 17 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 18 | * the Software, and to permit persons to whom the Software is furnished to do so, 19 | * subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in all 22 | * copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 27 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 28 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | * 31 | */ 32 | 33 | #ifndef _CLHT_PACKED_PACKED_H_ 34 | #define _CLHT_PACKED_PACKED_H_ 35 | 36 | #include 37 | #include 38 | #include 39 | #include "atomic_ops.h" 40 | #include "utils.h" 41 | 42 | #include "ssmem.h" 43 | 44 | #define true 1 45 | #define false 0 46 | 47 | #define READ_ONLY_FAIL 48 | /* #define DEBUG */ 49 | 50 | #if defined(DEBUG) 51 | # define DPP(x) x++ 52 | #else 53 | # define DPP(x) 54 | #endif 55 | 56 | #define CACHE_LINE_SIZE 64 57 | #define ENTRIES_PER_BUCKET 3 58 | 59 | #ifndef ALIGNED 60 | # if __GNUC__ && !SCC 61 | # define ALIGNED(N) __attribute__ ((aligned (N))) 62 | # else 63 | # define ALIGNED(N) 64 | # endif 65 | #endif 66 | 67 | #if defined(__sparc__) 68 | # define PREFETCHW(x) 69 | # define PREFETCH(x) 70 | # define PREFETCHNTA(x) 71 | # define PREFETCHT0(x) 72 | # define PREFETCHT1(x) 73 | # define PREFETCHT2(x) 74 | 75 | # define PAUSE asm volatile("rd %%ccr, %%g0\n\t" \ 76 | ::: "memory") 77 | # define _mm_pause() PAUSE 78 | # define _mm_mfence() __asm__ __volatile__("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore"); 79 | # define _mm_lfence() __asm__ __volatile__("membar #LoadLoad | #LoadStore"); 80 | # define _mm_sfence() __asm__ __volatile__("membar #StoreLoad | #StoreStore"); 81 | 82 | 83 | #elif defined(__tile__) 84 | # define _mm_lfence() arch_atomic_read_barrier() 85 | # define _mm_sfence() arch_atomic_write_barrier() 86 | # define _mm_mfence() arch_atomic_full_barrier() 87 | # define _mm_pause() cycle_relax() 88 | #endif 89 | 90 | #define CAS_U64_BOOL(a, b, c) (CAS_U64(a, b, c) == b) 91 | 92 | typedef uintptr_t clht_addr_t; 93 | typedef volatile uintptr_t clht_val_t; 94 | 95 | typedef uint8_t hyht_lock_t; 96 | 97 | typedef struct ALIGNED(CACHE_LINE_SIZE) bucket_s 98 | { 99 | hyht_lock_t lock; 100 | uint32_t last; 101 | clht_addr_t key[ENTRIES_PER_BUCKET]; 102 | clht_val_t val[ENTRIES_PER_BUCKET]; 103 | struct bucket_s* next; 104 | } bucket_t; 105 | 106 | typedef struct ALIGNED(CACHE_LINE_SIZE) clht 107 | { 108 | union 109 | { 110 | struct 111 | { 112 | struct clht_hashtable_s* ht; 113 | uint8_t next_cache_line[CACHE_LINE_SIZE - (sizeof(void*))]; 114 | }; 115 | uint8_t padding[2 * CACHE_LINE_SIZE]; 116 | }; 117 | } clht_t; 118 | 119 | typedef struct ALIGNED(CACHE_LINE_SIZE) clht_hashtable_s 120 | { 121 | union 122 | { 123 | struct 124 | { 125 | size_t num_buckets; 126 | bucket_t* table; 127 | }; 128 | uint8_t padding[1 * CACHE_LINE_SIZE]; 129 | }; 130 | } clht_hashtable_t; 131 | 132 | static inline void 133 | _mm_pause_rep(uint64_t w) 134 | { 135 | while (w--) 136 | { 137 | _mm_pause(); 138 | } 139 | } 140 | 141 | /* #define TAS_WITH_FAI */ 142 | #define TAS_WITH_TAS 143 | /* #define TAS_WITH_CAS */ 144 | /* #define TAS_WITH_SWAP */ 145 | 146 | #if defined(XEON) | defined(COREi7) 147 | # define TAS_RLS_MFENCE() _mm_mfence(); 148 | #else 149 | # define TAS_RLS_MFENCE() 150 | #endif 151 | 152 | #if defined(TAS_WITH_FAI) 153 | # define LOCK_ACQ(lock) \ 154 | while (FAI_U32((uint32_t*) lock)) \ 155 | { \ 156 | _mm_pause(); \ 157 | DPP(put_num_restarts); \ 158 | } 159 | #elif defined(TAS_WITH_TAS) 160 | # define LOCK_ACQ(lock) \ 161 | while (TAS_U8((uint8_t*) (lock))) \ 162 | { \ 163 | _mm_pause(); \ 164 | DPP(put_num_restarts); \ 165 | } 166 | #elif defined(TAS_WITH_SWAP) 167 | # define LOCK_ACQ(lock) \ 168 | while (SWAP_U32((uint32_t*) lock, 1)) \ 169 | { \ 170 | _mm_pause(); \ 171 | DPP(put_num_restarts); \ 172 | } 173 | #endif 174 | 175 | #define LOCK_RLS(lock) \ 176 | TAS_RLS_MFENCE(); \ 177 | *lock = 0; 178 | 179 | /* Create a new hashtable. */ 180 | clht_hashtable_t* clht_hashtable_create(uint64_t num_buckets ); 181 | clht_t* clht_create(uint64_t num_buckets); 182 | 183 | /* Hash a key for a particular hashtable. */ 184 | uint64_t clht_hash(clht_hashtable_t* hashtable, clht_addr_t key ); 185 | 186 | /* Insert a key-value pair into a hashtable. */ 187 | int clht_put(clht_t* h, clht_addr_t key, clht_val_t val); 188 | 189 | /* Retrieve a key-value pair from a hashtable. */ 190 | clht_val_t clht_get(clht_hashtable_t* hashtable, clht_addr_t key); 191 | 192 | /* Remove a key-value pair from a hashtable. */ 193 | clht_val_t clht_remove(clht_t* hashtable, clht_addr_t key); 194 | 195 | /* Dealloc the hashtable */ 196 | void clht_destroy(clht_hashtable_t* hashtable); 197 | 198 | uint64_t clht_size(clht_hashtable_t* hashtable); 199 | 200 | void clht_print(clht_hashtable_t* hashtable, uint64_t num_buckets); 201 | 202 | bucket_t* clht_bucket_create(); 203 | 204 | const char* clht_type_desc(); 205 | 206 | #endif /* _CLHT_PACKED_PACKED_H_ */ 207 | -------------------------------------------------------------------------------- /include/clht_lf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: clht_lf.h 3 | * Author: Vasileios Trigonakis 4 | * Description: lock-free cache-line hash table with no resizing. If there is 5 | * not enough space for a key/value pair in its corresponding bucket, the 6 | * operation might never complete. Thus, better use the resize version. 7 | * clht_lf.h is part of ASCYLIB 8 | * 9 | * The MIT License (MIT) 10 | * 11 | * Copyright (c) 2014 Vasileios Trigonakis 12 | * Distributed Programming Lab (LPD), EPFL 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 15 | * this software and associated documentation files (the "Software"), to deal in 16 | * the Software without restriction, including without limitation the rights to 17 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 18 | * the Software, and to permit persons to whom the Software is furnished to do so, 19 | * subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in all 22 | * copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 27 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 28 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | * 31 | */ 32 | 33 | #ifndef _CLHT_LF_RES_H_ 34 | #define _CLHT_LF_RES_H_ 35 | 36 | #include 37 | #include 38 | #include 39 | #include "atomic_ops.h" 40 | #include "utils.h" 41 | 42 | #include "ssmem.h" 43 | 44 | extern __thread ssmem_allocator_t* clht_alloc; 45 | 46 | #define true 1 47 | #define false 0 48 | 49 | /* #define DEBUG */ 50 | 51 | #if defined(DEBUG) 52 | # define DPP(x) x++ 53 | #else 54 | # define DPP(x) 55 | #endif 56 | 57 | #define CACHE_LINE_SIZE 64 58 | 59 | #define MAP_INVLD 0 60 | #define MAP_VALID 1 61 | #define MAP_INSRT 2 62 | 63 | #define KEY_BUCKT 3 64 | #define ENTRIES_PER_BUCKET KEY_BUCKT 65 | 66 | 67 | #ifndef ALIGNED 68 | # if __GNUC__ && !SCC 69 | # define ALIGNED(N) __attribute__ ((aligned (N))) 70 | # else 71 | # define ALIGNED(N) 72 | # endif 73 | #endif 74 | 75 | #define likely(x) __builtin_expect((x), 1) 76 | #define unlikely(x) __builtin_expect((x), 0) 77 | 78 | #if defined(__sparc__) 79 | # define PREFETCHW(x) 80 | # define PREFETCH(x) 81 | # define PREFETCHNTA(x) 82 | # define PREFETCHT0(x) 83 | # define PREFETCHT1(x) 84 | # define PREFETCHT2(x) 85 | 86 | # define PAUSE asm volatile("rd %%ccr, %%g0\n\t" \ 87 | ::: "memory") 88 | # define _mm_pause() PAUSE 89 | # define _mm_mfence() __asm__ __volatile__("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore"); 90 | # define _mm_lfence() __asm__ __volatile__("membar #LoadLoad | #LoadStore"); 91 | # define _mm_sfence() __asm__ __volatile__("membar #StoreLoad | #StoreStore"); 92 | 93 | 94 | #elif defined(__tile__) 95 | # define _mm_lfence() arch_atomic_read_barrier() 96 | # define _mm_sfence() arch_atomic_write_barrier() 97 | # define _mm_mfence() arch_atomic_full_barrier() 98 | # define _mm_pause() cycle_relax() 99 | #endif 100 | 101 | #define CAS_U64_BOOL(a, b, c) (CAS_U64(a, b, c) == b) 102 | inline int is_power_of_two(unsigned int x); 103 | 104 | typedef uintptr_t clht_addr_t; 105 | typedef volatile uintptr_t clht_val_t; 106 | typedef uint64_t clht_snapshot_all_t; 107 | 108 | typedef union 109 | { 110 | volatile uint64_t snapshot; 111 | struct 112 | { 113 | #if KEY_BUCKT == 4 114 | uint32_t version; 115 | #elif KEY_BUCKT == 6 116 | uint16_t version; 117 | #else 118 | uint32_t version; 119 | #endif 120 | uint8_t map[KEY_BUCKT]; 121 | }; 122 | } clht_snapshot_t; 123 | 124 | #if __GNUC__ > 4 && __GNUC_MINOR__ > 4 125 | _Static_assert (sizeof(clht_snapshot_t) == 8, "sizeof(clht_snapshot_t) == 8"); 126 | #endif 127 | 128 | typedef volatile struct ALIGNED(CACHE_LINE_SIZE) bucket_s 129 | { 130 | union 131 | { 132 | volatile uint64_t snapshot; 133 | struct 134 | { 135 | #if KEY_BUCKT == 4 136 | uint32_t version; 137 | #elif KEY_BUCKT == 6 138 | uint16_t version; 139 | #else 140 | uint32_t version; 141 | /* # error "KEY_BUCKT should be either 4 or 6" */ 142 | #endif 143 | uint8_t map[KEY_BUCKT]; 144 | }; 145 | }; 146 | clht_addr_t key[KEY_BUCKT]; 147 | clht_val_t val[KEY_BUCKT]; 148 | } bucket_t; 149 | 150 | #if __GNUC__ > 4 && __GNUC_MINOR__ > 4 151 | _Static_assert (sizeof(bucket_t) % 64 == 0, "sizeof(bucket_t) == 64"); 152 | #endif 153 | 154 | typedef struct ALIGNED(CACHE_LINE_SIZE) clht_wrapper 155 | { 156 | union 157 | { 158 | struct 159 | { 160 | struct clht_hashtable_s* ht; 161 | uint8_t next_cache_line[CACHE_LINE_SIZE - (sizeof(void*))]; 162 | }; 163 | uint8_t padding[2 * CACHE_LINE_SIZE]; 164 | }; 165 | } clht_t; 166 | 167 | typedef struct ALIGNED(CACHE_LINE_SIZE) clht_hashtable_s 168 | { 169 | union 170 | { 171 | struct 172 | { 173 | size_t num_buckets; 174 | bucket_t* table; 175 | size_t hash; 176 | }; 177 | uint8_t padding[2*CACHE_LINE_SIZE]; 178 | }; 179 | } clht_hashtable_t; 180 | 181 | inline uint64_t __ac_Jenkins_hash_64(uint64_t key); 182 | 183 | /* Hash a key for a particular hashtable. */ 184 | uint64_t clht_hash(clht_hashtable_t* hashtable, clht_addr_t key ); 185 | 186 | 187 | static inline int 188 | snap_get_empty_index(uint64_t snap) 189 | { 190 | clht_snapshot_t s = { .snapshot = snap }; 191 | int i; 192 | for (i = 0; i < KEY_BUCKT; i++) 193 | { 194 | if (s.map[i] == MAP_INVLD) 195 | { 196 | return i; 197 | } 198 | } 199 | return -1; 200 | } 201 | 202 | static inline int 203 | keys_get_empty_index(clht_addr_t* keys) 204 | { 205 | int i; 206 | for (i = 0; i < KEY_BUCKT; i++) 207 | { 208 | if (keys[i] == 0) 209 | { 210 | return i; 211 | } 212 | } 213 | return -1; 214 | } 215 | 216 | static inline int 217 | buck_get_empty_index(bucket_t* b, uint64_t snap) 218 | { 219 | clht_snapshot_t s = { .snapshot = snap }; 220 | 221 | int i; 222 | for (i = 0; i < KEY_BUCKT; i++) 223 | { 224 | if (b->key[i] == 0 && s.map[i] != MAP_INSRT) 225 | { 226 | return i; 227 | } 228 | } 229 | return -1; 230 | } 231 | 232 | 233 | static inline int 234 | vals_get_empty_index(clht_val_t* vals, clht_snapshot_all_t snap) 235 | { 236 | clht_snapshot_t s = { .snapshot = snap }; 237 | 238 | int i; 239 | for (i = 0; i < KEY_BUCKT; i++) 240 | { 241 | if (vals[i] == 0 && s.map[i] != MAP_INSRT) 242 | { 243 | return i; 244 | } 245 | } 246 | return -1; 247 | } 248 | 249 | 250 | static inline uint64_t 251 | snap_set_map(uint64_t s, int index, int val) 252 | { 253 | clht_snapshot_t s1 = { .snapshot = s }; 254 | s1.map[index] = val; 255 | return s1.snapshot; 256 | } 257 | 258 | static inline uint64_t 259 | snap_set_map_and_inc_version(uint64_t s, int index, int val) 260 | { 261 | clht_snapshot_t s1 = { .snapshot = s}; 262 | s1.map[index] = val; 263 | s1.version++; 264 | return s1.snapshot; 265 | } 266 | 267 | static inline void 268 | _mm_pause_rep(uint64_t w) 269 | { 270 | while (w--) 271 | { 272 | _mm_pause(); 273 | } 274 | } 275 | 276 | 277 | 278 | /* ******************************************************************************** */ 279 | /* inteface */ 280 | /* ******************************************************************************** */ 281 | 282 | /* Create a new hashtable. */ 283 | clht_hashtable_t* clht_hashtable_create(uint64_t num_buckets); 284 | clht_t* clht_create(uint64_t num_buckets); 285 | 286 | /* Insert a key-value pair into a hashtable. */ 287 | int clht_put(clht_t* hashtable, clht_addr_t key, clht_val_t val); 288 | 289 | /* Retrieve a key-value pair from a hashtable. */ 290 | clht_val_t clht_get(clht_hashtable_t* hashtable, clht_addr_t key); 291 | 292 | /* Remove a key-value pair from a hashtable. */ 293 | clht_val_t clht_remove(clht_t* hashtable, clht_addr_t key); 294 | 295 | size_t clht_size(clht_hashtable_t* hashtable); 296 | size_t clht_size_mem(clht_hashtable_t* hashtable); 297 | size_t clht_size_mem_garbage(clht_hashtable_t* hashtable); 298 | 299 | void clht_gc_thread_init(clht_t* hashtable, int id); 300 | inline void clht_gc_thread_version(clht_hashtable_t* h); 301 | inline int clht_gc_get_id(); 302 | int clht_gc_collect(clht_t* h); 303 | int clht_gc_collect_all(clht_t* h); 304 | int clht_gc_free(clht_hashtable_t* hashtable); 305 | void clht_gc_destroy(clht_t* hashtable); 306 | 307 | void clht_print(clht_hashtable_t* hashtable); 308 | size_t ht_status(clht_t* hashtable, int resize_increase, int just_print); 309 | 310 | bucket_t* clht_bucket_create(); 311 | int ht_resize_pes(clht_t* hashtable, int is_increase, int by); 312 | void clht_print_retry_stats(); 313 | 314 | const char* clht_type_desc(); 315 | 316 | #endif /* _CLHT_LF_RES_H_ */ 317 | 318 | -------------------------------------------------------------------------------- /include/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: common.h 3 | * Author: Vasileios Trigonakis 4 | * Description: 5 | * common.h is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #ifndef _COMMON_H_ 32 | #define _COMMON_H_ 33 | 34 | #include 35 | 36 | #define P(args...) printf("[%02d] ", ID); printf(args); printf("\n"); fflush(stdout) 37 | #define PRINT P 38 | 39 | extern uint8_t ID; 40 | #endif 41 | -------------------------------------------------------------------------------- /include/measurements.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: measurements.h 3 | * Author: Vasileios Trigonakis 4 | * Description: 5 | * measurements.h is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #ifndef _MEASUREMENTS_H_ 32 | #define _MEASUREMENTS_H_ 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #define SSMP 39 | 40 | #include "common.h" 41 | #ifdef SSMP 42 | # include "ssmp.h" 43 | #endif 44 | 45 | #if defined(LOCKS) 46 | typedef uint64_t ticks; 47 | #endif 48 | 49 | #define PLATFORM_MCORE 50 | /* #define DO_TIMINGS */ 51 | 52 | #ifndef REF_SPEED_GHZ 53 | # if defined(PLATFORM_MCORE) 54 | # define REF_SPEED_GHZ 2.1 55 | # elif defined(SCC) 56 | # define REF_SPEED_GHZ 0.533 57 | # elif defined(PLATFORM_TILERA) 58 | # define REF_SPEED_GHZ 0.7 59 | # else 60 | # error "Need to set REF_SPEED_GHZ for the platform" 61 | # endif 62 | #endif /* REF_SPEED_GHZ */ 63 | 64 | #define DO_TIMINGS_TICKS 65 | 66 | 67 | #ifndef DO_TIMINGS 68 | #undef DO_TIMINGS_TICKS 69 | #undef DO_TIMINGS_STD 70 | #define PF_MSG(pos, msg) 71 | #define PF_START(pos) 72 | #define PF_STOP(pos) 73 | #define PF_KILL(pos) 74 | #define PF_PRINT_TICKS 75 | #define PF_PRINT 76 | #define PF_EXCLUDE(pos) 77 | #define PF_CORRECTION 78 | #else 79 | #define PF_MSG(pos, msg) SET_PROF_MSG_POS(pos, msg) 80 | #define PF_START(pos) ENTRY_TIME_POS(pos) 81 | #define PF_STOP(pos) EXIT_TIME_POS(pos) 82 | #define PF_KILL(pos) KILL_ENTRY_TIME_POS(pos) 83 | #define PF_PRINT_TICKS REPORT_TIMINGS 84 | #define PF_PRINT REPORT_TIMINGS_SECS 85 | #define PF_EXCLUDE(pos) EXCLUDE_ENTRY(pos) 86 | #define PF_CORRECTION MEASUREREMENT_CORRECTION 87 | #endif 88 | 89 | #define PFIN PF_START 90 | #define PFOUT PF_STOP 91 | 92 | #ifdef DO_TIMINGS 93 | #ifndef DO_TIMINGS_STD 94 | #ifndef DO_TIMINGS_TICKS 95 | #error Define either DO_TIMINGS_STD or DO_TIMINGS_TICKS 96 | #endif 97 | #endif 98 | #endif 99 | 100 | #include 101 | #include 102 | 103 | // =============================== GETTIMEOFDAY ================================ {{{ 104 | #ifdef DO_TIMINGS_STD 105 | #define ENTRY_TIMES_SIZE 8 106 | EXINLINED struct timeval entry_time[ENTRY_TIMES_SIZE]; 107 | EXINLINED bool entry_time_valid[ENTRY_TIMES_SIZE]; 108 | EXINLINED long long total_sum_sec[ENTRY_TIMES_SIZE]; 109 | EXINLINED long long total_sum_usec[ENTRY_TIMES_SIZE]; 110 | EXINLINED long long total_samples[ENTRY_TIMES_SIZE]; 111 | 112 | #define ENTRY_TIME ENTRY_TIME_POS(0) 113 | #define EXIT_TIME EXIT_TIME_POS(0) 114 | #define KILL_ENTRY_TIME KILL_ENTRY_TIME_POS(0) 115 | 116 | #define ENTRY_TIME_POS(position) \ 117 | do {\ 118 | gettimeofday(&entry_time[position], NULL); \ 119 | entry_time_valid[position] = true; \ 120 | } while (0); 121 | 122 | #define EXIT_TIME_POS(position) \ 123 | do {\ 124 | if (entry_time_valid[position]) { \ 125 | entry_time_valid[position] = false; \ 126 | struct timeval exit_time; \ 127 | gettimeofday(&exit_time, NULL); \ 128 | total_sum_sec[position] += (exit_time.tv_sec - entry_time[position].tv_sec); \ 129 | total_sum_usec[position] += (exit_time.tv_usec - entry_time[position].tv_usec); \ 130 | while (total_sum_usec[position] > 1000000) { \ 131 | total_sum_usec[position] -= 1000000; \ 132 | total_sum_sec[position] ++; \ 133 | }; total_samples[position]++; } \ 134 | } while (0); 135 | #define KILL_ENTRY_TIME_POS(position) do {\ 136 | entry_time_valid[position] = false; \ 137 | } while (0); 138 | 139 | #ifndef _MEASUREMENTS_ID_ 140 | #define _MEASUREMENTS_ID_ -1 141 | #endif 142 | 143 | #define REPORT_TIMINGS REPORT_TIMINGS_RANGE(0,ENTRY_TIMES_SIZE) 144 | 145 | #define REPORT_TIMINGS_RANGE(start,end) do {\ 146 | for (int i=start;i 158 | #ifndef SSMP 159 | typedef uint64_t ticks; 160 | 161 | #if defined(__i386__) 162 | EXINLINED ticks getticks(void) { 163 | ticks ret; 164 | 165 | __asm__ __volatile__("rdtsc" : "=A" (ret)); 166 | return ret; 167 | } 168 | #elif defined(__x86_64__) 169 | EXINLINED ticks getticks(void) 170 | { 171 | unsigned hi, lo; 172 | __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 173 | return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 ); 174 | } 175 | #endif 176 | #endif 177 | 178 | #define ENTRY_TIMES_SIZE 16 179 | 180 | enum timings_bool_t { 181 | M_FALSE, M_TRUE 182 | }; 183 | 184 | extern ticks entry_time[ENTRY_TIMES_SIZE]; 185 | extern enum timings_bool_t entry_time_valid[ENTRY_TIMES_SIZE]; 186 | extern ticks total_sum_ticks[ENTRY_TIMES_SIZE]; 187 | extern long long total_samples[ENTRY_TIMES_SIZE]; 188 | extern const char *measurement_msgs[ENTRY_TIMES_SIZE]; 189 | #define MEASUREREMENT_CORRECTION getticks_correction_calc(); 190 | #define SET_PROF_MSG(msg) SET_PROF_MSG_POS(0, msg) 191 | #define ENTRY_TIME ENTRY_TIME_POS(0) 192 | #define EXIT_TIME EXIT_TIME_POS(0) 193 | #define KILL_ENTRY_TIME KILL_ENTRY_TIME_POS(0) 194 | 195 | #define SET_PROF_MSG_POS(pos, msg) \ 196 | measurement_msgs[pos] = msg; 197 | 198 | #define ENTRY_TIME_POS(position) \ 199 | do { \ 200 | entry_time[position] = getticks(); \ 201 | entry_time_valid[position] = M_TRUE; \ 202 | } while (0); 203 | 204 | #define EXIT_TIME_POS(position) \ 205 | do { \ 206 | ticks exit_time = getticks(); \ 207 | if (entry_time_valid[position]) { \ 208 | entry_time_valid[position] = M_FALSE; \ 209 | total_sum_ticks[position] += (exit_time - entry_time[position] - getticks_correction); \ 210 | total_samples[position]++; \ 211 | }} while (0); 212 | 213 | #define KILL_ENTRY_TIME_POS(position) \ 214 | do { \ 215 | entry_time_valid[position] = M_FALSE; \ 216 | } while (0); 217 | 218 | #define EXCLUDE_ENTRY(position) \ 219 | do { \ 220 | total_samples[position] = 0; \ 221 | } while(0); 222 | 223 | #ifndef _MEASUREMENTS_ID_ 224 | #define _MEASUREMENTS_ID_ -1 225 | #endif 226 | 227 | #define REPORT_TIMINGS REPORT_TIMINGS_RANGE(0,ENTRY_TIMES_SIZE) 228 | 229 | #define REPORT_TIMINGS_RANGE(start,end) \ 230 | do { \ 231 | int i; \ 232 | for (i = start; i < end; i++) { \ 233 | if (total_samples[i]) { \ 234 | printf("[%02d]%s:\n", i, measurement_msgs[i]); \ 235 | printf(" samples: %-16llu| ticks: %-16llu| avg ticks: %-16llu\n", \ 236 | total_samples[i], total_sum_ticks[i], total_sum_ticks[i] / total_samples[i]);\ 237 | } \ 238 | } \ 239 | } \ 240 | while (0); 241 | 242 | #define REPORT_TIMINGS_SECS REPORT_TIMINGS_SECS_RANGE(0, ENTRY_TIMES_SIZE) 243 | 244 | #define REPORT_TIMINGS_SECS_RANGE_(start,end) \ 245 | do { \ 246 | int i; \ 247 | for (i = start; i < end; i++) { \ 248 | if (total_samples[i]) { \ 249 | printf("[%02d]%s:\n", i, measurement_msgs[i]); \ 250 | printf(" samples: %-16llu | secs: %-4.10f | avg ticks: %-4.10f\n", \ 251 | total_samples[i], total_sum_ticks[i] / (REF_SPEED_GHZ * 1.e9), \ 252 | (total_sum_ticks[i] / total_samples[i])/ (REF_SPEED_GHZ * 1.e9));\ 253 | } \ 254 | } \ 255 | } \ 256 | while (0); 257 | 258 | #define trunc 259 | 260 | extern void prints_ticks_stats(int start, int end); 261 | #define REPORT_TIMINGS_SECS_RANGE(start,end) \ 262 | prints_ticks_stats(start, end); 263 | 264 | 265 | 266 | // }}} 267 | // ================================== OTHER ================================== {{{ 268 | #else 269 | #define ENTRY_TIME 270 | #define EXIT_TIME 271 | #define KILL_ENTRY_TIME 272 | #define REPORT_TIMINGS 273 | #define REPORT_TIMINGS_RANGE(x,y) 274 | #define ENTRY_TIME_POS(X) 275 | #define EXIT_TIME_POS(X) 276 | #define KILL_ENTRY_TIME_POS(X) 277 | #endif 278 | 279 | #ifdef __cplusplus 280 | } 281 | #endif 282 | 283 | #endif 284 | -------------------------------------------------------------------------------- /include/prand.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: prand.h 3 | * Author: Vasileios Trigonakis 4 | * Description: 5 | * prand.h is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #ifndef _PRAND_H_ 32 | #define _PRAND_H_ 33 | 34 | #include 35 | #include "utils.h" 36 | 37 | #define PRAND_LEN 8192 38 | /* #define PRAND_LEN 65536 */ 39 | /* #define PRAND_LEN 2097152 */ 40 | 41 | typedef uint32_t prand_gen_t; 42 | 43 | static inline prand_gen_t* 44 | prand_new() 45 | { 46 | prand_gen_t* g = (prand_gen_t*) malloc(sizeof(prand_gen_t) * PRAND_LEN); 47 | assert(g != NULL); 48 | 49 | unsigned long* s = seed_rand(); 50 | 51 | int i; 52 | for (i = 0; i < PRAND_LEN; i++) 53 | { 54 | g[i] = (uint32_t) xorshf96(s, s+1, s+2); 55 | } 56 | 57 | free(s); 58 | return g; 59 | } 60 | 61 | static inline prand_gen_t* 62 | prand_new_range(size_t min, size_t max) 63 | { 64 | prand_gen_t* g = (prand_gen_t*) malloc(sizeof(prand_gen_t) * PRAND_LEN); 65 | assert(g != NULL); 66 | 67 | unsigned long* s = seed_rand(); 68 | 69 | int i; 70 | for (i = 0; i < PRAND_LEN; i++) 71 | { 72 | g[i] = (uint32_t) (xorshf96(s, s+1, s+2) % max) + min; 73 | } 74 | 75 | free(s); 76 | return g; 77 | } 78 | 79 | static inline prand_gen_t* 80 | prand_new_range_len(size_t len, size_t min, size_t max) 81 | { 82 | prand_gen_t* g = (prand_gen_t*) malloc(sizeof(prand_gen_t) * (len + 1)); 83 | assert(g != NULL); 84 | 85 | unsigned long* s = seed_rand(); 86 | 87 | int i; 88 | for (i = 0; i <= len; i++) 89 | { 90 | g[i] = (uint32_t) ((xorshf96(s, s+1, s+2) % max) + min); 91 | assert(g[i] != 0); 92 | } 93 | 94 | free(s); 95 | return g; 96 | } 97 | 98 | 99 | static inline prand_gen_t 100 | prand_nxt(const prand_gen_t* g, int* idx) 101 | { 102 | return g[*idx++ & (PRAND_LEN - 1)]; 103 | } 104 | 105 | #define PRAND_GET_NXT(g, idx) \ 106 | g[idx++ & (PRAND_LEN - 1)] 107 | 108 | #define PRAND_GET_NXT_L(g, idx, len) \ 109 | g[idx++ & (len)] 110 | 111 | 112 | #define PRAND_FOR(g, i, key) \ 113 | for (i = 0; i < PRAND_LEN; key = g[i], i++) 114 | 115 | 116 | 117 | 118 | 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *~ 3 | /#run_lf_vs_lb_socket_short.sh# 4 | 5 | -------------------------------------------------------------------------------- /scripts/bins_add_suffix.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -gt 1 ]; 4 | then 5 | suffix=$1; 6 | base_name=$2; 7 | echo "Using suffix: $suffix on pattern: \""$base_name"-..$\""; 8 | 9 | for f in $(ls bin/* | grep $base_name"-..$"); 10 | do 11 | echo "Renaming: $f to $f"_$suffix; 12 | mv $f $f"_"$suffix; 13 | done; 14 | 15 | else 16 | echo "Please provide the: suffix base_pattern"; 17 | echo "Example: $0 aligned lf"; 18 | fi; 19 | -------------------------------------------------------------------------------- /scripts/build_microbench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # list of stms to test 4 | TARGETS="estm tinystm sequential tiny100 tiny10B tiny098" 5 | # list of lock to test 6 | LOCKS="lock spinlock" 7 | # othe list for lockfree 8 | LFS="lockfree" 9 | # current microbench version 10 | MBENCH_VERSION=0.4.1 11 | # where to store binaries 12 | EXPERIMENT_BIN_DIR=../bin 13 | # make or gmake 14 | MAKE="make" 15 | 16 | SRCDIR=../src 17 | BINDIR=../bin 18 | BUILDIR=../build 19 | 20 | for TARGET in $TARGETS 21 | do 22 | printf "\n********************************\n* Building $app with $TARGET...\n********************************\n\n" 23 | ${MAKE} -C .. clean 24 | ${MAKE} -C .. ${TARGET} 25 | mv ${BINDIR}/lf-ll ${EXPERIMENT_BIN_DIR}/ll-${MBENCH_VERSION}-${TARGET} 26 | mv ${BINDIR}/lf-sl ${EXPERIMENT_BIN_DIR}/sl-${MBENCH_VERSION}-${TARGET} 27 | mv ${BINDIR}/lf-ht ${EXPERIMENT_BIN_DIR}/ht-${MBENCH_VERSION}-${TARGET} 28 | mv ${BINDIR}/lf-rt ${EXPERIMENT_BIN_DIR}/rt-${MBENCH_VERSION}-${TARGET} 29 | mv ${BINDIR}/lf-dq ${EXPERIMENT_BIN_DIR}/dq-${MBENCH_VERSION}-${TARGET} 30 | done 31 | for LOCK in $LOCKS 32 | do 33 | printf "\n********************************\n* Building $app with $LOCK...\n********************************\n\n" 34 | ${MAKE} -C .. clean 35 | ${MAKE} -C .. ${LOCK} 36 | mv ${BINDIR}/lb-ll ${EXPERIMENT_BIN_DIR}/ll-${MBENCH_VERSION}-${LOCK} 37 | mv ${BINDIR}/lb-sl ${EXPERIMENT_BIN_DIR}/sl-${MBENCH_VERSION}-${LOCK} 38 | mv ${BINDIR}/lb-ht ${EXPERIMENT_BIN_DIR}/ht-${MBENCH_VERSION}-${LOCK} 39 | done 40 | for LF in $LFS 41 | do 42 | printf "\n********************************\n* Building $app with $LF...\n********************************\n\n" 43 | ${MAKE} -C .. clean 44 | ${MAKE} -C .. ${LF} 45 | mv ${BINDIR}/lf-ll ${EXPERIMENT_BIN_DIR}/ll-${MBENCH_VERSION}-${LF} 46 | mv ${BINDIR}/lf-sl ${EXPERIMENT_BIN_DIR}/sl-${MBENCH_VERSION}-${LF} 47 | mv ${BINDIR}/lf-ht ${EXPERIMENT_BIN_DIR}/ht-${MBENCH_VERSION}-${LF} 48 | done 49 | 50 | ${MAKE} clean 51 | 52 | -------------------------------------------------------------------------------- /scripts/config: -------------------------------------------------------------------------------- 1 | unm=$(uname -n); 2 | 3 | if [ $unm = "parsasrv1.epfl.ch" ]; 4 | then 5 | run_script="./run" 6 | fi; 7 | 8 | if [ $unm = "maglite" ]; 9 | then 10 | max_cores=64; 11 | elif [ $unm = "lpd48core" ]; 12 | then 13 | max_cores=48; 14 | elif [ $unm = "parsasrv1.epfl.ch" ]; 15 | then 16 | max_cores=36; 17 | elif [ $unm = "diassrv8" ]; 18 | then 19 | max_cores=80; 20 | elif [ $unm = "lpdpc34" ]; 21 | then 22 | max_cores=8; 23 | elif [ $unm = "lpdxeon2680" ]; 24 | then 25 | max_cores=40; 26 | else 27 | max_cores=48; 28 | fi; 29 | 30 | 31 | if [ "$cores" = "all" ]; 32 | then 33 | cores=$(seq 2 1 $max_cores); 34 | elif [ "$cores" = "socket" ]; 35 | then 36 | if [ $unm = "maglite" ]; 37 | then 38 | cores=$(seq 8 8 64); 39 | elif [ $unm = "parsasrv1.epfl.ch" ]; 40 | then 41 | cores=$(seq 6 6 36); 42 | elif [ $unm = "diassrv8" ]; 43 | then 44 | cores=$(seq 10 10 80); 45 | elif [ $unm = "lpdpc34" ]; 46 | then 47 | cores=$(seq 2 1 8); 48 | elif [ $unm = "lpdxeon2680" ]; 49 | then 50 | cores=$(seq 10 10 40); 51 | elif [ $unm = "ol-collab1" ]; 52 | then 53 | cores=$(seq 32 32 256); 54 | else 55 | cores=$(seq 6 6 48); 56 | fi; 57 | elif [ "$cores" = "insocket" ]; 58 | then 59 | if [ $unm = "maglite" ]; 60 | then 61 | cores=$(seq 8 8 64); 62 | elif [ $unm = "parsasrv1.epfl.ch" ]; 63 | then 64 | cores=$(seq 6 6 36); 65 | elif [ $unm = "diassrv8" ]; 66 | then 67 | cores="$(seq 2 1 9) $(seq 10 10 80)"; 68 | elif [ $unm = "lpdpc34" ]; 69 | then 70 | cores=$(seq 2 1 8); 71 | elif [ $unm = "lpdxeon2680" ]; 72 | then 73 | cores="$(seq 2 1 9) $(seq 10 10 40)"; 74 | else 75 | cores="2 3 4 5 $(seq 6 6 48)"; 76 | fi; 77 | elif [ "$cores" = "step" ]; 78 | then 79 | if [ $unm = "maglite" ]; 80 | then 81 | cores=$(seq 7 1 10); 82 | elif [ $unm = "parsasrv1.epfl.ch" ]; 83 | then 84 | cores=$(seq 5 1 8); 85 | elif [ $unm = "diassrv8" ]; 86 | then 87 | cores=$(seq 9 1 11); 88 | elif [ $unm = "lpdpc34" ]; 89 | then 90 | cores=$(seq 2 1 8); 91 | else 92 | cores=$(seq 5 1 8); 93 | fi; 94 | elif [ "$cores" = "eights" ]; 95 | then 96 | cores=$(seq 8 8 $max_cores); 97 | elif [ "$cores" = "twelve" ]; 98 | then 99 | cores=$(seq 2 1 12); 100 | fi; 101 | -------------------------------------------------------------------------------- /scripts/create_plots.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $# -gt 0 ]; 4 | then 5 | app_all="$@"; 6 | else 7 | app_all="ll sl ht"; 8 | fi 9 | 10 | dat_folder="./data"; 11 | gp_folder="./gp"; 12 | out_folder="./plots" 13 | gp_template="./scripts/lock-free.gp"; 14 | 15 | update_all="10 20"; 16 | initial_all="1000 10000 20000 50000"; 17 | load_factor_all="1 2 10 100"; 18 | 19 | for update in $update_all 20 | do 21 | echo "* Update: $update"; 22 | for initial in $initial_all 23 | do 24 | echo "** Size: $initial"; 25 | 26 | for app in $app_all 27 | do 28 | printf "*** Application: $app\n"; 29 | if [ "$app" = "ht" ]; 30 | then 31 | 32 | for load_factor in $load_factor_all 33 | do 34 | echo "**** Load factor: $load_factor"; 35 | 36 | dat="$dat_folder/$app.i$initial.u$update.l$load_factor.dat"; 37 | gp="$gp_folder/$app.i$initial.u$update.l$load_factor.gp"; 38 | eps="$out_folder/$app.l$load_factor.u$update.i$initial.eps"; 39 | title="Lock-free $app / Size: $initial / Update: $update / Load factor: $load_factor"; 40 | 41 | cp $gp_template $gp 42 | cat << EOF >> $gp 43 | set title "$title"; 44 | set output "$eps"; 45 | plot \\ 46 | "$dat" using 1:(\$2) title "Througput" ls 2 with lines, \\ 47 | "$dat" using 1:(\$4) axis x1y2 title "Scalability" ls 1 with points 48 | EOF 49 | done; 50 | 51 | else 52 | 53 | dat="$dat_folder/$app.i$initial.u$update.dat"; 54 | gp="$gp_folder/$app.i$initial.u$update.gp"; 55 | eps="$out_folder/$app.u$update.$initial.eps"; 56 | title="Lock-free $app / Size: $initial / Update: $update"; 57 | 58 | cp $gp_template $gp 59 | cat << EOF >> $gp 60 | set title "$title"; 61 | set output "$eps"; 62 | plot \\ 63 | "$dat" using 1:(\$2) title "Througput" ls 2 with lines, \\ 64 | "$dat" using 1:(\$4) axis x1y2 title "Scalability" ls 1 with points 65 | EOF 66 | 67 | fi; 68 | done; 69 | done; 70 | done; 71 | 72 | gnuplot $gp_folder/*.gp; 73 | 74 | -------------------------------------------------------------------------------- /scripts/create_plots_ll_sl_ht.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $# -gt 0 ]; 4 | then 5 | app_all="$@"; 6 | else 7 | app_all="ll sl ht"; 8 | fi 9 | 10 | dat_folder="./data"; 11 | gp_folder="./gp"; 12 | out_folder="./plots" 13 | gp_template="./scripts/lock-free.gp"; 14 | 15 | update_all="0 20 50" 16 | initial_all="1024 16384" 17 | load_factor_all="2 8"; 18 | 19 | for update in $update_all 20 | do 21 | echo "* Update: $update"; 22 | for initial in $initial_all 23 | do 24 | echo "** Size: $initial"; 25 | 26 | for app in $app_all 27 | do 28 | printf "*** Application: $app\n"; 29 | if [ "$app" = "ht" ]; 30 | then 31 | 32 | for load_factor in $load_factor_all 33 | do 34 | echo "**** Load factor: $load_factor"; 35 | 36 | dat="$dat_folder/$app.i$initial.l$load_factor.u$update.dat"; 37 | gp="$gp_folder/$app.i$initial.l$load_factor.u$update.gp"; 38 | eps="$out_folder/$app.l$load_factor.i$initial.u$update.eps"; 39 | title="Lock-free $app / Load factor: $load_factor / Size: $initial / Update: $update"; 40 | 41 | cp $gp_template $gp 42 | cat << EOF >> $gp 43 | set title "$title"; 44 | set output "$eps"; 45 | plot \\ 46 | "$dat" using 1:(\$2) title "lb - Througput" ls 2 with lines, \\ 47 | "$dat" using 1:(\$4) axis x1y2 title "lb - Scalability" ls 1 with points, \\ 48 | "$dat" using 1:(\$5) title "lz - Througput" ls 4 with lines, \\ 49 | "$dat" using 1:(\$7) axis x1y2 title "lz - Scalability" ls 3 with points, \\ 50 | "$dat" using 1:(\$8) title "lf - Througput" ls 6 with lines, \\ 51 | "$dat" using 1:(\$10) axis x1y2 title "lf - Scalability" ls 5 with points 52 | EOF 53 | 54 | gnuplot $gp; 55 | done; 56 | else # not hash table, aka not load_factor 57 | 58 | dat="$dat_folder/$app.i$initial.u$update.dat"; 59 | gp="$gp_folder/$app.i$initial.u$update.gp"; 60 | eps="$out_folder/$app.i$initial.u$update.eps"; 61 | title="Lock-free $app / Size: $initial / Update: $update"; 62 | 63 | cp $gp_template $gp 64 | 65 | 66 | if [ "$app" = "ll" ]; 67 | then 68 | cat << EOF >> $gp 69 | set title "$title"; 70 | set output "$eps"; 71 | plot \\ 72 | "$dat" using 1:(\$2) title "lb - Througput" ls 2 with lines, \\ 73 | "$dat" using 1:(\$4) axis x1y2 title "lb - Scalability" ls 1 with points, \\ 74 | "$dat" using 1:(\$5) title "lz - Througput" ls 4 with lines, \\ 75 | "$dat" using 1:(\$7) axis x1y2 title "lz - Scalability" ls 3 with points, \\ 76 | "$dat" using 1:(\$8) title "lf - Througput" ls 6 with lines, \\ 77 | "$dat" using 1:(\$10) axis x1y2 title "lf - Scalability" ls 5 with points 78 | EOF 79 | 80 | else # sl 81 | 82 | cat << EOF >> $gp 83 | set title "$title"; 84 | set output "$eps"; 85 | plot \\ 86 | "$dat" using 1:(\$2) title "lb - Througput" ls 2 with lines, \\ 87 | "$dat" using 1:(\$4) axis x1y2 title "lb - Scalability" ls 1 with points, \\ 88 | "$dat" using 1:(\$5) title "lf - Througput" ls 6 with lines, \\ 89 | "$dat" using 1:(\$7) axis x1y2 title "lf - Scalability" ls 5 with points 90 | EOF 91 | fi; 92 | 93 | gnuplot $gp; 94 | fi; 95 | done; 96 | done; 97 | done; 98 | 99 | 100 | -------------------------------------------------------------------------------- /scripts/events_all: -------------------------------------------------------------------------------- 1 | cache-references,cache-misses,L1-dcache-loads,L1-dcache-load-misses,L1-dcache-stores,L1-dcache-store-misses,L1-dcache-prefetches,L1-dcache-prefetch-misses,L1-icache-loads,L1-icache-load-misses,L1-icache-prefetches,L1-icache-prefetch-misses,LLC-loads,LLC-load-misses,LLC-stores,LLC-store-misses,LLC-prefetches,LLC-prefetch-misses -------------------------------------------------------------------------------- /scripts/lock-free.gp: -------------------------------------------------------------------------------- 1 | set xlabel "Number of threads" 2 | set ylabel "Throughput (Ops/s)" 3 | set y2label "Scalability" 4 | 5 | #nomirror - no tics on the right and top 6 | #scale - the size of the tics 7 | set xtics 6 nomirror scale 2 8 | set ytics auto nomirror scale 2 9 | set y2tics auto nomirror scale 2 10 | 11 | #remove top and right borders 12 | set border 3 back 13 | #add grid 14 | set style line 12 lc rgb '#808080' lt 2 lw 1 15 | set grid back ls 12 16 | 17 | set xrange [0:] 18 | set yrange [0:] 19 | 20 | #the size of the graph 21 | set size 2.0, 1.0 22 | 23 | #some nice line colors 24 | #lc: line color; lt: line type (1 - conitnuous); pt: point type 25 | #ps: point size; lw: line width 26 | set style line 1 lc rgb '#0060ad' lt 1 pt 2 ps 1.5 lw 5 27 | set style line 2 lc rgb '#dd181f' lt 1 pt 5 ps 2 lw 5 28 | set style line 3 lc rgb '#8b1a0e' pt 1 ps 1.5 lt 1 lw 5 29 | set style line 4 lc rgb '#5e9c36' pt 6 ps 2 lt 2 lw 5 30 | set style line 5 lc rgb '#663399' lt 1 pt 3 ps 1.5 lw 5 31 | set style line 8 lc rgb '#299fff' lt 1 pt 8 ps 2 lw 5 32 | set style line 9 lc rgb '#ff299f' lt 1 pt 9 ps 2 lw 5 33 | set style line 6 lc rgb '#cc6600' lt 4 pt 4 ps 2 lw 5 34 | set style line 7 lc rgb '#cccc00' lt 1 pt 7 ps 2 lw 5 35 | 36 | #move the legend to a custom position (can also be moved to absolute coordinates) 37 | set key outside 38 | 39 | set terminal postscript color "Helvetica" 24 eps enhanced 40 | 41 | #set term tikz standalone color solid size 5in,3in 42 | #set output "test.tex" 43 | 44 | #for more details on latex, see http://www.gnuplotting.org/introduction/output-terminals/ 45 | #set term epslatex #size 3.5, 2.62 #color colortext 46 | #size can also be in cm: set terminal epslatex size 8.89cm,6.65cm color colortext 47 | #set output "test.eps" 48 | 49 | # plot \ 50 | # "stress_rw_TTAS.txt" using 1:2 title "TTAS" ls 1 with linespoints, \ 51 | # "stress_rw_ARRAY.txt" using 1:2 title "Array" ls 2 with linespoints, \ 52 | # "stress_rw_MCS.txt" using 1:2 title "MCS" ls 3 with linespoints, \ 53 | # "stress_rw_HTICKET.txt" using 1:2 title "HTicket" ls 8 with linespoints, \ 54 | # "stress_rw_SPINLOCK.txt" using 1:2 title "Spinlock" ls 9 with linespoints, \ 55 | # "stress_rw_HCLH.txt" using 1:2 title "HCLH" ls 4 with linespoints, \ 56 | # "stress_rw_CLH.txt" using 1:2 title "CLH" ls 5 with linespoints, \ 57 | # "stress_rw_MUTEX.txt" using 1:2 title "Mutex" ls 7 with linespoints, \ 58 | # "stress_rw_TICKET.txt" using 1:2 title "Ticket" ls 6 with linespoints 59 | 60 | -------------------------------------------------------------------------------- /scripts/lock_exec: -------------------------------------------------------------------------------- 1 | # trap ctrl-c and call ctrl_c() 2 | trap 'rm /dev/shm/lock_exec_$(whoami) 2> /dev/null; echo "\n** cleaned-up"; exit 1' INT 3 | 4 | lock=$(ls /dev/shm/lock_exec_* 2> /dev/null); 5 | if [ "$lock" != "" ]; 6 | then 7 | echo "$(ls /dev/shm/lock_exec_*) exists"; 8 | # exit 1; 9 | fi; 10 | 11 | touch "/dev/shm/lock_exec_$(whoami)" 2> /dev/null; 12 | -------------------------------------------------------------------------------- /scripts/make_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $(uname -n) = "maglite" ]; 4 | then 5 | MAKE="/home/trigonak/sw/make/make"; 6 | else 7 | MAKE=make 8 | fi; 9 | 10 | $MAKE lockfree; 11 | $MAKE ticket GRANULARITY=GLOBAL_LOCK; 12 | ./scripts/bins_add_suffix.sh gl_ticket lb 13 | $MAKE ticket 14 | ./scripts/bins_add_suffix.sh ticket lb 15 | $MAKE hticket GRANULARITY=GLOBAL_LOCK; 16 | ./scripts/bins_add_suffix.sh gl_hticket lb 17 | $MAKE clh GRANULARITY=GLOBAL_LOCK; 18 | ./scripts/bins_add_suffix.sh gl_clh lb 19 | 20 | -------------------------------------------------------------------------------- /scripts/make_all_locks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $(uname -n) = "maglite" ]; 4 | then 5 | MAKE="/home/trigonak/sw/make/make"; 6 | else 7 | MAKE=make 8 | fi; 9 | 10 | lock=mutex 11 | $MAKE $lock GRANULARITY=GLOBAL_LOCK; 12 | ./scripts/bins_add_suffix.sh gl_$lock lb 13 | $MAKE $lock 14 | ./scripts/bins_add_suffix.sh $lock lb 15 | 16 | lock=spin 17 | $MAKE $lock GRANULARITY=GLOBAL_LOCK; 18 | ./scripts/bins_add_suffix.sh gl_$lock lb 19 | $MAKE $lock 20 | ./scripts/bins_add_suffix.sh $lock lb 21 | 22 | lock=tas 23 | $MAKE $lock GRANULARITY=GLOBAL_LOCK; 24 | ./scripts/bins_add_suffix.sh gl_$lock lb 25 | $MAKE $lock 26 | ./scripts/bins_add_suffix.sh $lock lb 27 | 28 | lock=ticket 29 | $MAKE $lock GRANULARITY=GLOBAL_LOCK; 30 | ./scripts/bins_add_suffix.sh gl_$lock lb 31 | $MAKE $lock 32 | ./scripts/bins_add_suffix.sh $lock lb 33 | 34 | 35 | if [ $(uname -n) = "lpd48core" ] || [ $(uname -n) = "diassrv8" ]; 36 | then 37 | lock=hticket 38 | $MAKE $lock GRANULARITY=GLOBAL_LOCK; 39 | ./scripts/bins_add_suffix.sh gl_$lock lb 40 | 41 | lock=clh 42 | $MAKE $lock GRANULARITY=GLOBAL_LOCK; 43 | ./scripts/bins_add_suffix.sh gl_$lock lb 44 | fi; 45 | -------------------------------------------------------------------------------- /scripts/make_dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ssmem=https://github.com/LPD-EPFL/ssmem 4 | ssmem_folder=./external/ssmem; 5 | sspfd=https://github.com/trigonak/sspfd 6 | sspfd_folder=./external/sspfd; 7 | 8 | if [ ! -d $ssmem_folder ]; 9 | then 10 | git clone $ssmem $ssmem_folder 11 | fi; 12 | 13 | if [ ! -d $sspfd_folder ]; 14 | then 15 | git clone $sspfd $sspfd_folder 16 | fi; 17 | 18 | mkdir external/lib &> /dev/null; 19 | 20 | cd $ssmem_folder; 21 | git pull; 22 | make libssmem.a; 23 | cp libssmem.a ../lib; 24 | cp include/ssmem.h ../include; 25 | cd -; 26 | 27 | cd $sspfd_folder; 28 | git pull; 29 | make libsspfd.a; 30 | cp libsspfd.a ../lib; 31 | cp sspfd.h ../include; 32 | cd -; 33 | 34 | -------------------------------------------------------------------------------- /scripts/o.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | reps=$1; 4 | shift; 5 | 6 | for r in $(seq 1 1 $reps); 7 | do 8 | printf "%-5d : " $r 9 | res=$(./hyht -b1 -i81920 -n80 -d1000 | grep "garbage:"); 10 | echo $res; 11 | done; 12 | 13 | 14 | -------------------------------------------------------------------------------- /scripts/perf.list: -------------------------------------------------------------------------------- 1 | 2 | List of pre-defined events (to be used in -e): 3 | cpu-cycles OR cycles [Hardware event] 4 | instructions [Hardware event] 5 | cache-references [Hardware event] 6 | cache-misses [Hardware event] 7 | branch-instructions OR branches [Hardware event] 8 | branch-misses [Hardware event] 9 | bus-cycles [Hardware event] 10 | stalled-cycles-frontend OR idle-cycles-frontend [Hardware event] 11 | stalled-cycles-backend OR idle-cycles-backend [Hardware event] 12 | ref-cycles [Hardware event] 13 | 14 | cpu-clock [Software event] 15 | task-clock [Software event] 16 | page-faults OR faults [Software event] 17 | context-switches OR cs [Software event] 18 | cpu-migrations OR migrations [Software event] 19 | minor-faults [Software event] 20 | major-faults [Software event] 21 | alignment-faults [Software event] 22 | emulation-faults [Software event] 23 | 24 | L1-dcache-loads [Hardware cache event] 25 | L1-dcache-load-misses [Hardware cache event] 26 | L1-dcache-stores [Hardware cache event] 27 | L1-dcache-store-misses [Hardware cache event] 28 | L1-dcache-prefetches [Hardware cache event] 29 | L1-dcache-prefetch-misses [Hardware cache event] 30 | L1-icache-loads [Hardware cache event] 31 | L1-icache-load-misses [Hardware cache event] 32 | L1-icache-prefetches [Hardware cache event] 33 | L1-icache-prefetch-misses [Hardware cache event] 34 | LLC-loads [Hardware cache event] 35 | LLC-load-misses [Hardware cache event] 36 | LLC-stores [Hardware cache event] 37 | LLC-store-misses [Hardware cache event] 38 | LLC-prefetches [Hardware cache event] 39 | LLC-prefetch-misses [Hardware cache event] 40 | dTLB-loads [Hardware cache event] 41 | dTLB-load-misses [Hardware cache event] 42 | dTLB-stores [Hardware cache event] 43 | dTLB-store-misses [Hardware cache event] 44 | dTLB-prefetches [Hardware cache event] 45 | dTLB-prefetch-misses [Hardware cache event] 46 | iTLB-loads [Hardware cache event] 47 | iTLB-load-misses [Hardware cache event] 48 | branch-loads [Hardware cache event] 49 | branch-load-misses [Hardware cache event] 50 | node-loads [Hardware cache event] 51 | node-load-misses [Hardware cache event] 52 | node-stores [Hardware cache event] 53 | node-store-misses [Hardware cache event] 54 | node-prefetches [Hardware cache event] 55 | node-prefetch-misses [Hardware cache event] 56 | 57 | rNNN [Raw hardware event descriptor] 58 | cpu/t1=v1[,t2=v2,t3 ...]/modifier [Raw hardware event descriptor] 59 | (see 'man perf-list' on how to encode it) 60 | 61 | mem:[:access] [Hardware breakpoint] 62 | 63 | -------------------------------------------------------------------------------- /scripts/repeat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | reps=$1; 4 | shift; 5 | 6 | for r in $(seq 1 1 $reps); 7 | do 8 | printf "%-5d : " $r 9 | ./$@ | grep txs; 10 | done; 11 | -------------------------------------------------------------------------------- /scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ `uname` = "SunOS" ] 3 | then 4 | for n in {1..64} 5 | do 6 | echo "./hclh " $1 " " $2 " " $4 " " ${n} 7 | ./latency_hclh $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_hclh.txt 8 | ./throughput_hclh $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_hclh.txt 9 | done 10 | 11 | for n in {1..64} 12 | do 13 | echo "./ttas " $1 " " $2 " " $4 " " ${n} 14 | ./latency_ttas $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_ttas.txt 15 | ./throughput_ttas $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_ttas.txt 16 | done 17 | 18 | for n in {1..64} 19 | do 20 | echo "./mcs " $1 " " $2 " " $4 " " ${n} 21 | ./latency_mcs $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_mcs.txt 22 | ./throughput_mcs $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_mcs.txt 23 | done 24 | 25 | for n in {1..64} 26 | do 27 | echo "./array " $1 " " $2 " " $4 " " ${n} 28 | ./latency_array $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_array.txt 29 | ./throughput_array $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_array.txt 30 | done 31 | 32 | for n in {1..64} 33 | do 34 | echo "./ticket " $1 " " $2 " " $4 " " ${n} 35 | ./latency_ticket $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_ticket.txt 36 | ./throughput_ticket $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_ticket.txt 37 | done 38 | 39 | for n in {1..64} 40 | do 41 | echo "./mutex " $1 " " $2 " " $4 " " ${n} 42 | ./latency_mutex $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_mutex.txt 43 | ./throughput_mutex $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_mutex.txt 44 | done 45 | 46 | for n in {1..64} 47 | do 48 | echo "./hticket " $1 " " $2 " " $4 " " ${n} 49 | ./latency_hticket $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_hticket.txt 50 | ./throughput_hticket $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_hticket.txt 51 | done 52 | 53 | else 54 | # Other UNIX (Linux, etc.) specific stuff 55 | for n in {1..48} 56 | do 57 | echo "./hclh " $1 " " $2 " " $4 " " ${n} 58 | ./latency_hclh $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_hclh.txt 59 | ./throughput_hclh $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_hclh.txt 60 | done 61 | 62 | for n in {1..48} 63 | do 64 | echo "./ttas " $1 " " $2 " " $4 " " ${n} 65 | ./latency_ttas $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_ttas.txt 66 | ./throughput_ttas $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_ttas.txt 67 | done 68 | 69 | for n in {1..48} 70 | do 71 | echo "./mcs " $1 " " $2 " " $4 " " ${n} 72 | ./latency_mcs $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_mcs.txt 73 | ./throughput_mcs $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_mcs.txt 74 | done 75 | 76 | for n in {1..48} 77 | do 78 | echo "./array " $1 " " $2 " " $4 " " ${n} 79 | ./latency_array $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_array.txt 80 | ./throughput_array $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_array.txt 81 | done 82 | 83 | for n in {1..48} 84 | do 85 | echo "./ticket " $1 " " $2 " " $4 " " ${n} 86 | ./latency_ticket $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_ticket.txt 87 | ./throughput_ticket $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_ticket.txt 88 | done 89 | 90 | for n in {1..48} 91 | do 92 | echo "./mutex " $1 " " $2 " " $4 " " ${n} 93 | ./latency_mutex $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_mutex.txt 94 | ./throughput_mutex $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_mutex.txt 95 | done 96 | 97 | for n in {1..48} 98 | do 99 | echo "./hticket " $1 " " $2 " " $4 " " ${n} 100 | ./latency_hticket $1 ${n} $2 $3 $4 $5 $6 $7 >> results/latency_hticket.txt 101 | ./throughput_hticket $1 ${n} $2 $3 $4 $5 $6 $7 >> results/throughput_hticket.txt 102 | done 103 | fi 104 | 105 | echo "./sequential " $1 " " $2 " " 1 106 | ./sequential $1 1 $2 $3 $4 $5 $6 $7 $8 >> results/sequential.txt 107 | 108 | if [ `uname` = "SunOS" ] 109 | then 110 | cd plot_sparc 111 | else 112 | cd plot 113 | fi 114 | ./put_acq.sh 115 | ./put_rel.sh 116 | ./put_opt.sh 117 | ./put_tot.sh 118 | ./get_acq.sh 119 | ./get_rel.sh 120 | ./get_opt.sh 121 | ./get_tot.sh 122 | ./remove_acq.sh 123 | ./remove_rel.sh 124 | ./remove_opt.sh 125 | ./remove_tot.sh 126 | ./tput.sh 127 | cp tput.eps "../throughput_"$1"_"$2"_"$3"_"$4"_"$5"_"$6"_"$7".eps" 128 | ./speedup.sh 129 | cp speedup.eps "../speedup_"$1"_"$2"_"$3"_"$4"_"$5"_"$6"_"$7".eps" 130 | cd .. 131 | 132 | cd tex 133 | if [ `uname` = "SunOS" ] 134 | then 135 | /home/guerel/local/texlive/2012/bin/sparc-solaris/latex latency_sparc.tex 136 | /home/guerel/local/texlive/2012/bin/sparc-solaris/dvips latency_sparc.dvi 137 | cp latency_sparc.ps "../latency_"$1"_"$2"_"$3"_"$4"_"$5"_"$6"_"$7".ps" 138 | cd .. 139 | rm results/*.txt plot_sparc/*.eps tex/*.ps 140 | else 141 | latex latency.tex 142 | dvipdf latency.dvi 143 | cp latency.pdf "../latency_"$1"_"$2"_"$3"_"$4"_"$5"_"$6"_"$7".pdf" 144 | cd .. 145 | rm results/*.txt plot/*.eps tex/*.pdf 146 | fi 147 | -------------------------------------------------------------------------------- /scripts/run_2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | app1=$1; 5 | app2=$2; 6 | shift; shift; 7 | bu=$1; 8 | shift; shift; 9 | P=$@ 10 | 11 | 12 | printf "%-20s%-20s\n" $app1 $app2 $app3 13 | 14 | 15 | # cores="2 6 36 48" 16 | cores="32 36 48" 17 | 18 | for n in $cores 19 | do 20 | echo " -- $n threads"; 21 | Pc="$bu $n $P" 22 | 23 | ./$app1 $Pc; 24 | ./$app2 $Pc; 25 | 26 | # P="-d1000 -n$n -l$acc -c1 -w1 -a0 -p0"; 27 | # v1=$(./$app1 $P | awk '// { print $5 }'); 28 | # v2=$(./$app2 $P | awk '// { print $5 }'); 29 | # v3=0 # $(./$app3 $P | awk '// { print $5 }'); 30 | 31 | # if [ $((v1)) -gt $((v2)) ]; 32 | # then 33 | # if [ $((v1)) -gt $((v3)) ]; 34 | # then 35 | # max=$((v1)); 36 | # else 37 | # max=$((v3)); 38 | # fi; 39 | # else 40 | # if [ $((v2)) -gt $((v3)) ]; 41 | # then 42 | # max=$((v2)); 43 | # else 44 | # max=$((v3)); 45 | # fi; 46 | # fi; 47 | 48 | # printf "%-10d%-10.2f" $((v1)) $(echo "$v1/$max" | bc -l) 49 | # printf "%-10d%-10.2f" $((v2)) $(echo "$v2/$max" | bc -l) 50 | # printf "%-10d%10.2f\n" $((v3)) $(echo "$v3/$max" | bc -l) 51 | 52 | done; 53 | 54 | -------------------------------------------------------------------------------- /scripts/run_all_hts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | initials="1024 8192 65536"; 4 | updates="0 1 10 20"; 5 | duration=1000; 6 | 7 | 8 | for i in $initials; 9 | do 10 | r=$((2*$i)); 11 | for u in $updates; 12 | do 13 | params="-i$i -u$u -b$i -r$r -d$duration"; 14 | echo "## PARAMS: $params"; 15 | ./scripts/scalability8.sh socket $(find . -name "clht*" -type f -executable -print) $params; 16 | done; 17 | done; 18 | -------------------------------------------------------------------------------- /scripts/run_all_hts_real.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | initials="16 128 1024 8192 65536"; 4 | updates="0 1 10 20 50 100"; 5 | duration=1000; 6 | 7 | 8 | for i in $initials; 9 | do 10 | r=$((2*$i)); 11 | for u in $updates; 12 | do 13 | params="-i$i -u$u -b$i -r$r -d$duration"; 14 | echo "## PARAMS: $params"; 15 | ./scripts/scalability4.sh socket hyht hyht_lock_ins lfht_dup lfht $params; 16 | done; 17 | done; 18 | -------------------------------------------------------------------------------- /scripts/run_avg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./run_rep.sh $@ | gawk '// { one=$1; sum+=$2; i++ } END { print one, sum/i }'; 4 | 5 | 6 | -------------------------------------------------------------------------------- /scripts/run_compare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pattern=$1; 4 | shift; 5 | 6 | num_bins=$(ls -1 bin/*$pattern* | wc -l); 7 | echo "# of executables found: $num_bins"; 8 | 9 | if [ $num_bins -gt 10 ]; 10 | then 11 | echo "** Cannot execute more than 9 benchmarks at a time"; 12 | exit -1; 13 | fi; 14 | 15 | if [ $num_bins -eq 0 ]; 16 | then 17 | echo "** No executables found"; 18 | exit -1; 19 | fi; 20 | 21 | bins=$(ls bin/*$pattern*); 22 | 23 | ./scripts/scalability$num_bins.sh socket $bins $@; 24 | -------------------------------------------------------------------------------- /scripts/run_compare_ht.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out_file="data/compare_ht_"$(date | gawk '// {print $2"_"$3}')".dat"; 4 | echo "Output file: $out_file"; 5 | printf "" > $out_file; 6 | 7 | initials="64 512 2048 8192"; 8 | updates="0 10 100"; 9 | load_factors="4 8" 10 | 11 | 12 | for i in $initials 13 | do 14 | r=$((2*$i)); 15 | for u in $updates 16 | do 17 | for l in $load_factors 18 | do 19 | settings="-i$i -r$r -u$u -l$l"; 20 | echo "## $settings" | tee -a $out_file; 21 | ./scripts/scalability5.sh socket "./bin/lf-ht" "./bin/lb-ht_ticket" "./bin/lb-ht_gl_ticket" "./bin/lb-ht_ticket -x2" "./bin/lb-ht_gl_ticket -x2" $settings | tee -a $out_file; 22 | done; 23 | done; 24 | done; 25 | -------------------------------------------------------------------------------- /scripts/run_compare_hy_pre.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out_file="data/compare_hy_pre_"$(date | gawk '// {print $2"_"$3}')".dat"; 4 | echo "Output file: $out_file"; 5 | printf "" > $out_file; 6 | 7 | initials="512 2048 8192"; 8 | updates="1 10 100"; 9 | load_factors="2 4" 10 | 11 | 12 | for i in $initials 13 | do 14 | r=$((2*$i)); 15 | for u in $updates 16 | do 17 | for l in $load_factors 18 | do 19 | settings="-i$i -r$r -u$u -l$l"; 20 | echo "## $settings" | tee -a $out_file; 21 | ./scripts/scalability2.sh socket "./throughput_ticket_no_pre" "./throughput_ticket" $settings | tee -a $out_file; 22 | done; 23 | done; 24 | done; 25 | -------------------------------------------------------------------------------- /scripts/run_compare_lf_hy_noise.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out_file="data/compare_lf_hy_noise_"$(date | gawk '// {print $2"_"$3}')".dat"; 4 | echo "Output file: $out_file"; 5 | printf "" > $out_file; 6 | 7 | initials="64 512 2048 8192"; 8 | updates="1 10 100"; 9 | load_factors="2 4" 10 | 11 | 12 | for i in $initials 13 | do 14 | r=$((2*$i)); 15 | for u in $updates 16 | do 17 | for l in $load_factors 18 | do 19 | settings="-i$i -r$r -u$u -l$l"; 20 | echo "## $settings" | tee -a $out_file; 21 | ./scripts/scalability2.sh socket "./lf-ht" "./throughput_ticket" $settings | tee -a $out_file; 22 | done; 23 | done; 24 | done; 25 | -------------------------------------------------------------------------------- /scripts/run_compare_locks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | p="lb-ll -u10"; 4 | echo "## settings: $p"; 5 | ./scripts/run_compare.sh $p 6 | p="lb-ll -u10 -i128 -r256"; 7 | echo "## settings: $p"; 8 | ./scripts/run_compare.sh $p 9 | 10 | p="lb-ll -u10 -x2"; 11 | echo "## settings: $p"; 12 | ./scripts/run_compare.sh $p 13 | p="lb-ll -u10 -i128 -r256 -x2"; 14 | echo "## settings: $p"; 15 | ./scripts/run_compare.sh $p 16 | 17 | p="lb-sl -u10"; 18 | echo "## settings: $p"; 19 | ./scripts/run_compare.sh $p 20 | p="lb-sl -u10 -i128 -r256"; 21 | echo "## settings: $p"; 22 | ./scripts/run_compare.sh $p 23 | 24 | p="lb-ht -u10 -l4"; 25 | echo "## settings: $p"; 26 | ./scripts/run_compare.sh $p 27 | p="lb-ht -u10 -l4 -i128 -r256"; 28 | echo "## settings: $p"; 29 | ./scripts/run_compare.sh $p 30 | 31 | 32 | p="lb-ht -u10 -l4 -x2" 33 | echo "## settings: $p"; 34 | ./scripts/run_compare.sh $p 35 | p="lb-ht -u10 -l4 -i128 -r256 -x2"; 36 | echo "## settings: $p"; 37 | ./scripts/run_compare.sh $p 38 | 39 | -------------------------------------------------------------------------------- /scripts/run_ht_short_buckets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## global -------------------------------------------------------------------------------------------------------- 4 | out_folder="./data"; 5 | cores="all"; 6 | duration="2000"; 7 | 8 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 | ## update ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | update=10; 11 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 12 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13 | 14 | ## settings -------------------------------------------------------------------------------------------------------- 15 | initial=1000; 16 | range=$((2*$initial)); 17 | 18 | load_factor=1; 19 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 20 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 21 | load_factor=2; 22 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 23 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 24 | 25 | ## settings -------------------------------------------------------------------------------------------------------- 26 | initial=10000; 27 | range=$((2*$initial)); 28 | 29 | load_factor=1; 30 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 31 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 32 | load_factor=2; 33 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 34 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 35 | 36 | ## settings -------------------------------------------------------------------------------------------------------- 37 | initial=20000; 38 | range=$((2*$initial)); 39 | 40 | load_factor=1; 41 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 42 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 43 | load_factor=2; 44 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 45 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 46 | 47 | ## settings -------------------------------------------------------------------------------------------------------- 48 | initial=50000; 49 | range=$((2*$initial)); 50 | 51 | load_factor=1; 52 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 53 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 54 | load_factor=2; 55 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 56 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 57 | 58 | 59 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 60 | ## update ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 61 | update=20; 62 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 63 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 64 | 65 | ## settings -------------------------------------------------------------------------------------------------------- 66 | initial=1000; 67 | range=$((2*$initial)); 68 | 69 | load_factor=1; 70 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 71 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 72 | load_factor=2; 73 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 74 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 75 | 76 | ## settings -------------------------------------------------------------------------------------------------------- 77 | initial=10000; 78 | range=$((2*$initial)); 79 | 80 | load_factor=1; 81 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 82 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 83 | load_factor=2; 84 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 85 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 86 | 87 | ## settings -------------------------------------------------------------------------------------------------------- 88 | initial=20000; 89 | range=$((2*$initial)); 90 | 91 | load_factor=1; 92 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 93 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 94 | load_factor=2; 95 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 96 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 97 | 98 | ## settings -------------------------------------------------------------------------------------------------------- 99 | initial=50000; 100 | range=$((2*$initial)); 101 | 102 | load_factor=1; 103 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 104 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 105 | load_factor=2; 106 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 107 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 108 | 109 | 110 | -------------------------------------------------------------------------------- /scripts/run_lf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## global -------------------------------------------------------------------------------------------------------- 4 | out_folder="./data"; 5 | cores="all"; 6 | duration="2000"; 7 | 8 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 | ## update ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | update=10; 11 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 12 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13 | 14 | ## settings -------------------------------------------------------------------------------------------------------- 15 | initial=1000; 16 | range=$((2*$initial)); 17 | 18 | out="$out_folder/ll.i$initial.u$update.dat"; 19 | ./scripts/scalability.sh "$cores" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 20 | out="$out_folder/sl.i$initial.u$update.dat"; 21 | ./scripts/scalability.sh "$cores" ./bin/lf-sl -d$duration -i$initial -r$range -u$update | tee $out; 22 | load_factor=10; 23 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 24 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 25 | load_factor=100; 26 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 27 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 28 | 29 | ## settings -------------------------------------------------------------------------------------------------------- 30 | initial=10000; 31 | range=$((2*$initial)); 32 | 33 | out="$out_folder/ll.i$initial.u$update.dat"; 34 | ./scripts/scalability.sh "$cores" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 35 | out="$out_folder/sl.i$initial.u$update.dat"; 36 | ./scripts/scalability.sh "$cores" ./bin/lf-sl -d$duration -i$initial -r$range -u$update | tee $out; 37 | load_factor=10; 38 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 39 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 40 | load_factor=100; 41 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 42 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 43 | 44 | ## settings -------------------------------------------------------------------------------------------------------- 45 | initial=20000; 46 | range=$((2*$initial)); 47 | 48 | out="$out_folder/ll.i$initial.u$update.dat"; 49 | ./scripts/scalability.sh "$cores" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 50 | out="$out_folder/sl.i$initial.u$update.dat"; 51 | ./scripts/scalability.sh "$cores" ./bin/lf-sl -d$duration -i$initial -r$range -u$update | tee $out; 52 | load_factor=10; 53 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 54 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 55 | load_factor=100; 56 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 57 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 58 | 59 | ## settings -------------------------------------------------------------------------------------------------------- 60 | initial=50000; 61 | range=$((2*$initial)); 62 | 63 | out="$out_folder/ll.i$initial.u$update.dat"; 64 | ./scripts/scalability.sh "$cores" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 65 | out="$out_folder/sl.i$initial.u$update.dat"; 66 | ./scripts/scalability.sh "$cores" ./bin/lf-sl -d$duration -i$initial -r$range -u$update | tee $out; 67 | load_factor=10; 68 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 69 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 70 | load_factor=100; 71 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 72 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 73 | 74 | 75 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 76 | ## update ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 77 | update=20; 78 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 80 | 81 | ## settings -------------------------------------------------------------------------------------------------------- 82 | initial=1000; 83 | range=$((2*$initial)); 84 | 85 | out="$out_folder/ll.i$initial.u$update.dat"; 86 | ./scripts/scalability.sh "$cores" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 87 | out="$out_folder/sl.i$initial.u$update.dat"; 88 | ./scripts/scalability.sh "$cores" ./bin/lf-sl -d$duration -i$initial -r$range -u$update | tee $out; 89 | load_factor=10; 90 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 91 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 92 | load_factor=100; 93 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 94 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 95 | 96 | ## settings -------------------------------------------------------------------------------------------------------- 97 | initial=10000; 98 | range=$((2*$initial)); 99 | 100 | out="$out_folder/ll.i$initial.u$update.dat"; 101 | ./scripts/scalability.sh "$cores" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 102 | out="$out_folder/sl.i$initial.u$update.dat"; 103 | ./scripts/scalability.sh "$cores" ./bin/lf-sl -d$duration -i$initial -r$range -u$update | tee $out; 104 | load_factor=10; 105 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 106 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 107 | load_factor=100; 108 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 109 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 110 | 111 | ## settings -------------------------------------------------------------------------------------------------------- 112 | initial=20000; 113 | range=$((2*$initial)); 114 | 115 | out="$out_folder/ll.i$initial.u$update.dat"; 116 | ./scripts/scalability.sh "$cores" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 117 | out="$out_folder/sl.i$initial.u$update.dat"; 118 | ./scripts/scalability.sh "$cores" ./bin/lf-sl -d$duration -i$initial -r$range -u$update | tee $out; 119 | load_factor=10; 120 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 121 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 122 | load_factor=100; 123 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 124 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 125 | 126 | ## settings -------------------------------------------------------------------------------------------------------- 127 | initial=50000; 128 | range=$((2*$initial)); 129 | 130 | out="$out_folder/ll.i$initial.u$update.dat"; 131 | ./scripts/scalability.sh "$cores" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 132 | out="$out_folder/sl.i$initial.u$update.dat"; 133 | ./scripts/scalability.sh "$cores" ./bin/lf-sl -d$duration -i$initial -r$range -u$update | tee $out; 134 | load_factor=10; 135 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 136 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 137 | load_factor=100; 138 | out="$out_folder/ht.i$initial.u$update.l$load_factor.dat"; 139 | ./scripts/scalability.sh "$cores" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 140 | 141 | 142 | -------------------------------------------------------------------------------- /scripts/run_lf_ll.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | initials="8 16 32 64 128 256 512 1024 2048 4096 8192"; 5 | updates="1 10 20 50 100"; 6 | 7 | for i in $initials 8 | do 9 | for u in $updates 10 | do 11 | r=$((2*$i)); 12 | settings="-i$i -r$r -u$u"; 13 | echo "## $settings"; 14 | ./scripts/scalability2.sh socket ./bin/lf-ll ./bin/lf-ll_padded $settings 15 | done; 16 | done; 17 | -------------------------------------------------------------------------------- /scripts/run_lf_socket.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out_file="data/lf_socket_"$(date | gawk '// {print $2"_"$3}')".dat"; 4 | echo "Output file: $out_file"; 5 | printf "" > $out_file; 6 | 7 | initials="8 16 32 64 128 256 512 1024 2048 4096 8192"; 8 | updates="0 1 10 20 50 100"; 9 | 10 | for i in $initials 11 | do 12 | for u in $updates 13 | do 14 | r=$((2*$i)); 15 | settings="-i$i -r$r -u$u"; 16 | echo "## $settings" | tee -a $out_file; 17 | ./scripts/scalability3.sh socket ./bin/lf-ll ./bin/lf-sl ./bin/lf-ht $settings -l4 | tee -a $out_file; 18 | done; 19 | done; 20 | -------------------------------------------------------------------------------- /scripts/run_lf_socket_short.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out_file="data/lf_socket_short_"$(date | awk '// {print $2"_"$3}')".dat"; 4 | echo "Output file: $out_file"; 5 | printf "" > $out_file; 6 | 7 | initials="8 64 512 1024 2048 8192"; 8 | updates="0 1 10 100"; 9 | 10 | for i in $initials 11 | do 12 | for u in $updates 13 | do 14 | r=$((2*$i)); 15 | settings="-i$i -r$r -u$u"; 16 | echo "## $settings" | tee -a $out_file; 17 | ./scripts/scalability3.sh socket ./bin/lf-ll ./bin/lf-sl ./bin/lf-ht $settings -l4 | tee -a $out_file; 18 | done; 19 | done; 20 | -------------------------------------------------------------------------------- /scripts/run_lf_step.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out_file="data/lf_step_"$(date | awk '// {print $2"_"$3}')".dat"; 4 | echo "Output file: $out_file"; 5 | printf "" > $out_file; 6 | 7 | initials="8 16 32 64 128 256 512 1024 2048 4096 8192"; 8 | updates="0 1 10 20 50 100"; 9 | 10 | for i in $initials 11 | do 12 | for u in $updates 13 | do 14 | r=$((2*$i)); 15 | settings="-i$i -r$r -u$u"; 16 | echo "## $settings" | tee -a $out_file; 17 | ./scripts/scalability3.sh "9 10 11 12" ./bin/lf-ll ./bin/lf-sl ./bin/lf-ht $settings -l4 | tee -a $out_file; 18 | done; 19 | done; 20 | -------------------------------------------------------------------------------- /scripts/run_lf_vs_lb_all_short.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out_file="data/lf_vs_lb_all_short_"$(date | gawk '// {print $2"_"$3}')".dat"; 4 | echo "Output file: $out_file"; 5 | printf "" > $out_file; 6 | 7 | initials="8 32 128 512 2048 8192"; 8 | updates="0 1 10 100"; 9 | 10 | lb_ll_gl="./bin/lb-ll_gl_ticket -x2"; 11 | if [ $(uname -n) = "diassrv8" ]; 12 | then 13 | lb_ll_gl="./bin/lb-ll_gl_hticket -x2"; 14 | elif [ $(uname -n) = "lpd48core" ]; 15 | then 16 | lb_ll_gl="./bin/lb-ll_gl_clh -x2"; 17 | fi; 18 | 19 | for i in $initials 20 | do 21 | for u in $updates 22 | do 23 | r=$((2*$i)); 24 | settings="-i$i -r$r -u$u"; 25 | echo "## $settings" | tee -a $out_file; 26 | ./scripts/scalability8.sh all ./bin/lf-ll "./bin/lb-ll_ticket -x2" "$lb_ll_gl" ./bin/lf-sl ./bin/lb-sl_ticket ./bin/lf-ht "./bin/lb-ht_ticket -x2" "./bin/lb-ht_gl_ticket -x2" $settings -l4 | tee -a $out_file; 27 | done; 28 | done; 29 | -------------------------------------------------------------------------------- /scripts/run_lf_vs_lb_socket_short.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | out_file="data/lf_vs_lb_socket_short_"$(date | gawk '// {print $2"_"$3}')".dat"; 4 | echo "Output file: $out_file"; 5 | printf "" > $out_file; 6 | 7 | initials="8 64 512 1024 2048 8192"; 8 | updates="0 1 10 100"; 9 | 10 | lb_ll_gl="./bin/lb-ll_gl_ticket -x2"; 11 | if [ $(uname -n) = "diassrv8" ]; 12 | then 13 | lb_ll_gl="./bin/lb-ll_gl_hticket -x2"; 14 | elif [ $(uname -n) = "lpd48core" ]; 15 | then 16 | lb_ll_gl="./bin/lb-ll_gl_clh -x2"; 17 | fi; 18 | 19 | for i in $initials 20 | do 21 | for u in $updates 22 | do 23 | r=$((2*$i)); 24 | settings="-i$i -r$r -u$u"; 25 | echo "## $settings" | tee -a $out_file; 26 | ./scripts/scalability8.sh socket ./bin/lf-ll "./bin/lb-ll_ticket -x2" "$lb_ll_gl" ./bin/lf-sl ./bin/lb-sl_ticket ./bin/lf-ht "./bin/lb-ht_ticket -x2" "./bin/lb-ht_gl_ticket -x2" $settings -l4 | tee -a $out_file; 27 | done; 28 | done; 29 | -------------------------------------------------------------------------------- /scripts/run_ll_sl_ht.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## global -------------------------------------------------------------------------------------------------------- 4 | out_folder="./data"; 5 | cores="all"; 6 | duration="1000"; 7 | 8 | 9 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | ## executables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 | lls='./bin/lb-ll "./bin/lb-ll -x2" ./bin/lf-ll' # -x2 does not work 12 | sls='./bin/lb-sl ./bin/lf-sl' 13 | hts='./bin/lb-ht "./bin/lb-ht -x2" ./bin/lf-ht' # -x2 does not work 14 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 15 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 16 | 17 | ## settings -------------------------------------------------------------------------------------------------------- 18 | initials="1024 16384"; 19 | updates="0 20 50"; 20 | load_factors="2 8" 21 | 22 | for initial in $initials; 23 | do 24 | echo "* -i$initial"; 25 | 26 | range=$((2*$initial)); 27 | 28 | for update in $updates; 29 | do 30 | echo "** -u$update"; 31 | 32 | out="$out_folder/ll.i$initial.u$update.dat"; 33 | ./scripts/scalability3.sh "$cores" ./bin/lb-ll "./bin/lb-ll -x2" ./bin/lf-ll -d$duration -i$initial -r$range -u$update | tee $out; 34 | # out="$out_folder/sl.i$initial.u$update.dat"; 35 | # ./scripts/scalability2.sh "$cores" $sls -d$duration -i$initial -r$range -u$update | tee $out; 36 | 37 | for load_factor in $load_factors; 38 | do 39 | echo "*** -l$load_factor"; 40 | out="$out_folder/ht.i$initial.l$load_factor.u$update.dat"; 41 | ./scripts/scalability3.sh "$cores" ./bin/lb-ht "./bin/lb-ht -x2" ./bin/lf-ht -d$duration -i$initial -r$range -u$update -l$load_factor | tee $out; 42 | done 43 | done 44 | done 45 | 46 | -------------------------------------------------------------------------------- /scripts/run_mp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for n in {3..48..3} 4 | do 5 | echo "./mp " $1 " " $2 " " $4 " " ${n} 6 | ./throughput_mp $1 ${n} $2 $3 $4 $5 $6 $7 $8 >> results/throughput_mp.txt 7 | done 8 | 9 | echo "./sequential " $1 " " $2 " " $4 " " 1 10 | ./sequential $1 1 $2 $3 $4 $5 $6 $7 $8 >> results/sequential.txt 11 | 12 | cd plot 13 | ./tput_mp.sh 14 | cp tput_mp.eps "../throughput_mp_"$1"_"$2"_"$3"_"$4"_"$5"_"$6"_"$7"_"$8".eps" 15 | ./speedup_mp.sh 16 | cp speedup_mp.eps "../speedup_mp_"$1"_"$2"_"$3"_"$4"_"$5"_"$6"_"$7"_"$8".eps" 17 | cd .. 18 | 19 | rm results/*.txt plot/*.eps -------------------------------------------------------------------------------- /scripts/run_normal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # lat="_lat"; 4 | 5 | e1="hyht$lat"; 6 | e2="hyht_linked$lat"; 7 | e3="lfht_res$lat"; 8 | 9 | es="$e1 $e2 $e3"; 10 | 11 | for e in $es; 12 | do 13 | printf " ---------------------------------------------------------------------------------------------------------------------------|| %-30s \n" $e 14 | ./$e $@; 15 | done; -------------------------------------------------------------------------------- /scripts/run_rep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | reps=$1; 4 | shift; 5 | 6 | if [ $(uname -n) = "smal1.sics.se" ]; 7 | then 8 | run=./run 9 | elif [ $(uname -n) = "parsasrv1.epfl.ch" ]; 10 | then 11 | run=./run 12 | fi 13 | 14 | 15 | execute=$@; 16 | 17 | for rep in $(seq 1 1 $reps) 18 | do 19 | $run ./$execute 20 | done; 21 | 22 | 23 | -------------------------------------------------------------------------------- /scripts/run_spinlocks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## global -------------------------------------------------------------------------------------------------------- 4 | dat_folder="./data"; 5 | cores="all"; 6 | duration="1000"; 7 | 8 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9 | ## update ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 10 | update=10; 11 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 12 | ## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13 | 14 | ## settings -------------------------------------------------------------------------------------------------------- 15 | app_all="lb-ll lb-sl lb-ht"; 16 | update_all="10 20"; 17 | initial_all="1000 10000 20000 50000"; 18 | load_factor_all="1 2 10"; 19 | 20 | for update in $update_all 21 | do 22 | echo "* Update: $update"; 23 | for initial in $initial_all 24 | do 25 | echo "** Size: $initial"; 26 | range=$((2*$initial)); 27 | 28 | for app in $app_all 29 | do 30 | printf "*** Application: $app\n"; 31 | if [ "$app" = "ht" ]; 32 | then 33 | 34 | for load_factor in $load_factor_all 35 | do 36 | echo "**** Load factor: $load_factor"; 37 | dat="$dat_folder/$app.i$initial.u$update.l$load_factor.dat"; 38 | ./scripts/scalability.sh "$cores" ./bin/$app -d$duration -i$initial -r$range -u$update | tee $dat; 39 | done; 40 | 41 | else 42 | 43 | dat="$dat_folder/$app.i$initial.u$update.dat"; 44 | ./scripts/scalability.sh "$cores" ./bin/$app -d$duration -i$initial -r$range -u$update | tee $dat; 45 | fi; 46 | done; 47 | done; 48 | done; -------------------------------------------------------------------------------- /scripts/run_throughput.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | read -p "Enter the max number of cores : " NUM_CORES 4 | read -p "Enter suffix for the data file: " SUFFIX 5 | 6 | repetitions=2; 7 | duration=1000; 8 | buckets="512 12"; 9 | rw="0.2'0.8"; 10 | 11 | fill_rate=0.5; 12 | payload_size="64"; 13 | num_elements="24 96"; 14 | 15 | executables=$(ls throughput_*); 16 | cores=$(seq 1 1 $NUM_CORES); 17 | 18 | 19 | if [ $(uname -n) = "lpd48core" ]; 20 | then 21 | platform="opteron"; 22 | elif [ $(uname -n) = "diascld9" ]; 23 | then 24 | platform="opteron2"; 25 | elif [ $(uname -n) = "diassrv8" ]; 26 | then 27 | platform="xeon"; 28 | elif [ $(uname -n) = "diascld19" ]; 29 | then 30 | platform="xeon2"; 31 | elif [ $(uname -n) = "smal1.sics.se" ]; 32 | then 33 | platform="tilepro"; 34 | elif [ $(uname -n) = "parsasrv1.epfl.ch" ]; 35 | then 36 | platform="tilera" 37 | run=./run; 38 | elif [ $(uname -n) = "maglite" ]; 39 | then 40 | platform="niagara" 41 | fi 42 | 43 | for bu in $buckets 44 | do 45 | for ne in $num_elements 46 | do 47 | num_elems=$(($ne*$bu)); 48 | 49 | for ps in $payload_size 50 | do 51 | for r in $rw 52 | do 53 | u=$(echo $r | cut -d"'" -f1); 54 | g=$(echo $r | cut -d"'" -f2); 55 | echo "#buckets: $bu / num elems: $num_elems / ps: $ps / update: $u / get: $g"; 56 | 57 | out_dat="data/throughput."$platform".b"$bu"_e"$num_elems"_ps"$ps"_u"$u"_diff_locks"$SUFFIX".dat" 58 | 59 | printf "# " | tee $out_dat; 60 | for f in $(ls throughput_*) 61 | do 62 | prim=$(echo $f | cut -d'_' -f2); 63 | printf "%-11s" $prim | tee -a $out_dat; 64 | done; 65 | echo "" | tee -a $out_dat; 66 | 67 | for c in $cores 68 | do 69 | printf "%-3u" $c | tee -a $out_dat; 70 | for ex in $executables 71 | do 72 | p="$bu $c $num_elems $fill_rate $ps $duration $u $g"; 73 | ./run_avg.sh $repetitions ./$ex $p | gawk '// { printf "%-11d", $2 }' | tee -a $out_dat; 74 | done; 75 | echo "" | tee -a $out_dat; 76 | done; 77 | done; 78 | done; 79 | done; 80 | done; 81 | -------------------------------------------------------------------------------- /scripts/scalability.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog=$1; 10 | shift; 11 | params="$@"; 12 | 13 | 14 | echo "#cores throughput %linear scalability" 15 | 16 | printf "%-8d" 1; 17 | thr1=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 18 | printf "%-12d" $thr1; 19 | printf "%-8.2f" 100.00; 20 | printf "%-8d\n" 1; 21 | 22 | for c in $cores 23 | do 24 | if [ $c -eq 1 ] 25 | then 26 | continue; 27 | fi; 28 | 29 | printf "%-8d" $c; 30 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 31 | printf "%-12d" $thr; 32 | scl=$(echo "$thr/$thr1" | bc -l); 33 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 34 | printf "%-8.2f" $linear_p; 35 | printf "%-8.2f\n" $scl; 36 | 37 | done; 38 | 39 | source scripts/unlock_exec; 40 | -------------------------------------------------------------------------------- /scripts/scalability10.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1="$1"; 10 | shift; 11 | prog2="$1"; 12 | shift; 13 | prog3="$1"; 14 | shift; 15 | prog4="$1"; 16 | shift; 17 | prog5="$1"; 18 | shift; 19 | prog6="$1"; 20 | shift; 21 | prog7="$1"; 22 | shift; 23 | prog8="$1"; 24 | shift; 25 | prog9="$1"; 26 | shift; 27 | prog10="$1"; 28 | shift; 29 | params="$@"; 30 | 31 | 32 | printf "# %-25s%-25s%-25s%-25s%-25s%-25s%-25s%-25s%-25s%-25s\n" "$prog1" "$prog2" "$prog3" "$prog4" "$prog5" "$prog6" "$prog7" "$prog8" "$prog9" "$prog10"; 33 | echo "#cor throughput %linea scalb throughput %linea scalb throughput %linea scalb throughput %linea scalb throughput %linea scalb throughput %linea scalb throughput %linea scalb throughput %linea scalb throughput %linea scalb throughput %linea scalb"; 34 | 35 | prog=$prog1; 36 | 37 | printf "%-6d" 1; 38 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 39 | printf "%-11d" $thr1a; 40 | printf "%-7.2f" 100.00; 41 | printf "%-7d" 1; 42 | 43 | prog=$prog2; 44 | 45 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 46 | printf "%-11d" $thr1b; 47 | printf "%-7.2f" 100.00; 48 | printf "%-7d" 1; 49 | 50 | prog=$prog3; 51 | 52 | thr1c=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 53 | printf "%-11d" $thr1c; 54 | printf "%-7.2f" 100.00; 55 | printf "%-7d" 1; 56 | 57 | prog=$prog4; 58 | 59 | thr1d=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 60 | printf "%-11d" $thr1d; 61 | printf "%-7.2f" 100.00; 62 | printf "%-7d" 1; 63 | 64 | prog=$prog5; 65 | 66 | thr1e=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 67 | printf "%-11d" $thr1e; 68 | printf "%-7.2f" 100.00; 69 | printf "%-7d" 1; 70 | 71 | prog=$prog6; 72 | 73 | thr1f=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 74 | printf "%-11d" $thr1f; 75 | printf "%-7.2f" 100.00; 76 | printf "%-7d" 1; 77 | 78 | prog=$prog7; 79 | 80 | thr1g=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 81 | printf "%-11d" $thr1g; 82 | printf "%-7.2f" 100.00; 83 | printf "%-7d" 1; 84 | 85 | prog=$prog8; 86 | 87 | thr1h=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 88 | printf "%-11d" $thr1h; 89 | printf "%-7.2f" 100.00; 90 | printf "%-7d" 1; 91 | 92 | prog=$prog9; 93 | 94 | thr1i=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 95 | printf "%-11d" $thr1i; 96 | printf "%-7.2f" 100.00; 97 | printf "%-7d" 1; 98 | 99 | prog=$prog10; 100 | 101 | thr1j=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 102 | printf "%-11d" $thr1j; 103 | printf "%-7.2f" 100.00; 104 | printf "%-6d\n" 1; 105 | 106 | 107 | for c in $cores 108 | do 109 | if [ $c -eq 1 ] 110 | then 111 | continue; 112 | fi; 113 | 114 | printf "%-6d" $c; 115 | 116 | prog=$prog1; 117 | thr1=$thr1a; 118 | 119 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 120 | printf "%-11d" $thr; 121 | scl=$(echo "$thr/$thr1" | bc -l); 122 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 123 | printf "%-7.2f" $linear_p; 124 | printf "%-7.2f" $scl; 125 | 126 | prog=$prog2; 127 | thr1=$thr1b; 128 | 129 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 130 | printf "%-11d" $thr; 131 | scl=$(echo "$thr/$thr1" | bc -l); 132 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 133 | printf "%-7.2f" $linear_p; 134 | printf "%-7.2f" $scl; 135 | 136 | prog=$prog3; 137 | thr1=$thr1c; 138 | 139 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 140 | printf "%-11d" $thr; 141 | scl=$(echo "$thr/$thr1" | bc -l); 142 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 143 | printf "%-7.2f" $linear_p; 144 | printf "%-7.2f" $scl; 145 | 146 | prog=$prog4; 147 | thr1=$thr1d; 148 | 149 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 150 | printf "%-11d" $thr; 151 | scl=$(echo "$thr/$thr1" | bc -l); 152 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 153 | printf "%-7.2f" $linear_p; 154 | printf "%-7.2f" $scl; 155 | 156 | prog=$prog5; 157 | thr1=$thr1e; 158 | 159 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 160 | printf "%-11d" $thr; 161 | scl=$(echo "$thr/$thr1" | bc -l); 162 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 163 | printf "%-7.2f" $linear_p; 164 | printf "%-7.2f" $scl; 165 | 166 | prog=$prog6; 167 | thr1=$thr1f; 168 | 169 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 170 | printf "%-11d" $thr; 171 | scl=$(echo "$thr/$thr1" | bc -l); 172 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 173 | printf "%-7.2f" $linear_p; 174 | printf "%-7.2f" $scl; 175 | 176 | prog=$prog7; 177 | thr1=$thr1g; 178 | 179 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 180 | printf "%-11d" $thr; 181 | scl=$(echo "$thr/$thr1" | bc -l); 182 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 183 | printf "%-7.2f" $linear_p; 184 | printf "%-7.2f" $scl; 185 | 186 | prog=$prog8; 187 | thr1=$thr1h; 188 | 189 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 190 | printf "%-11d" $thr; 191 | scl=$(echo "$thr/$thr1" | bc -l); 192 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 193 | printf "%-7.2f" $linear_p; 194 | printf "%-7.2f" $scl; 195 | 196 | prog=$prog9; 197 | thr1=$thr1i; 198 | 199 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 200 | printf "%-11d" $thr; 201 | scl=$(echo "$thr/$thr1" | bc -l); 202 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 203 | printf "%-7.2f" $linear_p; 204 | printf "%-7.2f" $scl; 205 | 206 | prog=$prog10; 207 | thr1=$thr1j; 208 | 209 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 210 | printf "%-11d" $thr; 211 | scl=$(echo "$thr/$thr1" | bc -l); 212 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 213 | printf "%-7.2f" $linear_p; 214 | printf "%-6.2f\n" $scl; 215 | 216 | 217 | done; 218 | 219 | source scripts/unlock_exec; 220 | -------------------------------------------------------------------------------- /scripts/scalability2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1=$1; 10 | shift; 11 | prog2=$1; 12 | shift; 13 | params="$@"; 14 | 15 | 16 | echo "# $prog1 $prog2" 17 | echo "#cores throughput %linear scalability throughput %linear scalability" 18 | 19 | prog=$prog1; 20 | 21 | printf "%-8d" 1; 22 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 23 | printf "%-12d" $thr1a; 24 | printf "%-8.2f" 100.00; 25 | printf "%-12d" 1; 26 | 27 | prog=$prog2; 28 | 29 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 30 | printf "%-12d" $thr1b; 31 | printf "%-8.2f" 100.00; 32 | printf "%-8d\n" 1; 33 | 34 | for c in $cores 35 | do 36 | if [ $c -eq 1 ] 37 | then 38 | continue; 39 | fi; 40 | 41 | printf "%-8d" $c; 42 | 43 | prog=$prog1; 44 | thr1=$thr1a; 45 | 46 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 47 | printf "%-12d" $thr; 48 | scl=$(echo "$thr/$thr1" | bc -l); 49 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 50 | printf "%-8.2f" $linear_p; 51 | printf "%-12.2f" $scl; 52 | 53 | prog=$prog2; 54 | thr1=$thr1b; 55 | 56 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 57 | printf "%-12d" $thr; 58 | scl=$(echo "$thr/$thr1" | bc -l); 59 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 60 | printf "%-8.2f" $linear_p; 61 | printf "%-8.2f\n" $scl; 62 | 63 | 64 | done; 65 | 66 | source scripts/unlock_exec; 67 | -------------------------------------------------------------------------------- /scripts/scalability3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1="$1"; 10 | shift; 11 | prog2="$1"; 12 | shift; 13 | prog3="$1"; 14 | shift; 15 | params="$@"; 16 | 17 | 18 | printf "# %-32s%-32s%-32s\n" "$prog1" "$prog2" "$prog3"; 19 | echo "#cores throughput %linear scalability throughput %linear scalability throughput %linear scalability"; 20 | 21 | prog=$prog1; 22 | 23 | printf "%-8d" 1; 24 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 25 | printf "%-12d" $thr1a; 26 | printf "%-8.2f" 100.00; 27 | printf "%-12d" 1; 28 | 29 | prog=$prog2; 30 | 31 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 32 | printf "%-12d" $thr1b; 33 | printf "%-8.2f" 100.00; 34 | printf "%-12d" 1; 35 | 36 | prog=$prog3; 37 | 38 | thr1c=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 39 | printf "%-12d" $thr1c; 40 | printf "%-8.2f" 100.00; 41 | printf "%-8d\n" 1; 42 | 43 | 44 | for c in $cores 45 | do 46 | if [ $c -eq 1 ] 47 | then 48 | continue; 49 | fi; 50 | 51 | printf "%-8d" $c; 52 | 53 | prog=$prog1; 54 | thr1=$thr1a; 55 | 56 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 57 | printf "%-12d" $thr; 58 | scl=$(echo "$thr/$thr1" | bc -l); 59 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 60 | printf "%-8.2f" $linear_p; 61 | printf "%-12.2f" $scl; 62 | 63 | prog=$prog2; 64 | thr1=$thr1b; 65 | 66 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 67 | printf "%-12d" $thr; 68 | scl=$(echo "$thr/$thr1" | bc -l); 69 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 70 | printf "%-8.2f" $linear_p; 71 | printf "%-12.2f" $scl; 72 | 73 | prog=$prog3; 74 | thr1=$thr1c; 75 | 76 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 77 | printf "%-12d" $thr; 78 | scl=$(echo "$thr/$thr1" | bc -l); 79 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 80 | printf "%-8.2f" $linear_p; 81 | printf "%-8.2f\n" $scl; 82 | 83 | 84 | done; 85 | 86 | source scripts/unlock_exec; 87 | -------------------------------------------------------------------------------- /scripts/scalability4.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1="$1"; 10 | shift; 11 | prog2="$1"; 12 | shift; 13 | prog3="$1"; 14 | shift; 15 | prog4="$1"; 16 | shift; 17 | params="$@"; 18 | 19 | 20 | printf "# %-32s%-32s%-32s%-32s\n" "$prog1" "$prog2" "$prog3" "$prog4"; 21 | echo "#cores throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability"; 22 | 23 | prog=$prog1; 24 | 25 | printf "%-8d" 1; 26 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 27 | printf "%-12d" $thr1a; 28 | printf "%-8.2f" 100.00; 29 | printf "%-12d" 1; 30 | 31 | prog=$prog2; 32 | 33 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 34 | printf "%-12d" $thr1b; 35 | printf "%-8.2f" 100.00; 36 | printf "%-12d" 1; 37 | 38 | prog=$prog3; 39 | 40 | thr1c=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 41 | printf "%-12d" $thr1c; 42 | printf "%-8.2f" 100.00; 43 | printf "%-12d" 1; 44 | 45 | prog=$prog4; 46 | 47 | thr1d=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 48 | printf "%-12d" $thr1d; 49 | printf "%-8.2f" 100.00; 50 | printf "%-8d\n" 1; 51 | 52 | 53 | for c in $cores 54 | do 55 | if [ $c -eq 1 ] 56 | then 57 | continue; 58 | fi; 59 | 60 | printf "%-8d" $c; 61 | 62 | prog=$prog1; 63 | thr1=$thr1a; 64 | 65 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 66 | printf "%-12d" $thr; 67 | scl=$(echo "$thr/$thr1" | bc -l); 68 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 69 | printf "%-8.2f" $linear_p; 70 | printf "%-12.2f" $scl; 71 | 72 | prog=$prog2; 73 | thr1=$thr1b; 74 | 75 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 76 | printf "%-12d" $thr; 77 | scl=$(echo "$thr/$thr1" | bc -l); 78 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 79 | printf "%-8.2f" $linear_p; 80 | printf "%-12.2f" $scl; 81 | 82 | prog=$prog3; 83 | thr1=$thr1c; 84 | 85 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 86 | printf "%-12d" $thr; 87 | scl=$(echo "$thr/$thr1" | bc -l); 88 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 89 | printf "%-8.2f" $linear_p; 90 | printf "%-12.2f" $scl; 91 | 92 | prog=$prog4; 93 | thr1=$thr1d; 94 | 95 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 96 | printf "%-12d" $thr; 97 | scl=$(echo "$thr/$thr1" | bc -l); 98 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 99 | printf "%-8.2f" $linear_p; 100 | printf "%-8.2f\n" $scl; 101 | 102 | done; 103 | 104 | source scripts/unlock_exec; 105 | -------------------------------------------------------------------------------- /scripts/scalability5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1="$1"; 10 | shift; 11 | prog2="$1"; 12 | shift; 13 | prog3="$1"; 14 | shift; 15 | prog4="$1"; 16 | shift; 17 | prog5="$1"; 18 | shift; 19 | params="$@"; 20 | 21 | 22 | printf "# %-32s%-32s%-32s%-32s%-32s\n" "$prog1" "$prog2" "$prog3" "$prog4" "$prog5"; 23 | echo "#cores throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability"; 24 | 25 | prog=$prog1; 26 | 27 | printf "%-8d" 1; 28 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 29 | printf "%-12d" $thr1a; 30 | printf "%-8.2f" 100.00; 31 | printf "%-12d" 1; 32 | 33 | prog=$prog2; 34 | 35 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 36 | printf "%-12d" $thr1b; 37 | printf "%-8.2f" 100.00; 38 | printf "%-12d" 1; 39 | 40 | prog=$prog3; 41 | 42 | thr1c=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 43 | printf "%-12d" $thr1c; 44 | printf "%-8.2f" 100.00; 45 | printf "%-12d" 1; 46 | 47 | prog=$prog4; 48 | 49 | thr1d=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 50 | printf "%-12d" $thr1d; 51 | printf "%-8.2f" 100.00; 52 | printf "%-12d" 1; 53 | 54 | prog=$prog5; 55 | 56 | thr1e=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 57 | printf "%-12d" $thr1e; 58 | printf "%-8.2f" 100.00; 59 | printf "%-8d\n" 1; 60 | 61 | 62 | for c in $cores 63 | do 64 | if [ $c -eq 1 ] 65 | then 66 | continue; 67 | fi; 68 | 69 | printf "%-8d" $c; 70 | 71 | prog=$prog1; 72 | thr1=$thr1a; 73 | 74 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 75 | printf "%-12d" $thr; 76 | scl=$(echo "$thr/$thr1" | bc -l); 77 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 78 | printf "%-8.2f" $linear_p; 79 | printf "%-12.2f" $scl; 80 | 81 | prog=$prog2; 82 | thr1=$thr1b; 83 | 84 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 85 | printf "%-12d" $thr; 86 | scl=$(echo "$thr/$thr1" | bc -l); 87 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 88 | printf "%-8.2f" $linear_p; 89 | printf "%-12.2f" $scl; 90 | 91 | prog=$prog3; 92 | thr1=$thr1c; 93 | 94 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 95 | printf "%-12d" $thr; 96 | scl=$(echo "$thr/$thr1" | bc -l); 97 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 98 | printf "%-8.2f" $linear_p; 99 | printf "%-12.2f" $scl; 100 | 101 | prog=$prog4; 102 | thr1=$thr1d; 103 | 104 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 105 | printf "%-12d" $thr; 106 | scl=$(echo "$thr/$thr1" | bc -l); 107 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 108 | printf "%-8.2f" $linear_p; 109 | printf "%-12.2f" $scl; 110 | 111 | prog=$prog5; 112 | thr1=$thr1e; 113 | 114 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 115 | printf "%-12d" $thr; 116 | scl=$(echo "$thr/$thr1" | bc -l); 117 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 118 | printf "%-8.2f" $linear_p; 119 | printf "%-8.2f\n" $scl; 120 | 121 | 122 | done; 123 | 124 | source scripts/unlock_exec; 125 | -------------------------------------------------------------------------------- /scripts/scalability6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1="$1"; 10 | shift; 11 | prog2="$1"; 12 | shift; 13 | prog3="$1"; 14 | shift; 15 | prog4="$1"; 16 | shift; 17 | prog5="$1"; 18 | shift; 19 | prog6="$1"; 20 | shift; 21 | params="$@"; 22 | 23 | 24 | printf "# %-32s%-32s%-32s%-32s%-32s%-32s\n" "$prog1" "$prog2" "$prog3" "$prog4" "$prog5" "$prog6"; 25 | echo "#cores throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability"; 26 | 27 | prog=$prog1; 28 | 29 | printf "%-8d" 1; 30 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 31 | printf "%-12d" $thr1a; 32 | printf "%-8.2f" 100.00; 33 | printf "%-12d" 1; 34 | 35 | prog=$prog2; 36 | 37 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 38 | printf "%-12d" $thr1b; 39 | printf "%-8.2f" 100.00; 40 | printf "%-12d" 1; 41 | 42 | prog=$prog3; 43 | 44 | thr1c=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 45 | printf "%-12d" $thr1c; 46 | printf "%-8.2f" 100.00; 47 | printf "%-12d" 1; 48 | 49 | prog=$prog4; 50 | 51 | thr1d=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 52 | printf "%-12d" $thr1d; 53 | printf "%-8.2f" 100.00; 54 | printf "%-12d" 1; 55 | 56 | prog=$prog5; 57 | 58 | thr1e=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 59 | printf "%-12d" $thr1e; 60 | printf "%-8.2f" 100.00; 61 | printf "%-12d" 1; 62 | 63 | prog=$prog6; 64 | 65 | thr1f=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 66 | printf "%-12d" $thr1f; 67 | printf "%-8.2f" 100.00; 68 | printf "%-8d\n" 1; 69 | 70 | 71 | for c in $cores 72 | do 73 | if [ $c -eq 1 ] 74 | then 75 | continue; 76 | fi; 77 | 78 | printf "%-8d" $c; 79 | 80 | prog=$prog1; 81 | thr1=$thr1a; 82 | 83 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 84 | printf "%-12d" $thr; 85 | scl=$(echo "$thr/$thr1" | bc -l); 86 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 87 | printf "%-8.2f" $linear_p; 88 | printf "%-12.2f" $scl; 89 | 90 | prog=$prog2; 91 | thr1=$thr1b; 92 | 93 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 94 | printf "%-12d" $thr; 95 | scl=$(echo "$thr/$thr1" | bc -l); 96 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 97 | printf "%-8.2f" $linear_p; 98 | printf "%-12.2f" $scl; 99 | 100 | prog=$prog3; 101 | thr1=$thr1c; 102 | 103 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 104 | printf "%-12d" $thr; 105 | scl=$(echo "$thr/$thr1" | bc -l); 106 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 107 | printf "%-8.2f" $linear_p; 108 | printf "%-12.2f" $scl; 109 | 110 | prog=$prog4; 111 | thr1=$thr1d; 112 | 113 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 114 | printf "%-12d" $thr; 115 | scl=$(echo "$thr/$thr1" | bc -l); 116 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 117 | printf "%-8.2f" $linear_p; 118 | printf "%-12.2f" $scl; 119 | 120 | prog=$prog5; 121 | thr1=$thr1e; 122 | 123 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 124 | printf "%-12d" $thr; 125 | scl=$(echo "$thr/$thr1" | bc -l); 126 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 127 | printf "%-8.2f" $linear_p; 128 | printf "%-12.2f" $scl; 129 | 130 | prog=$prog6; 131 | thr1=$thr1f; 132 | 133 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 134 | printf "%-12d" $thr; 135 | scl=$(echo "$thr/$thr1" | bc -l); 136 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 137 | printf "%-8.2f" $linear_p; 138 | printf "%-8.2f\n" $scl; 139 | 140 | 141 | done; 142 | 143 | source scripts/unlock_exec; 144 | -------------------------------------------------------------------------------- /scripts/scalability7.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1="$1"; 10 | shift; 11 | prog2="$1"; 12 | shift; 13 | prog3="$1"; 14 | shift; 15 | prog4="$1"; 16 | shift; 17 | prog5="$1"; 18 | shift; 19 | prog6="$1"; 20 | shift; 21 | prog7="$1"; 22 | shift; 23 | params="$@"; 24 | 25 | 26 | printf "# %-32s%-32s%-32s%-32s%-32s%-32s%-32s\n" "$prog1" "$prog2" "$prog3" "$prog4" "$prog5" "$prog6" "$prog7"; 27 | echo "#cores throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability"; 28 | 29 | prog=$prog1; 30 | 31 | printf "%-8d" 1; 32 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 33 | printf "%-12d" $thr1a; 34 | printf "%-8.2f" 100.00; 35 | printf "%-12d" 1; 36 | 37 | prog=$prog2; 38 | 39 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 40 | printf "%-12d" $thr1b; 41 | printf "%-8.2f" 100.00; 42 | printf "%-12d" 1; 43 | 44 | prog=$prog3; 45 | 46 | thr1c=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 47 | printf "%-12d" $thr1c; 48 | printf "%-8.2f" 100.00; 49 | printf "%-12d" 1; 50 | 51 | prog=$prog4; 52 | 53 | thr1d=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 54 | printf "%-12d" $thr1d; 55 | printf "%-8.2f" 100.00; 56 | printf "%-12d" 1; 57 | 58 | prog=$prog5; 59 | 60 | thr1e=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 61 | printf "%-12d" $thr1e; 62 | printf "%-8.2f" 100.00; 63 | printf "%-12d" 1; 64 | 65 | prog=$prog6; 66 | 67 | thr1f=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 68 | printf "%-12d" $thr1f; 69 | printf "%-8.2f" 100.00; 70 | printf "%-12d" 1; 71 | 72 | prog=$prog7; 73 | 74 | thr1g=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 75 | printf "%-12d" $thr1g; 76 | printf "%-8.2f" 100.00; 77 | printf "%-8d\n" 1; 78 | 79 | 80 | for c in $cores 81 | do 82 | if [ $c -eq 1 ] 83 | then 84 | continue; 85 | fi; 86 | 87 | printf "%-8d" $c; 88 | 89 | prog=$prog1; 90 | thr1=$thr1a; 91 | 92 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 93 | printf "%-12d" $thr; 94 | scl=$(echo "$thr/$thr1" | bc -l); 95 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 96 | printf "%-8.2f" $linear_p; 97 | printf "%-12.2f" $scl; 98 | 99 | prog=$prog2; 100 | thr1=$thr1b; 101 | 102 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 103 | printf "%-12d" $thr; 104 | scl=$(echo "$thr/$thr1" | bc -l); 105 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 106 | printf "%-8.2f" $linear_p; 107 | printf "%-12.2f" $scl; 108 | 109 | prog=$prog3; 110 | thr1=$thr1c; 111 | 112 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 113 | printf "%-12d" $thr; 114 | scl=$(echo "$thr/$thr1" | bc -l); 115 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 116 | printf "%-8.2f" $linear_p; 117 | printf "%-12.2f" $scl; 118 | 119 | prog=$prog4; 120 | thr1=$thr1d; 121 | 122 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 123 | printf "%-12d" $thr; 124 | scl=$(echo "$thr/$thr1" | bc -l); 125 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 126 | printf "%-8.2f" $linear_p; 127 | printf "%-12.2f" $scl; 128 | 129 | prog=$prog5; 130 | thr1=$thr1e; 131 | 132 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 133 | printf "%-12d" $thr; 134 | scl=$(echo "$thr/$thr1" | bc -l); 135 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 136 | printf "%-8.2f" $linear_p; 137 | printf "%-12.2f" $scl; 138 | 139 | prog=$prog6; 140 | thr1=$thr1f; 141 | 142 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 143 | printf "%-12d" $thr; 144 | scl=$(echo "$thr/$thr1" | bc -l); 145 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 146 | printf "%-8.2f" $linear_p; 147 | printf "%-12.2f" $scl; 148 | 149 | prog=$prog7; 150 | thr1=$thr1g; 151 | 152 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 153 | printf "%-12d" $thr; 154 | scl=$(echo "$thr/$thr1" | bc -l); 155 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 156 | printf "%-8.2f" $linear_p; 157 | printf "%-8.2f\n" $scl; 158 | 159 | done; 160 | 161 | source scripts/unlock_exec; 162 | -------------------------------------------------------------------------------- /scripts/scalability8.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1="$1"; 10 | shift; 11 | prog2="$1"; 12 | shift; 13 | prog3="$1"; 14 | shift; 15 | prog4="$1"; 16 | shift; 17 | prog5="$1"; 18 | shift; 19 | prog6="$1"; 20 | shift; 21 | prog7="$1"; 22 | shift; 23 | prog8="$1"; 24 | shift; 25 | params="$@"; 26 | 27 | 28 | printf "# %-32s%-32s%-32s%-32s%-32s%-32s%-32s%-32s\n" "$prog1" "$prog2" "$prog3" "$prog4" "$prog5" "$prog6" "$prog7" "$prog8"; 29 | echo "#cores throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability"; 30 | 31 | prog=$prog1; 32 | 33 | printf "%-8d" 1; 34 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 35 | printf "%-12d" $thr1a; 36 | printf "%-8.2f" 100.00; 37 | printf "%-12d" 1; 38 | 39 | prog=$prog2; 40 | 41 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 42 | printf "%-12d" $thr1b; 43 | printf "%-8.2f" 100.00; 44 | printf "%-12d" 1; 45 | 46 | prog=$prog3; 47 | 48 | thr1c=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 49 | printf "%-12d" $thr1c; 50 | printf "%-8.2f" 100.00; 51 | printf "%-12d" 1; 52 | 53 | prog=$prog4; 54 | 55 | thr1d=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 56 | printf "%-12d" $thr1d; 57 | printf "%-8.2f" 100.00; 58 | printf "%-12d" 1; 59 | 60 | prog=$prog5; 61 | 62 | thr1e=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 63 | printf "%-12d" $thr1e; 64 | printf "%-8.2f" 100.00; 65 | printf "%-12d" 1; 66 | 67 | prog=$prog6; 68 | 69 | thr1f=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 70 | printf "%-12d" $thr1f; 71 | printf "%-8.2f" 100.00; 72 | printf "%-12d" 1; 73 | 74 | prog=$prog7; 75 | 76 | thr1g=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 77 | printf "%-12d" $thr1g; 78 | printf "%-8.2f" 100.00; 79 | printf "%-12d" 1; 80 | 81 | prog=$prog8; 82 | 83 | thr1h=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 84 | printf "%-12d" $thr1h; 85 | printf "%-8.2f" 100.00; 86 | printf "%-8d\n" 1; 87 | 88 | 89 | for c in $cores 90 | do 91 | if [ $c -eq 1 ] 92 | then 93 | continue; 94 | fi; 95 | 96 | printf "%-8d" $c; 97 | 98 | prog=$prog1; 99 | thr1=$thr1a; 100 | 101 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 102 | printf "%-12d" $thr; 103 | scl=$(echo "$thr/$thr1" | bc -l); 104 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 105 | printf "%-8.2f" $linear_p; 106 | printf "%-12.2f" $scl; 107 | 108 | prog=$prog2; 109 | thr1=$thr1b; 110 | 111 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 112 | printf "%-12d" $thr; 113 | scl=$(echo "$thr/$thr1" | bc -l); 114 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 115 | printf "%-8.2f" $linear_p; 116 | printf "%-12.2f" $scl; 117 | 118 | prog=$prog3; 119 | thr1=$thr1c; 120 | 121 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 122 | printf "%-12d" $thr; 123 | scl=$(echo "$thr/$thr1" | bc -l); 124 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 125 | printf "%-8.2f" $linear_p; 126 | printf "%-12.2f" $scl; 127 | 128 | prog=$prog4; 129 | thr1=$thr1d; 130 | 131 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 132 | printf "%-12d" $thr; 133 | scl=$(echo "$thr/$thr1" | bc -l); 134 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 135 | printf "%-8.2f" $linear_p; 136 | printf "%-12.2f" $scl; 137 | 138 | prog=$prog5; 139 | thr1=$thr1e; 140 | 141 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 142 | printf "%-12d" $thr; 143 | scl=$(echo "$thr/$thr1" | bc -l); 144 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 145 | printf "%-8.2f" $linear_p; 146 | printf "%-12.2f" $scl; 147 | 148 | prog=$prog6; 149 | thr1=$thr1f; 150 | 151 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 152 | printf "%-12d" $thr; 153 | scl=$(echo "$thr/$thr1" | bc -l); 154 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 155 | printf "%-8.2f" $linear_p; 156 | printf "%-12.2f" $scl; 157 | 158 | prog=$prog7; 159 | thr1=$thr1g; 160 | 161 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 162 | printf "%-12d" $thr; 163 | scl=$(echo "$thr/$thr1" | bc -l); 164 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 165 | printf "%-8.2f" $linear_p; 166 | printf "%-12.2f" $scl; 167 | 168 | prog=$prog8; 169 | thr1=$thr1h; 170 | 171 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 172 | printf "%-12d" $thr; 173 | scl=$(echo "$thr/$thr1" | bc -l); 174 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 175 | printf "%-8.2f" $linear_p; 176 | printf "%-8.2f\n" $scl; 177 | 178 | done; 179 | 180 | source scripts/unlock_exec; 181 | -------------------------------------------------------------------------------- /scripts/scalability9.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cores=$1; 4 | shift; 5 | 6 | source scripts/lock_exec; 7 | source scripts/config; 8 | 9 | prog1="$1"; 10 | shift; 11 | prog2="$1"; 12 | shift; 13 | prog3="$1"; 14 | shift; 15 | prog4="$1"; 16 | shift; 17 | prog5="$1"; 18 | shift; 19 | prog6="$1"; 20 | shift; 21 | prog7="$1"; 22 | shift; 23 | prog8="$1"; 24 | shift; 25 | prog9="$1"; 26 | shift; 27 | params="$@"; 28 | 29 | 30 | printf "# %-32s%-32s%-32s%-32s%-32s%-32s%-32s%-32s%-32s\n" "$prog1" "$prog2" "$prog3" "$prog4" "$prog5" "$prog6" "$prog7" "$prog8" "$prog9"; 31 | echo "#cores throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability throughput %linear scalability"; 32 | 33 | prog=$prog1; 34 | 35 | printf "%-8d" 1; 36 | thr1a=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 37 | printf "%-12d" $thr1a; 38 | printf "%-8.2f" 100.00; 39 | printf "%-12d" 1; 40 | 41 | prog=$prog2; 42 | 43 | thr1b=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 44 | printf "%-12d" $thr1b; 45 | printf "%-8.2f" 100.00; 46 | printf "%-12d" 1; 47 | 48 | prog=$prog3; 49 | 50 | thr1c=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 51 | printf "%-12d" $thr1c; 52 | printf "%-8.2f" 100.00; 53 | printf "%-12d" 1; 54 | 55 | prog=$prog4; 56 | 57 | thr1d=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 58 | printf "%-12d" $thr1d; 59 | printf "%-8.2f" 100.00; 60 | printf "%-12d" 1; 61 | 62 | prog=$prog5; 63 | 64 | thr1e=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 65 | printf "%-12d" $thr1e; 66 | printf "%-8.2f" 100.00; 67 | printf "%-12d" 1; 68 | 69 | prog=$prog6; 70 | 71 | thr1f=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 72 | printf "%-12d" $thr1f; 73 | printf "%-8.2f" 100.00; 74 | printf "%-12d" 1; 75 | 76 | prog=$prog7; 77 | 78 | thr1g=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 79 | printf "%-12d" $thr1g; 80 | printf "%-8.2f" 100.00; 81 | printf "%-12d" 1; 82 | 83 | prog=$prog8; 84 | 85 | thr1h=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 86 | printf "%-12d" $thr1h; 87 | printf "%-8.2f" 100.00; 88 | printf "%-12d" 1; 89 | 90 | prog=$prog9; 91 | 92 | thr1i=$($run_script ./$prog $params -n1 | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 93 | printf "%-12d" $thr1i; 94 | printf "%-8.2f" 100.00; 95 | printf "%-8d\n" 1; 96 | 97 | 98 | for c in $cores 99 | do 100 | if [ $c -eq 1 ] 101 | then 102 | continue; 103 | fi; 104 | 105 | printf "%-8d" $c; 106 | 107 | prog=$prog1; 108 | thr1=$thr1a; 109 | 110 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 111 | printf "%-12d" $thr; 112 | scl=$(echo "$thr/$thr1" | bc -l); 113 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 114 | printf "%-8.2f" $linear_p; 115 | printf "%-12.2f" $scl; 116 | 117 | prog=$prog2; 118 | thr1=$thr1b; 119 | 120 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 121 | printf "%-12d" $thr; 122 | scl=$(echo "$thr/$thr1" | bc -l); 123 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 124 | printf "%-8.2f" $linear_p; 125 | printf "%-12.2f" $scl; 126 | 127 | prog=$prog3; 128 | thr1=$thr1c; 129 | 130 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 131 | printf "%-12d" $thr; 132 | scl=$(echo "$thr/$thr1" | bc -l); 133 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 134 | printf "%-8.2f" $linear_p; 135 | printf "%-12.2f" $scl; 136 | 137 | prog=$prog4; 138 | thr1=$thr1d; 139 | 140 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 141 | printf "%-12d" $thr; 142 | scl=$(echo "$thr/$thr1" | bc -l); 143 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 144 | printf "%-8.2f" $linear_p; 145 | printf "%-12.2f" $scl; 146 | 147 | prog=$prog5; 148 | thr1=$thr1e; 149 | 150 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 151 | printf "%-12d" $thr; 152 | scl=$(echo "$thr/$thr1" | bc -l); 153 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 154 | printf "%-8.2f" $linear_p; 155 | printf "%-12.2f" $scl; 156 | 157 | prog=$prog6; 158 | thr1=$thr1f; 159 | 160 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 161 | printf "%-12d" $thr; 162 | scl=$(echo "$thr/$thr1" | bc -l); 163 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 164 | printf "%-8.2f" $linear_p; 165 | printf "%-12.2f" $scl; 166 | 167 | prog=$prog7; 168 | thr1=$thr1g; 169 | 170 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 171 | printf "%-12d" $thr; 172 | scl=$(echo "$thr/$thr1" | bc -l); 173 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 174 | printf "%-8.2f" $linear_p; 175 | printf "%-12.2f" $scl; 176 | 177 | prog=$prog8; 178 | thr1=$thr1h; 179 | 180 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 181 | printf "%-12d" $thr; 182 | scl=$(echo "$thr/$thr1" | bc -l); 183 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 184 | printf "%-8.2f" $linear_p; 185 | printf "%-12.2f" $scl; 186 | 187 | prog=$prog9; 188 | thr1=$thr1i; 189 | 190 | thr=$($run_script ./$prog $params -n$c | grep "#txs" | cut -d'(' -f2 | cut -d. -f1); 191 | printf "%-12d" $thr; 192 | scl=$(echo "$thr/$thr1" | bc -l); 193 | linear_p=$(echo "100*(1-(($c-$scl)/$c))" | bc -l); 194 | printf "%-8.2f" $linear_p; 195 | printf "%-8.2f\n" $scl; 196 | 197 | 198 | done; 199 | 200 | source scripts/unlock_exec; 201 | -------------------------------------------------------------------------------- /scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./run.sh 17 408 0.7 64 1000 0 1 3 | ./run.sh 127 3048 0.7 64 1000 0 1 4 | ./run.sh 1021 24504 0.7 64 1000 0 1 5 | ./run.sh 17 408 0.7 64 1000 0.2 0.8 6 | ./run.sh 127 3048 0.7 64 1000 0.2 0.8 7 | ./run.sh 1021 24504 0.7 64 1000 0.2 0.8 8 | #./run.sh 17 408 0.7 128 1000 0 1 9 | #./run.sh 127 3048 0.7 128 1000 0 1 10 | #./run.sh 1021 24504 0.7 128 1000 0 1 11 | #./run.sh 17 408 0.7 128 1000 0.2 0.8 12 | #./run.sh 127 3048 0.7 128 1000 0.2 0.8 13 | #./run.sh 1021 24504 0.7 128 1000 0.2 0.8 14 | #./run.sh 17 408 0.7 256 1000 0 1 15 | #./run.sh 127 3048 0.7 256 1000 0 1 16 | #./run.sh 1021 24504 0.7 256 1000 0 1 17 | #./run.sh 17 408 0.7 256 1000 0.2 0.8 18 | #./run.sh 127 3048 0.7 256 1000 0.2 0.8 19 | #./run.sh 1021 24504 0.7 256 1000 0.2 0.8 20 | #./run.sh 17 408 0.7 512 1000 0 1 21 | #./run.sh 127 3048 0.7 512 1000 0 1 22 | #./run.sh 1021 24504 0.7 512 1000 0 1 23 | #./run.sh 17 408 0.7 512 1000 0.2 0.8 24 | #./run.sh 127 3048 0.7 512 1000 0.2 0.8 25 | #./run.sh 1021 24504 0.7 512 1000 0.2 0.8 26 | ./run.sh 17 408 0.7 1024 1000 0 1 27 | ./run.sh 127 3048 0.7 1024 1000 0 1 28 | ./run.sh 1021 24504 0.7 1024 1000 0 1 29 | ./run.sh 17 408 0.7 1024 1000 0.2 0.8 30 | ./run.sh 127 3048 0.7 1024 1000 0.2 0.8 31 | ./run.sh 1021 24504 0.7 1024 1000 0.2 0.8 32 | -------------------------------------------------------------------------------- /scripts/test_correctness.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source scripts/lock_exec; 4 | source scripts/config; 5 | 6 | for bin in $(ls ./bin/*); 7 | do 8 | echo "Testing: $bin"; 9 | $run_script $bin -n$max_cores -l4 | grep "expected"; 10 | $run_script $bin -n$max_cores -l4 -i32 -r64 | grep "expected"; 11 | $run_script $bin -n$max_cores -l2 -i16 -r32 -u100 | grep "expected"; 12 | done; 13 | 14 | source scripts/unlock_exec; 15 | -------------------------------------------------------------------------------- /scripts/test_hy_correctness.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | initials="16 64 128 512 1024 2048 4096 8192"; 4 | updates="1 10 20 50 100"; 5 | load_factors="2 4 8 16"; 6 | reps=20; 7 | 8 | for i in $initials 9 | do 10 | r=$((2*$i)); 11 | for u in $updates 12 | do 13 | for l in $load_factors 14 | do 15 | settings="-i$i -r$r -u$u -l$l"; 16 | echo "## $settings"; 17 | for r in $(seq 1 1 $reps) 18 | do 19 | echo "# rep: $r"; 20 | ./scripts/scalability.sh socket "./throughput_ticket" $settings; 21 | done; 22 | done; 23 | done; 24 | done; 25 | 26 | 27 | -------------------------------------------------------------------------------- /scripts/test_mp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./run_mp.sh 17 408 0.7 64 1000 0 1 0 3 | ./run_mp.sh 127 3048 0.7 64 1000 0 1 0 4 | ./run_mp.sh 1021 24504 0.7 64 1000 0 1 0 5 | ./run_mp.sh 17 408 0.7 64 1000 0.1 0.8 0.1 6 | ./run_mp.sh 127 3048 0.7 64 1000 0.1 0.8 0.1 7 | ./run_mp.sh 1021 24504 0.7 64 1000 0.1 0.8 0.1 8 | ./run_mp.sh 17 408 0.7 128 1000 0 1 0 9 | ./run_mp.sh 127 3048 0.7 128 1000 0 1 0 10 | ./run_mp.sh 1021 24504 0.7 128 1000 0 1 0 11 | ./run_mp.sh 17 408 0.7 128 1000 0.1 0.8 0.1 12 | ./run_mp.sh 127 3048 0.7 128 1000 0.1 0.8 0.1 13 | ./run_mp.sh 1021 24504 0.7 128 1000 0.1 0.8 0.1 14 | ./run_mp.sh 17 408 0.7 256 1000 0 1 0 15 | ./run_mp.sh 127 3048 0.7 256 1000 0 1 0 16 | ./run_mp.sh 1021 24504 0.7 256 1000 0 1 0 17 | ./run_mp.sh 17 408 0.7 256 1000 0.1 0.8 0.1 18 | ./run_mp.sh 127 3048 0.7 256 1000 0.1 0.8 0.1 19 | ./run_mp.sh 1021 24504 0.7 256 1000 0.1 0.8 0.1 20 | ./run_mp.sh 17 408 0.7 512 1000 0 1 0 21 | ./run_mp.sh 127 3048 0.7 512 1000 0 1 0 22 | ./run_mp.sh 1021 24504 0.7 512 1000 0 1 0 23 | ./run_mp.sh 17 408 0.7 512 1000 0.1 0.8 0.1 24 | ./run_mp.sh 127 3048 0.7 512 1000 0.1 0.8 0.1 25 | ./run_mp.sh 1021 24504 0.7 512 1000 0.1 0.8 0.1 26 | ./run_mp.sh 17 408 0.7 1024 1000 0 1 0 27 | ./run_mp.sh 127 3048 0.7 1024 1000 0 1 0 28 | ./run_mp.sh 1021 24504 0.7 1024 1000 0 1 0 29 | ./run_mp.sh 17 408 0.7 1024 1000 0.1 0.8 0.1 30 | ./run_mp.sh 127 3048 0.7 1024 1000 0.1 0.8 0.1 31 | ./run_mp.sh 1021 24504 0.7 1024 1000 0.1 0.8 0.1 32 | -------------------------------------------------------------------------------- /scripts/unlock_exec: -------------------------------------------------------------------------------- 1 | rm "/dev/shm/lock_exec_$(whoami)" 2> /dev/null; -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | /.#htlock.c 3 | /.#mcore_malloc.c 4 | /cscope.files 5 | /cscope.out 6 | -------------------------------------------------------------------------------- /src/clht_gc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: clht_gc.c 3 | * Author: Vasileios Trigonakis 4 | * Description: 5 | * clht_gc.c is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #include "clht_lb_res.h" 32 | #include 33 | #include 34 | 35 | static __thread ht_ts_t* clht_ts_thread = NULL; 36 | 37 | /* 38 | * initialize thread metadata for GC 39 | */ 40 | void 41 | clht_gc_thread_init(clht_t* h, int id) 42 | { 43 | clht_alloc = (ssmem_allocator_t*) malloc(sizeof(ssmem_allocator_t)); 44 | assert(clht_alloc != NULL); 45 | ssmem_alloc_init_fs_size(clht_alloc, SSMEM_DEFAULT_MEM_SIZE, SSMEM_GC_FREE_SET_SIZE, id); 46 | 47 | ht_ts_t* ts = (ht_ts_t*) memalign(CACHE_LINE_SIZE, sizeof(ht_ts_t)); 48 | assert(ts != NULL); 49 | 50 | ts->version = h->ht->version; 51 | ts->id = id; 52 | 53 | do 54 | { 55 | ts->next = h->version_list; 56 | } 57 | while (CAS_U64((volatile size_t*) &h->version_list, (size_t) ts->next, (size_t) ts) != (size_t) ts->next); 58 | 59 | clht_ts_thread = ts; 60 | } 61 | 62 | /* 63 | * set the ht version currently used by the current thread 64 | */ 65 | inline void 66 | clht_gc_thread_version(clht_hashtable_t* h) 67 | { 68 | clht_ts_thread->version = h->version; 69 | } 70 | 71 | /* 72 | * set the ht version currently used by the current thread 73 | * to maximum to indicate that there is no ongoing update 74 | * operation. 75 | */ 76 | void 77 | clht_gc_thread_version_max() 78 | { 79 | clht_ts_thread->version = -1; 80 | } 81 | 82 | 83 | /* 84 | * get the GC id of the current thread 85 | */ 86 | inline int 87 | clht_gc_get_id() 88 | { 89 | return clht_ts_thread->id; 90 | } 91 | 92 | static int clht_gc_collect_cond(clht_t* hashtable, int collect_not_referenced_only); 93 | 94 | /* 95 | * perform a GC of the versions of the ht that are not currently used by any 96 | * of the participating threads 97 | */ 98 | inline int 99 | clht_gc_collect(clht_t* hashtable) 100 | { 101 | #if CLHT_DO_GC == 1 102 | CLHT_GC_HT_VERSION_USED(hashtable->ht); 103 | return clht_gc_collect_cond(hashtable, 1); 104 | #else 105 | return 0; 106 | #endif 107 | } 108 | 109 | /* 110 | * perform a GC of ALL old versions of the ht, regardless if they are 111 | * referenced by any of the threads 112 | */ 113 | int 114 | clht_gc_collect_all(clht_t* hashtable) 115 | { 116 | return clht_gc_collect_cond(hashtable, 0); 117 | } 118 | 119 | #define GET_ID(x) x ? clht_gc_get_id() : 99 120 | 121 | /* 122 | * go over the version metadata of all threads and return the min ht 123 | * version that is currently used. In other words, all versions, less 124 | * than the returned value, can be GCed 125 | */ 126 | size_t 127 | clht_gc_min_version_used(clht_t* h) 128 | { 129 | volatile ht_ts_t* cur = h->version_list; 130 | 131 | size_t min = h->ht->version; 132 | while (cur != NULL) 133 | { 134 | if (cur->version < min) 135 | { 136 | min = cur->version; 137 | } 138 | cur = cur->next; 139 | } 140 | 141 | return min; 142 | } 143 | 144 | /* 145 | * GC help function: 146 | * collect_not_referenced_only == 0 -> clht_gc_collect_all(); 147 | * collect_not_referenced_only != 0 -> clht_gc_collect(); 148 | */ 149 | static int 150 | clht_gc_collect_cond(clht_t* hashtable, int collect_not_referenced_only) 151 | { 152 | /* if version_min >= current version there is nothing to collect! */ 153 | if ((hashtable->version_min >= hashtable->ht->version) || TRYLOCK_ACQ(&hashtable->gc_lock)) 154 | { 155 | /* printf("** someone else is performing gc\n"); */ 156 | return 0; 157 | } 158 | 159 | ticks s = getticks(); 160 | 161 | /* printf("[GCOLLE-%02d] LOCK : %zu\n", GET_ID(collect_not_referenced_only), hashtable->version); */ 162 | 163 | size_t version_min = hashtable->ht->version; 164 | if (collect_not_referenced_only) 165 | { 166 | version_min = clht_gc_min_version_used(hashtable); 167 | } 168 | 169 | /* printf("[GCOLLE-%02d] gc collect versions < %3zu - current: %3zu - oldest: %zu\n", */ 170 | /* GET_ID(collect_not_referenced_only), version_min, hashtable->version, hashtable->version_min); */ 171 | 172 | int gced_num = 0; 173 | 174 | if (hashtable->version_min >= version_min) 175 | { 176 | /* printf("[GCOLLE-%02d] UNLOCK: %zu (nothing to collect)\n", GET_ID(collect_not_referenced_only), hashtable->ht->version); */ 177 | TRYLOCK_RLS(hashtable->gc_lock); 178 | } 179 | else 180 | { 181 | /* printf("[GCOLLE-%02d] collect from %zu to %zu\n", GET_ID(collect_not_referenced_only), hashtable->version_min, version_min); */ 182 | 183 | clht_hashtable_t* cur = hashtable->ht_oldest; 184 | while (cur != NULL && cur->version < version_min) 185 | { 186 | gced_num++; 187 | clht_hashtable_t* nxt = cur->table_new; 188 | /* printf("[GCOLLE-%02d] gc_free version: %6zu | current version: %6zu\n", GET_ID(collect_not_referenced_only), */ 189 | /* cur->version, hashtable->ht->version); */ 190 | nxt->table_prev = NULL; 191 | clht_gc_free(cur); 192 | cur = nxt; 193 | } 194 | 195 | hashtable->version_min = cur->version; 196 | hashtable->ht_oldest = cur; 197 | 198 | TRYLOCK_RLS(hashtable->gc_lock); 199 | /* printf("[GCOLLE-%02d] UNLOCK: %zu\n", GET_ID(collect_not_referenced_only), cur->version); */ 200 | } 201 | 202 | ticks e = getticks() - s; 203 | printf("[GCOLLE-%02d] collected: %-3d | took: %13llu ti = %8.6f s\n", 204 | GET_ID(collect_not_referenced_only), gced_num, (unsigned long long) e, e / 2.1e9); 205 | 206 | 207 | return gced_num; 208 | } 209 | 210 | /* 211 | * free the given hashtable 212 | */ 213 | int 214 | clht_gc_free(clht_hashtable_t* hashtable) 215 | { 216 | /* the CLHT_LINKED version does not allocate any extra buckets! */ 217 | #if !defined(CLHT_LB_LINKED) && !defined(LOCKFREE_RES) 218 | uint64_t num_buckets = hashtable->num_buckets; 219 | volatile bucket_t* bucket = NULL; 220 | 221 | uint64_t bin; 222 | for (bin = 0; bin < num_buckets; bin++) 223 | { 224 | bucket = hashtable->table + bin; 225 | bucket = bucket->next; 226 | while (bucket != NULL) 227 | { 228 | volatile bucket_t* cur = bucket; 229 | bucket = bucket->next; 230 | free((void*) cur); 231 | } 232 | } 233 | #endif 234 | 235 | free(hashtable->table); 236 | free(hashtable); 237 | 238 | return 1; 239 | } 240 | 241 | /* 242 | * free all hashtable version (inluding the latest) 243 | */ 244 | void 245 | clht_gc_destroy(clht_t* hashtable) 246 | { 247 | #if !defined(CLHT_LINKED) 248 | clht_gc_collect_all(hashtable); 249 | clht_gc_free(hashtable->ht); 250 | free(hashtable); 251 | #endif 252 | 253 | // ssmem_alloc_term(clht_alloc); 254 | free(clht_alloc); 255 | } 256 | 257 | /* 258 | * uses the ssmem_release function to return some memory 259 | * to the OS (free), when it is safe (nobody is using it 260 | * anymore) 261 | */ 262 | inline int 263 | clht_gc_release(clht_hashtable_t* hashtable) 264 | { 265 | /* the CLHT_LINKED version does not allocate any extra buckets! */ 266 | #if !defined(CLHT_LINKED) && !defined(LOCKFREE_RES) 267 | uint64_t num_buckets = hashtable->num_buckets; 268 | volatile bucket_t* bucket = NULL; 269 | 270 | uint64_t bin; 271 | for (bin = 0; bin < num_buckets; bin++) 272 | { 273 | bucket = hashtable->table + bin; 274 | bucket = bucket->next; 275 | while (bucket != NULL) 276 | { 277 | volatile bucket_t* cur = bucket; 278 | bucket = bucket->next; 279 | ssmem_release(clht_alloc, (void*) cur); 280 | } 281 | } 282 | #endif 283 | 284 | ssmem_release(clht_alloc, hashtable->table); 285 | ssmem_release(clht_alloc, hashtable); 286 | return 1; 287 | } 288 | 289 | 290 | -------------------------------------------------------------------------------- /src/clht_lf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: clht_lf.c 3 | * Author: Vasileios Trigonakis 4 | * Description: lock-free cache-line hash table with no resizing. If there is 5 | * not enough space for a key/value pair in its corresponding bucket, the 6 | * operation might never complete. Thus, better use the resize version. 7 | * clht_lf.c is part of ASCYLIB 8 | * 9 | * The MIT License (MIT) 10 | * 11 | * Copyright (c) 2014 Vasileios Trigonakis 12 | * Distributed Programming Lab (LPD), EPFL 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 15 | * this software and associated documentation files (the "Software"), to deal in 16 | * the Software without restriction, including without limitation the rights to 17 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 18 | * the Software, and to permit persons to whom the Software is furnished to do so, 19 | * subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in all 22 | * copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 26 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 27 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 28 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | * 31 | */ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "clht_lf.h" 39 | 40 | __thread ssmem_allocator_t* clht_alloc; 41 | 42 | #ifdef DEBUG 43 | __thread uint32_t put_num_restarts = 0; 44 | __thread uint32_t put_num_failed_expand = 0; 45 | __thread uint32_t put_num_failed_on_new = 0; 46 | #endif 47 | 48 | #include "stdlib.h" 49 | #include "assert.h" 50 | 51 | const char* 52 | clht_type_desc() 53 | { 54 | return "CLHT-LF-NO-RESIZE"; 55 | } 56 | 57 | inline int 58 | is_power_of_two (unsigned int x) 59 | { 60 | return ((x != 0) && !(x & (x - 1))); 61 | } 62 | 63 | static inline 64 | int is_odd (int x) 65 | { 66 | return x & 1; 67 | } 68 | 69 | /** Jenkins' hash function for 64-bit integers. */ 70 | inline uint64_t 71 | __ac_Jenkins_hash_64(uint64_t key) 72 | { 73 | key += ~(key << 32); 74 | key ^= (key >> 22); 75 | key += ~(key << 13); 76 | key ^= (key >> 8); 77 | key += (key << 3); 78 | key ^= (key >> 15); 79 | key += ~(key << 27); 80 | key ^= (key >> 31); 81 | return key; 82 | } 83 | 84 | /* Create a new bucket. */ 85 | bucket_t* 86 | clht_bucket_create() 87 | { 88 | bucket_t* bucket = NULL; 89 | bucket = memalign(CACHE_LINE_SIZE, sizeof(bucket_t)); 90 | if (bucket == NULL) 91 | { 92 | return NULL; 93 | } 94 | 95 | uint32_t j; 96 | for (j = 0; j < KEY_BUCKT; j++) 97 | { 98 | bucket->snapshot = 0; 99 | bucket->key[j] = 0; 100 | } 101 | 102 | return bucket; 103 | } 104 | 105 | clht_hashtable_t* clht_hashtable_create(uint64_t num_buckets); 106 | 107 | clht_t* 108 | clht_create(uint64_t num_buckets) 109 | { 110 | clht_t* w = (clht_t*) memalign(CACHE_LINE_SIZE, sizeof(clht_t)); 111 | if (w == NULL) 112 | { 113 | printf("** malloc @ hatshtalbe\n"); 114 | return NULL; 115 | } 116 | 117 | w->ht = clht_hashtable_create(num_buckets); 118 | return w; 119 | } 120 | 121 | clht_hashtable_t* 122 | clht_hashtable_create(uint64_t num_buckets) 123 | { 124 | clht_hashtable_t* hashtable = NULL; 125 | 126 | if (num_buckets == 0) 127 | { 128 | return NULL; 129 | } 130 | 131 | /* Allocate the table itself. */ 132 | hashtable = (clht_hashtable_t*) memalign(CACHE_LINE_SIZE, sizeof(clht_hashtable_t)); 133 | if (hashtable == NULL) 134 | { 135 | printf("** malloc @ hatshtalbe\n"); 136 | return NULL; 137 | } 138 | 139 | /* hashtable->table = calloc(num_buckets, (sizeof(bucket_t))); */ 140 | hashtable->table = (bucket_t*) memalign(CACHE_LINE_SIZE, num_buckets * (sizeof(bucket_t))); 141 | if (hashtable->table == NULL) 142 | { 143 | printf("** alloc: hashtable->table\n"); fflush(stdout); 144 | free(hashtable); 145 | return NULL; 146 | } 147 | 148 | memset((void*) hashtable->table, 0, num_buckets * (sizeof(bucket_t))); 149 | 150 | uint64_t i; 151 | for (i = 0; i < num_buckets; i++) 152 | { 153 | uint32_t j; 154 | for (j = 0; j < ENTRIES_PER_BUCKET; j++) 155 | { 156 | hashtable->table[i].snapshot = 0; 157 | hashtable->table[i].key[j] = 0; 158 | } 159 | } 160 | 161 | hashtable->num_buckets = num_buckets; 162 | hashtable->hash = num_buckets - 1; 163 | 164 | return hashtable; 165 | } 166 | 167 | 168 | /* Hash a key for a particular hash table. */ 169 | uint64_t 170 | clht_hash(clht_hashtable_t* hashtable, clht_addr_t key) 171 | { 172 | /* uint64_t hashval; */ 173 | /* return __ac_Jenkins_hash_64(key) & (hashtable->hash); */ 174 | /* return hashval % hashtable->num_buckets; */ 175 | /* return key % hashtable->num_buckets; */ 176 | /* return key & (hashtable->num_buckets - 1); */ 177 | return key & (hashtable->hash); 178 | } 179 | 180 | 181 | static inline clht_val_t 182 | clht_bucket_search(bucket_t* bucket, clht_addr_t key) 183 | { 184 | int i; 185 | for (i = 0; i < KEY_BUCKT; i++) 186 | { 187 | clht_val_t val = bucket->val[i]; 188 | #ifdef __tile__ 189 | _mm_lfence(); 190 | #endif 191 | if (bucket->map[i] == MAP_VALID) 192 | { 193 | if (bucket->key[i] == key) 194 | { 195 | if (likely(bucket->val[i] == val)) 196 | { 197 | return val; 198 | } 199 | else 200 | { 201 | return 0; 202 | } 203 | } 204 | } 205 | } 206 | return 0; 207 | } 208 | 209 | 210 | /* Retrieve a key-value entry from a hash table. */ 211 | clht_val_t 212 | clht_get(clht_hashtable_t* hashtable, clht_addr_t key) 213 | { 214 | size_t bin = clht_hash(hashtable, key); 215 | bucket_t* bucket = hashtable->table + bin; 216 | 217 | return clht_bucket_search(bucket, key); 218 | } 219 | 220 | 221 | 222 | __thread size_t num_retry_cas1 = 0, num_retry_cas2 = 0, num_retry_cas3 = 0, num_retry_cas4 = 0, num_retry_cas5 = 0; 223 | 224 | void 225 | clht_print_retry_stats() 226 | { 227 | printf("#cas1: %-8zu / #cas2: %-8zu / #cas3: %-8zu / #cas4: %-8zu\n", 228 | num_retry_cas1, num_retry_cas2, num_retry_cas3, num_retry_cas4); 229 | } 230 | 231 | #define DO_LF_STATS 0 232 | 233 | #if DO_LF_STATS == 1 234 | # define INC(x) x++ 235 | #else 236 | # define INC(x) ; 237 | #endif 238 | 239 | 240 | /* Insert a key-value entry into a hash table. */ 241 | int 242 | clht_put(clht_t* h, clht_addr_t key, clht_val_t val) 243 | { 244 | clht_hashtable_t* hashtable = h->ht; 245 | size_t bin = clht_hash(hashtable, key); 246 | bucket_t* bucket = hashtable->table + bin; 247 | 248 | int empty_index = -2; 249 | clht_snapshot_all_t s, s1; 250 | 251 | retry: 252 | s = bucket->snapshot; 253 | #ifdef __tile__ 254 | _mm_lfence(); 255 | #endif 256 | 257 | if (clht_bucket_search(bucket, key) != 0) 258 | { 259 | if (unlikely(empty_index >= 0)) 260 | { 261 | bucket->map[empty_index] = MAP_INVLD; 262 | } 263 | return false; 264 | } 265 | 266 | if (likely(empty_index < 0)) 267 | { 268 | empty_index = snap_get_empty_index(s); 269 | if (empty_index < 0) 270 | { 271 | goto retry; 272 | } 273 | s1 = snap_set_map(s, empty_index, MAP_INSRT); 274 | if (CAS_U64(&bucket->snapshot, s, s1) != s) 275 | { 276 | empty_index = -2; 277 | INC(num_retry_cas1); 278 | goto retry; 279 | } 280 | 281 | bucket->val[empty_index] = val; 282 | #ifdef __tile__ 283 | _mm_sfence(); 284 | #endif 285 | bucket->key[empty_index] = key; 286 | #ifdef __tile__ 287 | _mm_sfence(); 288 | #endif 289 | } 290 | else 291 | { 292 | s1 = snap_set_map(s, empty_index, MAP_INSRT); 293 | } 294 | 295 | clht_snapshot_all_t s2 = snap_set_map_and_inc_version(s1, empty_index, MAP_VALID); 296 | if (CAS_U64(&bucket->snapshot, s1, s2) != s1) 297 | { 298 | INC(num_retry_cas2); 299 | goto retry; 300 | } 301 | 302 | return true; 303 | } 304 | 305 | 306 | /* Remove a key-value entry from a hash table. */ 307 | clht_val_t 308 | clht_remove(clht_t* h, clht_addr_t key) 309 | { 310 | clht_hashtable_t* hashtable = h->ht; 311 | size_t bin = clht_hash(hashtable, key); 312 | bucket_t* bucket = hashtable->table + bin; 313 | 314 | clht_snapshot_t s; 315 | 316 | int i; 317 | retry: 318 | s.snapshot = bucket->snapshot; 319 | #ifdef __tile__ 320 | _mm_lfence(); 321 | #endif 322 | 323 | for (i = 0; i < KEY_BUCKT; i++) 324 | { 325 | if (bucket->key[i] == key && s.map[i] == MAP_VALID) 326 | { 327 | clht_val_t removed = bucket->val[i]; 328 | #ifdef __tile__ 329 | _mm_mfence(); 330 | #endif 331 | clht_snapshot_all_t s1 = snap_set_map(s.snapshot, i, MAP_INVLD); 332 | if (CAS_U64(&bucket->snapshot, s.snapshot, s1) == s.snapshot) 333 | { 334 | return removed; 335 | } 336 | else 337 | { 338 | INC(num_retry_cas3); 339 | goto retry; 340 | } 341 | } 342 | } 343 | return 0; 344 | } 345 | 346 | size_t 347 | clht_size(clht_hashtable_t* hashtable) 348 | { 349 | uint64_t num_buckets = hashtable->num_buckets; 350 | bucket_t* bucket = NULL; 351 | size_t size = 0; 352 | 353 | uint64_t bin; 354 | for (bin = 0; bin < num_buckets; bin++) 355 | { 356 | bucket = hashtable->table + bin; 357 | int i; 358 | for (i = 0; i < KEY_BUCKT; i++) 359 | { 360 | if (bucket->key[i] != 0 && bucket->map[i] == MAP_VALID) 361 | { 362 | size++; 363 | } 364 | } 365 | } 366 | return size; 367 | } 368 | 369 | 370 | void 371 | clht_print(clht_hashtable_t* hashtable) 372 | { 373 | uint64_t num_buckets = hashtable->num_buckets; 374 | bucket_t* bucket; 375 | 376 | printf("Number of buckets: %u\n", num_buckets); 377 | 378 | uint64_t bin; 379 | for (bin = 0; bin < num_buckets; bin++) 380 | { 381 | bucket = hashtable->table + bin; 382 | 383 | printf("[[%05d]] ", bin); 384 | 385 | uint32_t j; 386 | do 387 | { 388 | for (j = 0; j < ENTRIES_PER_BUCKET; j++) 389 | { 390 | if (bucket->key[j]) 391 | { 392 | printf("(%-5llu/%p)-> ", (long long unsigned int) bucket->key[j], (void*) bucket->val[j]); 393 | } 394 | } 395 | printf(" ** -> "); 396 | } 397 | while (bucket != NULL); 398 | printf("\n"); 399 | } 400 | fflush(stdout); 401 | } 402 | -------------------------------------------------------------------------------- /src/clht_lf_only_map_rem.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: clht_lf_only_map_rem.c 3 | * Author: Vasileios Trigonakis 4 | * Description: lock-free cache-line hash table with no resizing. The remove 5 | * operation changed only the map[] of the clht_snapshot_t struct and does 6 | * not increment the version number of the bucket. If there is 7 | * not enough space for a key/value pair in its corresponding bucket, the 8 | * operation might never complete. Thus, better use the resize version. 9 | * clht_lf_only_map_rem.c is part of ASCYLIB 10 | * 11 | * The MIT License (MIT) 12 | * 13 | * Copyright (c) 2014 Vasileios Trigonakis 14 | * Distributed Programming Lab (LPD), EPFL 15 | * 16 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 17 | * this software and associated documentation files (the "Software"), to deal in 18 | * the Software without restriction, including without limitation the rights to 19 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 20 | * the Software, and to permit persons to whom the Software is furnished to do so, 21 | * subject to the following conditions: 22 | * 23 | * The above copyright notice and this permission notice shall be included in all 24 | * copies or substantial portions of the Software. 25 | * 26 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 28 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 29 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 30 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | * 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "clht_lf_only_map_rem.h" 41 | 42 | __thread ssmem_allocator_t* clht_alloc; 43 | 44 | #ifdef DEBUG 45 | __thread uint32_t put_num_restarts = 0; 46 | __thread uint32_t put_num_failed_expand = 0; 47 | __thread uint32_t put_num_failed_on_new = 0; 48 | #endif 49 | 50 | #include "stdlib.h" 51 | #include "assert.h" 52 | 53 | const char* 54 | clht_type_desc() 55 | { 56 | return "CLHT-LF-ONLY-MAP-REM"; 57 | } 58 | 59 | inline int 60 | is_power_of_two (unsigned int x) 61 | { 62 | return ((x != 0) && !(x & (x - 1))); 63 | } 64 | 65 | static inline 66 | int is_odd (int x) 67 | { 68 | return x & 1; 69 | } 70 | 71 | /** Jenkins' hash function for 64-bit integers. */ 72 | inline uint64_t 73 | __ac_Jenkins_hash_64(uint64_t key) 74 | { 75 | key += ~(key << 32); 76 | key ^= (key >> 22); 77 | key += ~(key << 13); 78 | key ^= (key >> 8); 79 | key += (key << 3); 80 | key ^= (key >> 15); 81 | key += ~(key << 27); 82 | key ^= (key >> 31); 83 | return key; 84 | } 85 | 86 | /* Create a new bucket. */ 87 | bucket_t* 88 | clht_bucket_create() 89 | { 90 | bucket_t* bucket = NULL; 91 | bucket = memalign(CACHE_LINE_SIZE, sizeof(bucket_t)); 92 | if (bucket == NULL) 93 | { 94 | return NULL; 95 | } 96 | 97 | uint32_t j; 98 | for (j = 0; j < KEY_BUCKT; j++) 99 | { 100 | bucket->snapshot = 0; 101 | bucket->key[j] = 0; 102 | } 103 | 104 | return bucket; 105 | } 106 | 107 | clht_hashtable_t* clht_hashtable_create(uint64_t num_buckets); 108 | 109 | clht_t* 110 | clht_create(uint64_t num_buckets) 111 | { 112 | clht_t* w = (clht_t*) memalign(CACHE_LINE_SIZE, sizeof(clht_t)); 113 | if (w == NULL) 114 | { 115 | printf("** malloc @ hatshtalbe\n"); 116 | return NULL; 117 | } 118 | 119 | w->ht = clht_hashtable_create(num_buckets); 120 | return w; 121 | } 122 | 123 | clht_hashtable_t* 124 | clht_hashtable_create(uint64_t num_buckets) 125 | { 126 | clht_hashtable_t* hashtable = NULL; 127 | 128 | if (num_buckets == 0) 129 | { 130 | return NULL; 131 | } 132 | 133 | /* Allocate the table itself. */ 134 | hashtable = (clht_hashtable_t*) memalign(CACHE_LINE_SIZE, sizeof(clht_hashtable_t)); 135 | if (hashtable == NULL) 136 | { 137 | printf("** malloc @ hatshtalbe\n"); 138 | return NULL; 139 | } 140 | 141 | /* hashtable->table = calloc(num_buckets, (sizeof(bucket_t))); */ 142 | hashtable->table = (bucket_t*) memalign(CACHE_LINE_SIZE, num_buckets * (sizeof(bucket_t))); 143 | if (hashtable->table == NULL) 144 | { 145 | printf("** alloc: hashtable->table\n"); fflush(stdout); 146 | free(hashtable); 147 | return NULL; 148 | } 149 | 150 | memset((void*) hashtable->table, 0, num_buckets * (sizeof(bucket_t))); 151 | 152 | uint64_t i; 153 | for (i = 0; i < num_buckets; i++) 154 | { 155 | uint32_t j; 156 | for (j = 0; j < ENTRIES_PER_BUCKET; j++) 157 | { 158 | hashtable->table[i].snapshot = 0; 159 | hashtable->table[i].key[j] = 0; 160 | } 161 | } 162 | 163 | hashtable->num_buckets = num_buckets; 164 | hashtable->hash = num_buckets - 1; 165 | 166 | return hashtable; 167 | } 168 | 169 | 170 | /* Hash a key for a particular hash table. */ 171 | uint64_t 172 | clht_hash(clht_hashtable_t* hashtable, clht_addr_t key) 173 | { 174 | /* uint64_t hashval; */ 175 | /* return __ac_Jenkins_hash_64(key) & (hashtable->hash); */ 176 | /* return hashval % hashtable->num_buckets; */ 177 | /* return key % hashtable->num_buckets; */ 178 | /* return key & (hashtable->num_buckets - 1); */ 179 | return key & (hashtable->hash); 180 | } 181 | 182 | 183 | static inline clht_val_t 184 | clht_bucket_search(bucket_t* bucket, clht_addr_t key) 185 | { 186 | int i; 187 | for (i = 0; i < KEY_BUCKT; i++) 188 | { 189 | clht_val_t val = bucket->val[i]; 190 | #ifdef __tile__ 191 | _mm_lfence(); 192 | #endif 193 | if (bucket->map[i] >= MAP_VALID && bucket->key[i] == key) 194 | { 195 | if (likely(bucket->val[i] == val)) 196 | { 197 | return val; 198 | } 199 | else 200 | { 201 | return 0; 202 | } 203 | } 204 | } 205 | 206 | return 0; 207 | } 208 | 209 | /* Retrieve a key-value entry from a hash table. */ 210 | clht_val_t 211 | clht_get(clht_hashtable_t* hashtable, clht_addr_t key) 212 | { 213 | size_t bin = clht_hash(hashtable, key); 214 | bucket_t* bucket = hashtable->table + bin; 215 | 216 | return clht_bucket_search(bucket, key); 217 | } 218 | 219 | 220 | __thread size_t num_retry_cas1 = 0, num_retry_cas2 = 0, num_retry_cas3 = 0, 221 | num_retry_cas4 = 0, num_retry_cas5 = 0; 222 | 223 | void 224 | clht_print_retry_stats() 225 | { 226 | printf("#cas1: %-8zu / #cas2: %-8zu / #cas3: %-8zu / #cas4: %-8zu\n", 227 | num_retry_cas1, num_retry_cas2, num_retry_cas3, num_retry_cas4); 228 | } 229 | 230 | #define DO_LF_STATS 0 231 | 232 | #if DO_LF_STATS == 1 233 | # define INC(x) x++ 234 | #else 235 | # define INC(x) ; 236 | #endif 237 | 238 | 239 | /* Insert a key-value entry into a hash table. */ 240 | int 241 | clht_put(clht_t* h, clht_addr_t key, clht_val_t val) 242 | { 243 | clht_hashtable_t* hashtable = h->ht; 244 | size_t bin = clht_hash(hashtable, key); 245 | bucket_t* bucket = hashtable->table + bin; 246 | 247 | int empty_index = -2; 248 | clht_snapshot_all_t s, s1, s2; 249 | 250 | retry: 251 | s = bucket->snapshot; 252 | #ifdef __tile__ 253 | _mm_lfence(); 254 | #endif 255 | 256 | if (clht_bucket_search(bucket, key) != 0) 257 | { 258 | if (unlikely(empty_index >= 0)) 259 | { 260 | bucket->map[empty_index] = MAP_INVLD; 261 | } 262 | return false; 263 | } 264 | 265 | 266 | if (empty_index < 0) 267 | { 268 | empty_index = snap_get_empty_index(s); 269 | if (empty_index < 0) 270 | { 271 | goto retry; 272 | } 273 | s1 = snap_set_map(s, empty_index, MAP_INSRT); 274 | if (CAS_U64(&bucket->snapshot, s, s1) != s) 275 | { 276 | empty_index = -2; 277 | INC(num_retry_cas1); 278 | goto retry; 279 | } 280 | 281 | bucket->val[empty_index] = val; 282 | #ifdef __tile__ 283 | _mm_sfence(); 284 | #endif 285 | bucket->key[empty_index] = key; 286 | #ifdef __tile__ 287 | _mm_sfence(); 288 | #endif 289 | } 290 | else 291 | { 292 | s1 = snap_set_map(s, empty_index, MAP_INSRT); 293 | } 294 | 295 | 296 | s2 = snap_set_map_and_inc_version(s1, empty_index, MAP_VALID); 297 | if (CAS_U64(&bucket->snapshot, s1, s2) != s1) 298 | { 299 | INC(num_retry_cas2); 300 | goto retry; 301 | } 302 | 303 | return true; 304 | } 305 | 306 | 307 | /* Remove a key-value entry from a hash table. */ 308 | clht_val_t 309 | clht_remove(clht_t* h, clht_addr_t key) 310 | { 311 | clht_hashtable_t* hashtable = h->ht; 312 | size_t bin = clht_hash(hashtable, key); 313 | bucket_t* bucket = hashtable->table + bin; 314 | 315 | int i; 316 | for (i = 0; i < KEY_BUCKT; i++) 317 | { 318 | clht_val_t val = bucket->val[i]; 319 | #ifdef __tile__ 320 | _mm_lfence(); 321 | #endif 322 | if (bucket->map[i] == MAP_VALID && bucket->key[i] == key) 323 | { 324 | if (likely(bucket->val[i] == val)) 325 | { 326 | #if !defined(__tile__) 327 | if (CAS_U8(&bucket->map[i], MAP_VALID, MAP_REMOV) == MAP_VALID) 328 | #else /* tilera does not support atomic ops on bytes */ 329 | # warning "Tilera does not support atomic ops on bytes" 330 | #endif 331 | { 332 | if (bucket->key[i] == key) 333 | { 334 | val = bucket->val[i]; 335 | #ifdef __tile__ 336 | _mm_mfence(); 337 | #endif 338 | bucket->map[i] = MAP_INVLD; 339 | return val; 340 | } 341 | else 342 | { 343 | bucket->map[i] = MAP_VALID; 344 | } 345 | } 346 | 347 | return 0; 348 | } 349 | } 350 | } 351 | return 0; 352 | } 353 | 354 | size_t 355 | clht_size(clht_hashtable_t* hashtable) 356 | { 357 | uint64_t num_buckets = hashtable->num_buckets; 358 | bucket_t* bucket = NULL; 359 | size_t size = 0; 360 | 361 | uint64_t bin; 362 | for (bin = 0; bin < num_buckets; bin++) 363 | { 364 | bucket = hashtable->table + bin; 365 | int i; 366 | for (i = 0; i < KEY_BUCKT; i++) 367 | { 368 | if (bucket->key[i] != 0 && bucket->map[i] == MAP_VALID) 369 | { 370 | size++; 371 | } 372 | } 373 | } 374 | return size; 375 | } 376 | 377 | 378 | void 379 | clht_print(clht_hashtable_t* hashtable) 380 | { 381 | uint64_t num_buckets = hashtable->num_buckets; 382 | bucket_t* bucket; 383 | 384 | printf("Number of buckets: %u\n", num_buckets); 385 | 386 | uint64_t bin; 387 | for (bin = 0; bin < num_buckets; bin++) 388 | { 389 | bucket = hashtable->table + bin; 390 | 391 | printf("[[%05d]] ", bin); 392 | 393 | uint32_t j; 394 | do 395 | { 396 | for (j = 0; j < ENTRIES_PER_BUCKET; j++) 397 | { 398 | if (bucket->key[j]) 399 | { 400 | printf("(%-5llu/%p)-> ", (long long unsigned int) bucket->key[j], (void*) bucket->val[j]); 401 | } 402 | } 403 | printf(" ** -> "); 404 | } 405 | while (bucket != NULL); 406 | printf("\n"); 407 | } 408 | fflush(stdout); 409 | } 410 | -------------------------------------------------------------------------------- /src/measurements.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File: measurements.c 3 | * Author: Vasileios Trigonakis 4 | * Description: 5 | * measurements.c is part of ASCYLIB 6 | * 7 | * The MIT License (MIT) 8 | * 9 | * Copyright (c) 2014 Vasileios Trigonakis 10 | * Distributed Programming Lab (LPD), EPFL 11 | * 12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 13 | * this software and associated documentation files (the "Software"), to deal in 14 | * the Software without restriction, including without limitation the rights to 15 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16 | * the Software, and to permit persons to whom the Software is furnished to do so, 17 | * subject to the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be included in all 20 | * copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 24 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 25 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 26 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | * 29 | */ 30 | 31 | #define EXINLINED 32 | #include "measurements.h" 33 | 34 | #ifdef DO_TIMINGS 35 | ticks entry_time[ENTRY_TIMES_SIZE]; 36 | enum timings_bool_t entry_time_valid[ENTRY_TIMES_SIZE] = {M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE, M_FALSE}; 37 | ticks total_sum_ticks[ENTRY_TIMES_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 38 | long long total_samples[ENTRY_TIMES_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 39 | const char *measurement_msgs[ENTRY_TIMES_SIZE]; 40 | ticks getticks_correction = 0; 41 | 42 | void 43 | prints_ticks_stats(int start, int end) 44 | { 45 | uint32_t i, mpoints = 0, have_output = 0; 46 | unsigned long long tsamples = 0; 47 | ticks tticks = 0; 48 | 49 | for (i = start; i < end; i++) 50 | { 51 | if (total_samples[i]) 52 | { 53 | have_output = 1; 54 | mpoints++; 55 | tsamples += total_samples[i]; 56 | tticks += total_sum_ticks[i]; 57 | } 58 | } 59 | 60 | if (have_output) 61 | { 62 | printf("(PROFILING) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); 63 | } 64 | for (i = start; i < end; i++) { 65 | if (total_samples[i] && total_sum_ticks[i]) { 66 | printf("[%02d]%s:\n", i, measurement_msgs[i]); 67 | double ticks_perc = 100 * ((double) total_sum_ticks[i] / tticks); 68 | double secs = total_sum_ticks[i] / (REF_SPEED_GHZ * 1.e9); 69 | int s = (int) trunc(secs); 70 | int ms = (int) trunc((secs - s) * 1000); 71 | int us = (int) trunc(((secs - s) * 1000000) - (ms * 1000)); 72 | int ns = (int) trunc(((secs - s) * 1000000000) - (ms * 1000000) - (us * 1000)); 73 | double secsa = (total_sum_ticks[i] / total_samples[i]) / (REF_SPEED_GHZ * 1.e9); 74 | int sa = (int) trunc(secsa); 75 | int msa = (int) trunc((secsa - sa) * 1000); 76 | int usa = (int) trunc(((secsa - sa) * 1000000) - (msa * 1000)); 77 | int nsa = (int) trunc(((secsa - sa) * 1000000000) - (msa * 1000000) - (usa * 1000)); 78 | printf(" [%4.1f%%] samples: %-12llu | time: %3d %3d %3d %3d | avg: %3d %3d %3d %3d | ticks: %.1f\n", 79 | ticks_perc, total_samples[i], 80 | s, ms, us, ns, 81 | sa, msa, usa, nsa, 82 | (double) total_sum_ticks[i]/total_samples[i]); 83 | } 84 | } 85 | if (have_output) 86 | { 87 | printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< (PROFILING)\n"); 88 | fflush(stdout); 89 | } 90 | } 91 | 92 | #endif 93 | --------------------------------------------------------------------------------