├── .clang-format ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── ae-plot-scripts ├── calc_breakdown.py ├── calc_small.py ├── common.py ├── draw_graph_processing.py ├── draw_heatmap.py ├── draw_livegraph.py ├── draw_rocksdb.py └── draw_terasort.py ├── bench ├── bench_cached_vector.cpp ├── bench_compact_hash_page_table.cpp ├── bench_hitrate.cpp ├── bench_hitrate_fastmap.cpp ├── bench_hitrate_mmap.cpp ├── bench_io.cpp ├── bench_partition_server_client.cpp ├── bench_private_cache.cpp ├── bench_shared_cache.cpp ├── bench_single_thread_cache.cpp ├── bench_terasort_gnu.cpp └── bench_terasort_manual.cpp ├── bind ├── cache.cpp ├── cache.h ├── hook.cpp └── segfault_handler.cpp ├── cmake ├── Findaio.cmake ├── Findnuma.cmake └── Finduring.cmake ├── deps ├── fadec_output │ ├── fadec-decode-private.inc │ └── fadec-decode-public.inc └── spdk.patch ├── include ├── access_counter.hpp ├── cached_allocator.hpp ├── cached_ptr.hpp ├── compact_hash_page_table.hpp ├── direct_cache.hpp ├── integrated_cache.hpp ├── io_backend.hpp ├── memory_pool.hpp ├── mmap_allocator.hpp ├── page_table.hpp ├── partition_client.hpp ├── partition_server.hpp ├── partition_type.hpp ├── partitioner.hpp ├── private_cache.hpp ├── replacement.hpp ├── shared_cache.hpp ├── shared_single_thread_cache.hpp ├── single_thread_cache.hpp ├── type.hpp └── util.hpp ├── llvm-plugin ├── CMakeLists.txt ├── TriCacheAlloc │ ├── CMakeLists.txt │ ├── TriCacheAlloc.cpp │ └── TriCacheAlloc.h └── TriCacheInstrument │ ├── CMakeLists.txt │ ├── TriCacheInstrument.cpp │ └── TriCacheInstrument.h ├── playground ├── manual_parallel_sort.cpp ├── parallel_sort.cpp ├── spdk.cpp ├── test_instrument.cpp ├── test_instrument_mmap.cpp ├── test_libcache.cpp └── test_memcpy.cpp └── scripts ├── build.sh ├── build_flashgraph.sh ├── build_ligra.sh ├── build_livegraph.sh ├── build_rocksdb.sh ├── build_terasort_spark.sh ├── cgroups.sh ├── clearcache.sh ├── config.sh ├── convert_to_flashgraph.sh ├── convert_to_ligra.sh ├── install_4.14_kernel.sh ├── kexec.sh ├── livegraph_cp_dataset_cache.sh ├── livegraph_cp_dataset_mmap.sh ├── livegraph_exec_cache.sh ├── livegraph_exec_mmap.sh ├── load_to_flashgraph.sh ├── mkraid.sh ├── mkswap.sh ├── mkxfs.sh ├── plot_all.sh ├── prepare_fastmap.sh ├── reset_spdk.sh ├── rmraid.sh ├── rmswap.sh ├── rmxfs.sh ├── run_all.sh ├── run_all_small.sh ├── run_breakdown.sh ├── run_flashgraph.sh ├── run_flashgraph_small.sh ├── run_graph_processing.sh ├── run_ligra_breakdown.sh ├── run_ligra_cache.sh ├── run_ligra_cache_small.sh ├── run_ligra_swap.sh ├── run_ligra_swap_slow.sh ├── run_ligra_swap_small.sh ├── run_livegraph.sh ├── run_livegraph_cache.sh ├── run_livegraph_cache_small.sh ├── run_livegraph_mmap.sh ├── run_livegraph_mmap_small.sh ├── run_microbenchmark.sh ├── run_microbenchmark_cache.sh ├── run_microbenchmark_cache_small.sh ├── run_microbenchmark_fastmap.sh ├── run_microbenchmark_fastmap_driver.sh ├── run_microbenchmark_mmap.sh ├── run_microbenchmark_mmap_small.sh ├── run_rocksdb.sh ├── run_rocksdb_block.sh ├── run_rocksdb_block_small.sh ├── run_rocksdb_cache.sh ├── run_rocksdb_cache_small.sh ├── run_rocksdb_mmap.sh ├── run_rocksdb_mmap_small.sh ├── run_terasort.sh ├── run_terasort_breakdown.sh ├── run_terasort_cache.sh ├── run_terasort_cache_small.sh ├── run_terasort_spark.sh ├── run_terasort_spark_small.sh ├── run_terasort_swap.sh ├── run_terasort_swap_slow.sh ├── run_terasort_swap_small.sh ├── setup_spdk.sh └── test_build.sh /.clang-format: -------------------------------------------------------------------------------- 1 | Language: Cpp 2 | BasedOnStyle: LLVM 3 | IndentWidth: 4 4 | AccessModifierOffset: -4 5 | BreakBeforeBraces: Allman 6 | BinPackParameters: false 7 | ColumnLimit: 120 8 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 9 | NamespaceIndentation: All 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt.user 2 | CMakeCache.txt 3 | CMakeFiles 4 | CMakeScripts 5 | Testing 6 | Makefile 7 | cmake_install.cmake 8 | install_manifest.txt 9 | compile_commands.json 10 | CTestTestfile.cmake 11 | _deps 12 | build 13 | .clangd 14 | .cache 15 | compile_commands.json 16 | __pycache__ 17 | /results_* 18 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/hopscotch-map"] 2 | path = deps/hopscotch-map 3 | url = https://github.com/Tessil/hopscotch-map.git 4 | [submodule "deps/fadec"] 5 | path = deps/fadec 6 | url = https://github.com/aengelke/fadec.git 7 | [submodule "deps/mimalloc"] 8 | path = deps/mimalloc 9 | url = https://github.com/microsoft/mimalloc.git 10 | [submodule "ae-projects/ligra"] 11 | path = ae-projects/ligra 12 | url = https://github.com/TriCache-OSDI-AE/ligra.git 13 | [submodule "ae-projects/FlashX"] 14 | path = ae-projects/FlashX 15 | url = https://github.com/TriCache-OSDI-AE/FlashX.git 16 | [submodule "ae-projects/LiveGraph-snb"] 17 | path = ae-projects/LiveGraph-snb 18 | url = https://github.com/TriCache-OSDI-AE/LiveGraph-snb.git 19 | [submodule "ae-projects/ldbc_snb_implementations"] 20 | path = ae-projects/ldbc_snb_implementations 21 | url = https://github.com/TriCache-OSDI-AE/ldbc_snb_implementations.git 22 | [submodule "ae-projects/terasort_spark"] 23 | path = ae-projects/terasort_spark 24 | url = https://github.com/TriCache-OSDI-AE/terasort_spark.git 25 | [submodule "ae-projects/rocksdb"] 26 | path = ae-projects/rocksdb 27 | url = https://github.com/TriCache-OSDI-AE/rocksdb.git 28 | [submodule "ae-projects/FastMap"] 29 | path = ae-projects/FastMap 30 | url = https://github.com/TriCache-OSDI-AE/FastMap.git 31 | -------------------------------------------------------------------------------- /ae-plot-scripts/calc_breakdown.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import pathlib 3 | import re 4 | import numpy as np 5 | 6 | def read_result(filename, result_re): 7 | found_result = False 8 | try: 9 | with open(filename, "r") as f: 10 | lines = f.readlines() 11 | for line in lines: 12 | if result_re.match(line): 13 | result = float(result_re.match(line).group(1)) 14 | found_result = True 15 | except: 16 | pass 17 | return result if found_result else np.inf 18 | 19 | ligra_re = re.compile(r"^Running time : (.*)$") 20 | terasort_re = re.compile(r"^exec (.*) s.*$") 21 | prfile_re = re.compile(r"""# Profile of Direct SATC: 22 | # access number: (\d+) 23 | # access cycles: (\d+) 24 | # miss number: (\d+) 25 | # miss cycles: (\d+) 26 | # Profile of Private SATC: 27 | # access number: (\d+) 28 | # access cycles: (\d+) 29 | # miss number: (\d+) 30 | # miss cycles: (\d+) 31 | # Profile of Shared: 32 | # access number: (\d+) 33 | # access cycles: (\d+) 34 | # miss number: (\d+) 35 | # miss cycles: (\d+)""") 36 | 37 | if __name__ == '__main__': 38 | 39 | result_dir = pathlib.Path(sys.argv[1]) / 'results_breakdown' 40 | 41 | filelist = lambda x: [ 42 | x + ".txt", 43 | x + "_disable_direct.txt", 44 | x + "_disable_private.txt", 45 | x + "_disable_direct_private.txt" 46 | ] 47 | 48 | configs = [ 49 | ("PageRank", ligra_re, "PageRank_uk-2014"), 50 | ("ShuffleSort", terasort_re, "terasort_manual"), 51 | ("GNUSort", terasort_re, "terasort_gnu"), 52 | ] 53 | 54 | for name, matcher, prefix in configs: 55 | result = list(map(lambda x: read_result(result_dir / x, matcher), filelist(prefix))) 56 | print(f"For {name}, slowdown of disabling direct SATC is {result[1] / result[0]:.2f}, disabling private SATC is {result[2] / result[0]:.2f}, disabling direct and private SATC is {result[3] / result[0]:.2f}") 57 | 58 | print() 59 | 60 | for name, _, prefix in configs: 61 | profile_f = result_dir / (prefix + "_profile.txt") 62 | with open(profile_f, "r") as f: 63 | m = list(prfile_re.finditer(f.read()))[-1] 64 | direct_acc_num = int(m.group( 1)) 65 | direct_acc_cyc = int(m.group( 2)) 66 | direct_mis_num = int(m.group( 3)) 67 | direct_mis_cyc = int(m.group( 4)) 68 | private_acc_num = int(m.group( 5)) 69 | private_acc_cyc = int(m.group( 6)) 70 | private_mis_num = int(m.group( 7)) 71 | private_mis_cyc = int(m.group( 8)) 72 | shared_acc_num = int(m.group( 9)) 73 | # shared_acc_cyc = int(m.group(10)) 74 | shared_acc_cyc = private_mis_cyc 75 | shared_mis_num = int(m.group(11)) 76 | shared_mis_cyc = int(m.group(12)) 77 | 78 | data = [ 79 | ("Direct SATC", direct_mis_num / direct_acc_num, (direct_acc_cyc - direct_mis_cyc) / (direct_acc_num - direct_mis_num)), 80 | ("Private SATC", private_mis_num / private_acc_num, (private_acc_cyc - private_mis_cyc) / (private_acc_num - private_mis_num)), 81 | ("Shared Cache", shared_mis_num / shared_acc_num, (shared_acc_cyc - shared_mis_cyc) / shared_acc_num), 82 | ] 83 | 84 | print(f"Case: {name}") 85 | for type, miss_rate, avg_cycle in data: 86 | print(f"{type} miss rate: {miss_rate:f}, average cycle: {avg_cycle:.2f}") 87 | -------------------------------------------------------------------------------- /ae-plot-scripts/common.py: -------------------------------------------------------------------------------- 1 | from types import CodeType 2 | from matplotlib.colors import Normalize, LinearSegmentedColormap 3 | import numpy as np 4 | import matplotlib as mpl 5 | import matplotlib.pyplot as plt 6 | import math 7 | import matplotlib.mlab as mlab 8 | import matplotlib.ticker as ticker 9 | from mpl_toolkits.axes_grid1 import host_subplot 10 | import mpl_toolkits.axisartist as AA 11 | import matplotlib.patches as mpatches 12 | import matplotlib.lines as mlines 13 | import matplotlib.cm as cm 14 | import json 15 | 16 | import matplotlib 17 | from numpy.lib.function_base import cov 18 | 19 | matplotlib.rcParams["font.sans-serif"] = "DejaVu Sans" 20 | matplotlib.rcParams["pdf.fonttype"] = 42 21 | matplotlib.rcParams["ps.fonttype"] = 42 22 | dirbase = "./" 23 | 24 | from matplotlib import font_manager 25 | 26 | sz, fontsz = (6, 3), 16 27 | figsz = { 28 | "axes.labelsize": 12, 29 | "font.size": 12, 30 | "legend.fontsize": 10, 31 | "xtick.labelsize": 10, 32 | "ytick.labelsize": 10, 33 | "figure.figsize": (6, 3), 34 | "axes.titlesize": 12, 35 | } 36 | plt.rcParams.update(figsz) 37 | 38 | hb = "\\\\//\\\\//" 39 | 40 | color_def = [ 41 | "#f4b183", 42 | "#ffd966", 43 | "#c5e0b4", 44 | "#bdd7ee", 45 | "#8dd3c7", 46 | "#bebada", 47 | "#fb8072", 48 | "#80b1d3", 49 | "#fdb462", 50 | "#cccccc", 51 | "#fccde5", 52 | "#b3de69", 53 | "#ffd92f", 54 | "#fc8d59", 55 | "#74a9cf", 56 | "#66c2a4", 57 | "#f4a143", 58 | "#ffc936", 59 | "#78c679", 60 | ] 61 | 62 | color_line = [ 63 | "#5AA469", 64 | "#1A508B", 65 | "#F39233", 66 | "#B61919", 67 | ] 68 | 69 | hatch_def = [ 70 | "//", 71 | "\\\\", 72 | "xx", 73 | "++", 74 | "--", 75 | "||", 76 | "..", 77 | "oo", 78 | "", 79 | ] 80 | 81 | marker_def = [ 82 | "o", 83 | "x", 84 | "D", 85 | "*", 86 | "+", 87 | ] 88 | -------------------------------------------------------------------------------- /ae-plot-scripts/draw_livegraph.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | MMAP = "LiveGraph (mmap)" 4 | TRICACHE = "LiveGraph (TriCache)" 5 | 6 | sizes = ["256", "128", "64", "32", "16"] 7 | exps = ["SF30", "SF100"] 8 | 9 | def draw_livegraph(data): 10 | dat_SF30_cache = np.log10(data[TRICACHE][exps.index("SF30")]) 11 | dat_SF30_mmap = np.log10(data[MMAP][exps.index("SF30")]) 12 | dat_SF100_cache = np.log10(data[TRICACHE][exps.index("SF100")]) 13 | dat_SF100_mmap = np.log10(data[MMAP][exps.index("SF100")]) 14 | 15 | dat = [[dat_SF30_mmap, dat_SF30_cache], [dat_SF100_mmap, dat_SF100_cache]] 16 | case_labels = ["(a) SF30", "(b) SF100"] 17 | 18 | sz = (8, 5) 19 | figsz = {"figure.figsize": sz} 20 | plt.rcParams.update(figsz) 21 | 22 | fig, axes = plt.subplots(nrows=2) 23 | color_vec = [color_def[1], color_def[2]] 24 | hatch_vec = [None, hatch_def[0]] 25 | 26 | num_cases = len(dat) 27 | num_bars = len(dat[0]) 28 | num_groups = len(dat[0][0]) 29 | 30 | bar_width, bar_gap = 0.6, 0 31 | group_width = (bar_width + bar_gap) * num_bars - bar_gap 32 | group_gap = 1 33 | 34 | for k in range(num_cases): 35 | for i in range(num_groups): 36 | for j in range(num_bars): 37 | offset = ( 38 | group_gap 39 | + (group_width + group_gap) * i 40 | + bar_width / 2 41 | + (bar_width + bar_gap) * j 42 | ) 43 | axes[k].bar( 44 | offset, 45 | dat[k][j][i], 46 | bar_width, 47 | color=color_vec[j], 48 | hatch=hatch_vec[j], 49 | edgecolor="black", 50 | ) 51 | 52 | axes[k].set_xlim(0, (group_width + group_gap) * num_groups + group_gap) 53 | axes[k].set_xticks( 54 | [ 55 | group_gap + (group_width + group_gap) * x + group_width / 2 56 | for x in range(num_groups) 57 | ] 58 | ) 59 | axes[k].set_xticklabels([]) 60 | axes[k].set_xticklabels(np.flip(["16GB", "32GB", "64GB", "128GB", "256GB"])) 61 | 62 | axes[k].set_ylabel("Throughput") 63 | axes[k].set_ylim(1, 5) 64 | axes[k].set_yticks(range(1, 6)) 65 | axes[k].set_yticklabels(["1E1", "1E2", "1E3", "1E4", "1E5"]) 66 | # axes[k].set_title(case_labels[k]) 67 | axes[k].set_xlabel(case_labels[k]) 68 | 69 | labels = [MMAP, TRICACHE] 70 | num_type = len(labels) 71 | legend_handles = [ 72 | mpatches.Patch( 73 | facecolor=color_vec[i], 74 | edgecolor="black", 75 | hatch=hatch_vec[i], 76 | label=labels[i], 77 | ) 78 | for i in range(num_type) 79 | ] 80 | fig.legend( 81 | handles=legend_handles, ncol=2, loc="upper center", bbox_to_anchor=(0.5, 0.97) 82 | ) 83 | 84 | # plt.show() 85 | fig.subplots_adjust(hspace=0.33) 86 | fig.savefig(dirbase + "livegraph.pdf", bbox_inches="tight") 87 | 88 | 89 | if __name__ == "__main__": 90 | 91 | import re 92 | import sys 93 | import pathlib 94 | 95 | result_dir = pathlib.Path(sys.argv[1]) 96 | 97 | configs = [ 98 | { 99 | "name": MMAP, 100 | "dir": result_dir / 'results_livegraph_mmap', 101 | "name_extrator": re.compile(r".*results_.*_(sf.*)_mmap_(.*)G.*"), 102 | "result_extrator": re.compile(r"""^.*"throughput" : (.*)$"""), 103 | }, 104 | { 105 | "name": TRICACHE, 106 | "dir": result_dir / 'results_livegraph_cache', 107 | "name_extrator": re.compile(r".*results_.*_(sf.*)_cache_(.*)G.*"), 108 | "result_extrator": re.compile(r"""^.*"throughput" : (.*)$"""), 109 | }, 110 | ] 111 | 112 | def read_result(c): 113 | 114 | results = np.zeros((len(exps), len(sizes)), np.float64) 115 | # results[:] = np.nan 116 | 117 | for p in c["dir"].rglob("*/LDBC-SNB-results.json"): 118 | match = c["name_extrator"].match(str(p)) 119 | exp, size = match.group(1), match.group(2) 120 | 121 | exp = exp.upper() 122 | 123 | time_extrator = c["result_extrator"] 124 | 125 | with open(p.resolve(), "r") as f: 126 | lines = f.readlines() 127 | for line in lines: 128 | if time_extrator.match(line): 129 | result = float(time_extrator.match(line).group(1)) 130 | 131 | results[exps.index(exp), sizes.index(size)] = result 132 | result = 0 133 | 134 | return c["name"], results 135 | 136 | plot_results = {} 137 | 138 | for c in configs: 139 | name, results = read_result(c) 140 | plot_results[name] = results 141 | 142 | # print(plot_results) 143 | 144 | print("With 256GB memory & SF30 dataset, TriCache brings {:.1%} overhead compared with mmap.".format(1 - plot_results[TRICACHE][exps.index("SF30"), sizes.index("256")] / plot_results[MMAP][exps.index("SF30"), sizes.index("256")])) 145 | print("With 32GB memory & SF30 dataset, TriCache outperforms mmap by {:.2f}x.".format(plot_results[TRICACHE][exps.index("SF30"), sizes.index("32")] / plot_results[MMAP][exps.index("SF30"), sizes.index("32")])) 146 | 147 | print() 148 | 149 | print("With 256GB memory & SF100 dataset, TriCache outperforms mmap by {:.2f}x.".format(plot_results[TRICACHE][exps.index("SF100"), sizes.index("256")] / plot_results[MMAP][exps.index("SF100"), sizes.index("256")])) 150 | print("With 16GB memory & SF100 dataset, TriCache outperforms mmap by {:.2f}x.".format(plot_results[TRICACHE][exps.index("SF100"), sizes.index("16")] / plot_results[MMAP][exps.index("SF100"), sizes.index("16")])) 151 | 152 | draw_livegraph(plot_results) 153 | -------------------------------------------------------------------------------- /ae-plot-scripts/draw_rocksdb.py: -------------------------------------------------------------------------------- 1 | from common import * 2 | 3 | BLOCK = "BlockBasedTable" 4 | PLAIN_MMAP = "PlainTable (mmap)" 5 | PLAIN_TRICACHE = "PlainTable (TriCache)" 6 | 7 | exps = [""] 8 | sizes = ["256", "128", "64", "32", "16"] 9 | 10 | def draw_rocksdb(data): 11 | dat_plain_mmap = np.log10(data[PLAIN_MMAP]).flatten() 12 | dat_block = np.log10(data[BLOCK]).flatten() 13 | dat_plain_cache = np.log10(data[PLAIN_TRICACHE]).flatten() 14 | 15 | dat = [dat_block, dat_plain_mmap, dat_plain_cache] 16 | 17 | labels = [BLOCK, PLAIN_MMAP, PLAIN_TRICACHE] 18 | 19 | sz = (8, 2.5) 20 | figsz = {"figure.figsize": sz} 21 | plt.rcParams.update(figsz) 22 | 23 | fig, ax = plt.subplots() 24 | color_vec = [color_def[3], color_def[1], color_def[2]] 25 | hatch_vec = [None, None, hatch_def[0]] 26 | 27 | num_bars = len(dat) 28 | num_groups = len(dat[0]) 29 | 30 | bar_width, bar_gap = 0.6, 0 31 | group_width = (bar_width + bar_gap) * num_bars - bar_gap 32 | group_gap = 1 33 | 34 | for i in range(num_groups): 35 | for j in range(num_bars): 36 | offset = ( 37 | group_gap 38 | + (group_width + group_gap) * i 39 | + bar_width / 2 40 | + (bar_width + bar_gap) * j 41 | ) 42 | ax.bar( 43 | offset, 44 | dat[j][i], 45 | bar_width, 46 | color=color_vec[j], 47 | hatch=hatch_vec[j], 48 | edgecolor="black", 49 | ) 50 | 51 | ax.set_xlabel("Memory Quota") 52 | ax.set_xlim(0, (group_width + group_gap) * num_groups + group_gap) 53 | ax.set_xticks( 54 | [ 55 | group_gap + (group_width + group_gap) * x + group_width / 2 56 | for x in range(num_groups) 57 | ] 58 | ) 59 | ax.set_xticklabels(["256GB", "128GB", "64GB", "32GB", "16GB"]) 60 | 61 | ax.set_ylabel("Throughput") 62 | ax.set_ylim(1, 7) 63 | ax.set_yticks(range(1, 8)) 64 | ax.set_yticklabels(["1E1", "1E2", "1E3", "1E4", "1E5", "1E6", "1E7"]) 65 | 66 | num_type = len(labels) 67 | legend_handles = [ 68 | mpatches.Patch( 69 | facecolor=color_vec[i], 70 | edgecolor="black", 71 | hatch=hatch_vec[i], 72 | label=labels[i], 73 | ) 74 | for i in range(num_type) 75 | ] 76 | plt.legend( 77 | handles=legend_handles, ncol=3, loc="upper center", bbox_to_anchor=(0.5, 1.25) 78 | ) 79 | 80 | # plt.show() 81 | fig.savefig(dirbase + "rocksdb.pdf", bbox_inches="tight") 82 | 83 | 84 | if __name__ == "__main__": 85 | 86 | import re 87 | import sys 88 | import pathlib 89 | 90 | result_dir = pathlib.Path(sys.argv[1]) 91 | 92 | name_re = re.compile(r".*/(.*)_(.*)G_.*.txt$") 93 | result_re = re.compile(r"^mixgraph.*op (.*) ops/sec.*$") 94 | 95 | configs = [ 96 | { 97 | "name": BLOCK, 98 | "dir": result_dir / 'results_rocksdb_block', 99 | "name_extrator": name_re, 100 | "result_extrator": result_re, 101 | }, 102 | { 103 | "name": PLAIN_MMAP, 104 | "dir": result_dir / 'results_rocksdb_mmap', 105 | "name_extrator": name_re, 106 | "result_extrator": result_re, 107 | }, 108 | { 109 | "name": PLAIN_TRICACHE, 110 | "dir": result_dir / 'results_rocksdb_cache', 111 | "name_extrator": name_re, 112 | "result_extrator": result_re, 113 | }, 114 | ] 115 | 116 | def read_result(c): 117 | 118 | results = np.zeros((len(exps), len(sizes)), np.float64) 119 | # results[:] = np.nan 120 | 121 | for p in c["dir"].glob("*.txt"): 122 | match = c["name_extrator"].match(str(p)) 123 | _, size = match.group(1), match.group(2) 124 | 125 | time_extrator = c["result_extrator"] 126 | 127 | with open(p.resolve(), "r") as f: 128 | lines = f.readlines() 129 | for line in lines: 130 | if time_extrator.match(line): 131 | result = float(time_extrator.match(line).group(1)) 132 | 133 | results[0, sizes.index(size)] = result 134 | result = 0 135 | 136 | return c["name"], results 137 | 138 | plot_results = {} 139 | 140 | for c in configs: 141 | name, results = read_result(c) 142 | plot_results[name] = results 143 | 144 | # print(plot_results) 145 | 146 | for i, s in enumerate(sizes): 147 | b = plot_results[BLOCK][0, i] 148 | m = plot_results[PLAIN_MMAP][0, i] 149 | t = plot_results[PLAIN_TRICACHE][0, i] 150 | print(f"With {s}G memory, PlainTable(TriCache)'s speedup over PlainTable(mmap): {t/m:.2f}, over BlockBasedTable {t/b:.2f}") 151 | 152 | 153 | draw_rocksdb(plot_results) 154 | -------------------------------------------------------------------------------- /bench/bench_compact_hash_page_table.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "compact_hash_page_table.hpp" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | const size_t virt_size = 8 * 128lu * (1 << 30); 23 | const size_t num_vpages = virt_size / scache::CACHE_PAGE_SIZE; 24 | const size_t phy_size = 128lu * (1 << 30); 25 | const size_t num_ppages = phy_size / scache::CACHE_PAGE_SIZE; 26 | const size_t num_requests = 50000000; 27 | 28 | int main() 29 | { 30 | auto read_only = [&](size_t stride) 31 | { 32 | numa_set_interleave_mask(numa_all_nodes_ptr); 33 | scache::CompactHashPageTable page_table(num_vpages, num_ppages); 34 | 35 | for (uint64_t ppage_id = 0; ppage_id < num_ppages; ppage_id++) 36 | { 37 | auto vpage_id = ppage_id * stride; 38 | auto hint = page_table.find_or_create_hint(vpage_id); 39 | auto success = page_table.create_mapping(vpage_id, ppage_id); 40 | assert(success == true); 41 | success = page_table.release_mapping_lock(vpage_id); 42 | assert(success == true); 43 | } 44 | 45 | size_t sum_checksum = 0; 46 | double sum_throughput = 0; 47 | #pragma omp parallel 48 | { 49 | std::mt19937_64 rand(omp_get_thread_num()); 50 | size_t checksum = 0; 51 | auto start = std::chrono::high_resolution_clock::now(); 52 | for (uint64_t i = 0; i < num_requests; i++) 53 | { 54 | auto key = rand() % num_ppages; 55 | { 56 | auto [success, ppage_id, pre_ref_count] = page_table.pin(key * stride); 57 | assert(success == true); 58 | assert(ppage_id == key); 59 | checksum += ppage_id + pre_ref_count; 60 | } 61 | { 62 | auto pre_ref_count = page_table.unpin(key * stride); 63 | checksum += pre_ref_count; 64 | } 65 | } 66 | auto end = std::chrono::high_resolution_clock::now(); 67 | 68 | #pragma omp critical 69 | { 70 | double throughput = 1e9 * num_requests / (end - start).count(); 71 | // printf("\t[%d] : %lf ops/s : %lu\n", omp_get_thread_num(), throughput, checksum); 72 | sum_checksum += checksum; 73 | sum_throughput += throughput; 74 | } 75 | } 76 | printf("Shared Stride : %lu \n, Request : %lf ops/s, checksum : %lu\n", stride, sum_throughput, sum_checksum); 77 | }; 78 | 79 | auto private_read_only = [&, num_vpages = num_vpages / omp_get_max_threads(), 80 | num_ppages = num_ppages / omp_get_max_threads()](size_t stride) 81 | { 82 | numa_set_localalloc(); 83 | size_t sum_checksum = 0; 84 | double sum_throughput = 0; 85 | #pragma omp parallel 86 | { 87 | scache::CompactHashPageTable page_table(num_vpages, num_ppages); 88 | 89 | for (uint64_t ppage_id = 0; ppage_id < num_ppages; ppage_id++) 90 | { 91 | auto vpage_id = ppage_id * stride; 92 | auto hint = page_table.find_or_create_hint(vpage_id); 93 | auto success = page_table.create_mapping(vpage_id, ppage_id); 94 | assert(success == true); 95 | success = page_table.release_mapping_lock(vpage_id); 96 | assert(success == true); 97 | } 98 | 99 | std::mt19937_64 rand(omp_get_thread_num()); 100 | size_t checksum = 0; 101 | auto start = std::chrono::high_resolution_clock::now(); 102 | for (uint64_t i = 0; i < num_requests; i++) 103 | { 104 | auto key = rand() % num_ppages; 105 | { 106 | auto [success, ppage_id, pre_ref_count] = page_table.pin(key * stride); 107 | assert(success == true); 108 | assert(ppage_id == key); 109 | checksum += ppage_id + pre_ref_count; 110 | } 111 | { 112 | auto pre_ref_count = page_table.unpin(key * stride); 113 | checksum += pre_ref_count; 114 | } 115 | } 116 | auto end = std::chrono::high_resolution_clock::now(); 117 | 118 | #pragma omp critical 119 | { 120 | double throughput = 1e9 * num_requests / (end - start).count(); 121 | // printf("\t[%d] : %lf ops/s : %lu\n", omp_get_thread_num(), throughput, checksum); 122 | sum_checksum += checksum; 123 | sum_throughput += throughput; 124 | } 125 | } 126 | printf("Private Stride : %lu \n, Request : %lf ops/s, checksum : %lu\n", stride, sum_throughput, sum_checksum); 127 | }; 128 | 129 | for (size_t i = 1; i <= 8; i++) 130 | { 131 | read_only(i); 132 | private_read_only(i); 133 | } 134 | return 0; 135 | } 136 | -------------------------------------------------------------------------------- /bench/bench_hitrate_fastmap.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | const size_t PAGE_SIZE = 4096; 28 | 29 | int main(int argc, char **argv) 30 | { 31 | 32 | if (argc <= 4) 33 | { 34 | printf("usage: %s num_requests phy_size_in_GB partition_hit_rate is_allpage [file_path] ...\n", argv[0]); 35 | return 0; 36 | } 37 | 38 | const size_t num_requests = std::stoul(argv[1]); 39 | 40 | // const size_t phy_size = std::stoul(argv[2]) * (1lu << 30); 41 | // const size_t num_ppages = phy_size / PAGE_SIZE; 42 | 43 | printf("%lu %lu\n", std::stoul(argv[2]), std::stoul(argv[2]) * (1lu << 30)); 44 | const size_t virt_size = std::stoul(argv[2]) * (1lu << 30); 45 | const size_t num_vpages = virt_size / PAGE_SIZE; 46 | 47 | const double partition_hit_rate = std::stod(argv[3]); 48 | 49 | // const size_t num_vpages = (double) num_ppages / partition_hit_rate; 50 | // const size_t virt_size = num_vpages * PAGE_SIZE; 51 | 52 | const size_t num_ppages = (double)num_vpages * partition_hit_rate; 53 | const size_t phy_size = num_ppages * PAGE_SIZE; 54 | 55 | using item_type = uint64_t; 56 | const size_t items_per_page = PAGE_SIZE / sizeof(item_type); 57 | 58 | printf("NUM_THREADS: %d\n", omp_get_max_threads()); 59 | 60 | bool is_allpage = std::stoul(argv[4]); 61 | 62 | int fd = -1; 63 | char *pool = nullptr; 64 | if (argc > 5) 65 | { 66 | fd = open(argv[5], O_CREAT | O_RDWR, 0640); 67 | if (fd == -1) 68 | throw std::runtime_error(std::string("open path ") + argv[4] + " error."); 69 | pool = (char *)mmap(nullptr, virt_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 70 | if (pool == MAP_FAILED) 71 | throw std::runtime_error("mmap error."); 72 | int ret = madvise(pool, virt_size, MADV_RANDOM); 73 | if (ret != 0) 74 | throw std::runtime_error("madvise error."); 75 | } 76 | else 77 | { 78 | pool = (char *)mmap(nullptr, virt_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, fd, 0); 79 | } 80 | 81 | double sum_throughput = 0; 82 | 83 | #pragma omp parallel 84 | { 85 | auto my_cpu = sched_getcpu(); 86 | 87 | item_type check_sum = 0; 88 | std::mt19937_64 rand(omp_get_thread_num()); 89 | 90 | #pragma omp for schedule(dynamic, 64) 91 | for (size_t page_id = 0; page_id < num_ppages; page_id++) 92 | { 93 | auto pointer = pool + page_id * PAGE_SIZE; 94 | if (fd == -1) 95 | ((item_type *)pointer)[0] = page_id; // avoid dummy IO ops 96 | else 97 | check_sum += ((item_type *)pointer)[0]; 98 | } 99 | 100 | auto private_base = (num_ppages / omp_get_max_threads()) * omp_get_thread_num(); 101 | ; 102 | 103 | for (size_t private_hit_rate = 0; private_hit_rate <= 100; private_hit_rate += 5) 104 | { 105 | const size_t private_range = 106 | (private_hit_rate == 0) ? num_ppages : (num_ppages / omp_get_max_threads() * 100 / private_hit_rate); 107 | 108 | #pragma omp master 109 | sum_throughput = 0; 110 | 111 | #pragma omp barrier 112 | auto start = std::chrono::high_resolution_clock::now(); 113 | 114 | if (!is_allpage) 115 | { 116 | for (size_t i = 0; i < num_requests; i++) 117 | { 118 | auto page_id = rand() % num_vpages; 119 | if (page_id < num_ppages) 120 | page_id = (page_id % private_range + private_base) % num_ppages; 121 | auto pointer = pool + page_id * PAGE_SIZE; 122 | check_sum += ((item_type *)pointer)[rand() % items_per_page]; 123 | // ((item_type*)pointer)[rand() % items_per_page] += i; 124 | } 125 | } 126 | else 127 | { 128 | for (size_t i = 0; i < num_requests; i++) 129 | { 130 | auto page_id = rand() % num_vpages; 131 | if (page_id < num_ppages) 132 | page_id = (page_id % private_range + private_base) % num_ppages; 133 | auto pointer = pool + page_id * PAGE_SIZE; 134 | for (size_t j = 0; j < items_per_page; j++) 135 | { 136 | check_sum += ((item_type *)pointer)[j]; 137 | // ((item_type*)pointer)[j] += i; 138 | } 139 | } 140 | } 141 | 142 | #pragma omp barrier 143 | auto end = std::chrono::high_resolution_clock::now(); 144 | 145 | #pragma omp critical 146 | { 147 | double throughput = 1e9 * num_requests / (end - start).count(); 148 | printf("\t[%d] : %lf ops/s : %lu\n", my_cpu, throughput, check_sum); 149 | sum_throughput += throughput; 150 | } 151 | 152 | #pragma omp barrier 153 | #pragma omp master 154 | printf("SharedHitRate = %lf , PrivateHitRate = %lf , Request : %lf ops/s\n", partition_hit_rate, 155 | 0.01 * private_hit_rate, sum_throughput); 156 | } 157 | } 158 | 159 | system("sh $TRICACHE_ROOT/scripts/kexec.sh"); 160 | std::this_thread::sleep_for(std::chrono::hours(1)); 161 | 162 | return 0; 163 | } 164 | -------------------------------------------------------------------------------- /bench/bench_hitrate_mmap.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | const size_t PAGE_SIZE = 4096; 27 | 28 | int main(int argc, char **argv) 29 | { 30 | 31 | if (argc <= 4) 32 | { 33 | printf("usage: %s num_requests phy_size_in_GB partition_hit_rate is_allpage [file_path] ...\n", argv[0]); 34 | return 0; 35 | } 36 | 37 | const size_t num_requests = std::stoul(argv[1]); 38 | 39 | // const size_t phy_size = std::stoul(argv[2]) * (1lu << 30); 40 | // const size_t num_ppages = phy_size / PAGE_SIZE; 41 | 42 | printf("%lu %lu\n", std::stoul(argv[2]), std::stoul(argv[2]) * (1lu << 30)); 43 | const size_t virt_size = std::stoul(argv[2]) * (1lu << 30); 44 | const size_t num_vpages = virt_size / PAGE_SIZE; 45 | 46 | const double partition_hit_rate = std::stod(argv[3]); 47 | 48 | // const size_t num_vpages = (double) num_ppages / partition_hit_rate; 49 | // const size_t virt_size = num_vpages * PAGE_SIZE; 50 | 51 | const size_t num_ppages = (double)num_vpages * partition_hit_rate; 52 | const size_t phy_size = num_ppages * PAGE_SIZE; 53 | 54 | using item_type = uint64_t; 55 | const size_t items_per_page = PAGE_SIZE / sizeof(item_type); 56 | 57 | printf("NUM_THREADS: %d\n", omp_get_max_threads()); 58 | 59 | bool is_allpage = std::stoul(argv[4]); 60 | 61 | int fd = -1; 62 | char *pool = nullptr; 63 | if (argc > 5) 64 | { 65 | fd = open(argv[5], O_CREAT | O_RDWR, 0640); 66 | if (fd == -1) 67 | throw std::runtime_error(std::string("open path ") + argv[4] + " error."); 68 | pool = (char *)mmap(nullptr, virt_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 69 | if (pool == MAP_FAILED) 70 | throw std::runtime_error("mmap error."); 71 | int ret = madvise(pool, virt_size, MADV_RANDOM); 72 | if (ret != 0) 73 | throw std::runtime_error("madvise error."); 74 | } 75 | else 76 | { 77 | pool = (char *)mmap(nullptr, virt_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, fd, 0); 78 | } 79 | 80 | double sum_throughput = 0; 81 | 82 | #pragma omp parallel 83 | { 84 | auto my_cpu = sched_getcpu(); 85 | 86 | item_type check_sum = 0; 87 | std::mt19937_64 rand(omp_get_thread_num()); 88 | 89 | #pragma omp for schedule(dynamic, 64) 90 | for (size_t page_id = 0; page_id < num_ppages; page_id++) 91 | { 92 | auto pointer = pool + page_id * PAGE_SIZE; 93 | if (fd == -1) 94 | ((item_type *)pointer)[0] = page_id; // avoid dummy IO ops 95 | else 96 | check_sum += ((item_type *)pointer)[0]; 97 | } 98 | 99 | auto private_base = (num_ppages / omp_get_max_threads()) * omp_get_thread_num(); 100 | ; 101 | 102 | for (size_t private_hit_rate = 0; private_hit_rate <= 100; private_hit_rate += 5) 103 | { 104 | const size_t private_range = 105 | (private_hit_rate == 0) ? num_ppages : (num_ppages / omp_get_max_threads() * 100 / private_hit_rate); 106 | 107 | #pragma omp master 108 | sum_throughput = 0; 109 | 110 | #pragma omp barrier 111 | auto start = std::chrono::high_resolution_clock::now(); 112 | 113 | if (!is_allpage) 114 | { 115 | for (size_t i = 0; i < num_requests; i++) 116 | { 117 | auto page_id = rand() % num_vpages; 118 | if (page_id < num_ppages) 119 | page_id = (page_id % private_range + private_base) % num_ppages; 120 | auto pointer = pool + page_id * PAGE_SIZE; 121 | check_sum += ((item_type *)pointer)[rand() % items_per_page]; 122 | // ((item_type*)pointer)[rand() % items_per_page] += i; 123 | } 124 | } 125 | else 126 | { 127 | for (size_t i = 0; i < num_requests; i++) 128 | { 129 | auto page_id = rand() % num_vpages; 130 | if (page_id < num_ppages) 131 | page_id = (page_id % private_range + private_base) % num_ppages; 132 | auto pointer = pool + page_id * PAGE_SIZE; 133 | for (size_t j = 0; j < items_per_page; j++) 134 | { 135 | check_sum += ((item_type *)pointer)[j]; 136 | // ((item_type*)pointer)[j] += i; 137 | } 138 | } 139 | } 140 | 141 | #pragma omp barrier 142 | auto end = std::chrono::high_resolution_clock::now(); 143 | 144 | #pragma omp critical 145 | { 146 | double throughput = 1e9 * num_requests / (end - start).count(); 147 | printf("\t[%d] : %lf ops/s : %lu\n", my_cpu, throughput, check_sum); 148 | sum_throughput += throughput; 149 | } 150 | 151 | #pragma omp barrier 152 | #pragma omp master 153 | printf("SharedHitRate = %lf , PrivateHitRate = %lf , Request : %lf ops/s\n", partition_hit_rate, 154 | 0.01 * private_hit_rate, sum_throughput); 155 | } 156 | } 157 | 158 | munmap(pool, virt_size); 159 | if (fd != -1) 160 | close(fd); 161 | 162 | return 0; 163 | } 164 | -------------------------------------------------------------------------------- /bench/bench_partition_server_client.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "partition_client.hpp" 16 | #include "partition_server.hpp" 17 | #include "partition_type.hpp" 18 | #include "partitioner.hpp" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | const size_t num_servers_per_numa = 2; 29 | const size_t num_requests = 5000000; 30 | const size_t range = 1lu << 48; 31 | int main() 32 | { 33 | auto num_numas = numa_num_configured_nodes(); 34 | std::vector num_servers(numa_max_node() + 1, 0); 35 | std::vector server_cpus; 36 | for (size_t i = 0; i < std::thread::hardware_concurrency(); i++) 37 | { 38 | auto numa_id = numa_node_of_cpu(i); 39 | if (num_servers[numa_id] < num_servers_per_numa) 40 | { 41 | server_cpus.emplace_back(i); 42 | num_servers[numa_id]++; 43 | } 44 | } 45 | scache::RoundRobinPartitioner partioner(num_numas * num_servers_per_numa, 0); 46 | 47 | struct Context 48 | { 49 | Context(size_t _data) : data(_data) {} 50 | size_t data; 51 | }; 52 | 53 | auto create_context = [](size_t sid) FORCE_INLINE { return Context(123); }; 54 | 55 | struct RequestContext 56 | { 57 | int status; 58 | }; 59 | 60 | auto preprocess_func = [](auto &context, const scache::request_type &req) FORCE_INLINE {}; 61 | 62 | auto first_equal_func = [](auto &context, const scache::request_type &req, scache::response_type &resp) FORCE_INLINE 63 | { 64 | // resp.pointer = (void*)(uintptr_t)req.page_id; 65 | // return std::optional(std::nullopt); 66 | resp.pointer = nullptr; 67 | return std::make_optional(RequestContext{0}); 68 | }; 69 | 70 | auto equal_func = [](auto &context, RequestContext &req_context, const scache::request_type &req) FORCE_INLINE 71 | { 72 | if (++req_context.status < 5) 73 | return false; 74 | 75 | req.resp->pointer = (void *)(uintptr_t)req.page_id; 76 | return true; 77 | }; 78 | 79 | auto destroy_context = [](auto &context) FORCE_INLINE {}; 80 | 81 | scache::PartitionServer server(server_cpus, omp_get_max_threads()); 82 | server.run(create_context, preprocess_func, first_equal_func, equal_func, destroy_context); 83 | 84 | double sum_throughput = 0; 85 | #pragma omp parallel 86 | { 87 | scache::PartitionClient client(server); 88 | #pragma omp barrier 89 | 90 | auto my_cpu = sched_getcpu(); 91 | bool is_server = false; 92 | for (auto cpu : server_cpus) 93 | { 94 | if (cpu == my_cpu) 95 | is_server = true; 96 | } 97 | if (!is_server) 98 | { 99 | std::mt19937_64 rand(omp_get_thread_num()); 100 | 101 | auto start = std::chrono::high_resolution_clock::now(); 102 | 103 | size_t ref = 0, sum = 0; 104 | 105 | const size_t num_fibers = scache::MAX_FIBERS_PER_THREAD; 106 | std::vector fibers; 107 | for (size_t i = 0; i < num_fibers; i++) 108 | { 109 | fibers.emplace_back(boost::fibers::launch::dispatch, 110 | [&, fid = i]() 111 | { 112 | for (size_t i = fid; i < num_requests; i += num_fibers) 113 | { 114 | auto key = rand() % range + 1; 115 | ref += key; 116 | scache::cacheline_aligned_type response; 117 | response().pointer = nullptr; 118 | scache::request_type request; 119 | request.page_id = key; 120 | request.resp = &response(); 121 | auto [sid, _] = partioner(key); 122 | auto epoch = client.request(sid, request, &response()); 123 | while (!response().pointer) 124 | { 125 | boost::this_fiber::yield(); 126 | client.poll_message(sid, epoch); 127 | } 128 | sum += (size_t)response().pointer; 129 | } 130 | }); 131 | } 132 | for (auto &f : fibers) 133 | f.join(); 134 | client.wait(); 135 | 136 | auto end = std::chrono::high_resolution_clock::now(); 137 | 138 | #pragma omp critical 139 | { 140 | double throughput = 1e9 * num_requests / (end - start).count(); 141 | printf("\t[%d] : %lf ops/s, %s : %lu, %lu\n", my_cpu, throughput, ref == sum ? "Success" : "Failed", 142 | ref, sum); 143 | sum_throughput += throughput; 144 | } 145 | } 146 | } 147 | 148 | printf("Request : %lf ops/s\n", sum_throughput); 149 | } 150 | -------------------------------------------------------------------------------- /bench/bench_private_cache.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "direct_cache.hpp" 16 | #include "private_cache.hpp" 17 | #include "shared_cache.hpp" 18 | #include "type.hpp" 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | const size_t virt_size = 128lu * (1 << 30); 26 | const size_t num_vpages = virt_size / scache::CACHE_PAGE_SIZE; 27 | const size_t phy_size = 128lu * (1 << 30); 28 | const size_t num_ppages = phy_size / scache::CACHE_PAGE_SIZE; 29 | const size_t num_requests = 5000000; 30 | 31 | int main(int argc, char **argv) 32 | { 33 | const size_t private_range = num_vpages / omp_get_max_threads(); 34 | 35 | if (argc <= 1) 36 | { 37 | printf("usage: %s cpu_id,file_path ...\n", argv[0]); 38 | return 0; 39 | } 40 | 41 | std::vector server_cpus; 42 | std::vector server_paths; 43 | 44 | for (int i = 1; i < argc; i++) 45 | { 46 | auto str = std::string(argv[i]); 47 | auto pos = str.find(","); 48 | auto cpu = std::stoul(str.substr(0, pos)); 49 | auto path = str.substr(pos + 1); 50 | printf("%lu %s\n", cpu, path.c_str()); 51 | server_cpus.emplace_back(cpu); 52 | server_paths.emplace_back(path); 53 | } 54 | 55 | scache::SharedCache shared_cache(virt_size, phy_size, server_cpus, server_paths, omp_get_max_threads()); 56 | 57 | std::vector count(num_vpages); 58 | for (auto &c : count) 59 | c = 0; 60 | 61 | double sum_throughput = 0; 62 | #pragma omp parallel 63 | { 64 | scache::PrivateCache cache(shared_cache); 65 | #pragma omp barrier 66 | // auto &cache = shared_cache; 67 | 68 | auto my_cpu = sched_getcpu(); 69 | bool is_server = false; 70 | for (auto cpu : server_cpus) 71 | { 72 | if (cpu == my_cpu || cpu + std::thread::hardware_concurrency() / 2 == my_cpu) 73 | is_server = true; 74 | } 75 | if (!is_server) 76 | { 77 | uintptr_t sum = 0; 78 | std::mt19937_64 rand(omp_get_thread_num()); 79 | auto private_base = rand() % num_vpages; 80 | 81 | auto start = std::chrono::high_resolution_clock::now(); 82 | 83 | const size_t num_fibers = scache::MAX_FIBERS_PER_THREAD; 84 | std::vector fibers; 85 | for (size_t i = 0; i < num_fibers; i++) 86 | { 87 | auto fid = 0; 88 | fibers.emplace_back(boost::fibers::launch::dispatch, 89 | [&, fid = i]() 90 | { 91 | // auto direct_cache = scache::DirectCache(cache); 92 | for (size_t i = fid; i < num_requests; i += num_fibers) 93 | { 94 | // auto key = rand()%num_vpages; 95 | auto key = (rand() % private_range + private_base) % num_vpages; 96 | auto pointer = cache.pin(key); 97 | // auto pointer = direct_cache.access(key, true); 98 | // auto pre = __atomic_fetch_add((size_t*)pointer, 1, __ATOMIC_SEQ_CST); 99 | // printf("[%lu] %p: %lu %lu\n", key, pointer, pre, *(size_t*)pointer); 100 | // count[key]+=1; 101 | sum += reinterpret_cast(pointer); 102 | cache.unpin(key, true); 103 | } 104 | }); 105 | } 106 | for (auto &f : fibers) 107 | f.join(); 108 | 109 | auto end = std::chrono::high_resolution_clock::now(); 110 | 111 | #pragma omp critical 112 | { 113 | double throughput = 1e9 * num_requests / (end - start).count(); 114 | printf("\t[%d] : %lf ops/s : %lu\n", my_cpu, throughput, sum); 115 | sum_throughput += throughput; 116 | } 117 | } 118 | #pragma omp barrier 119 | #pragma omp master 120 | printf("Request : %lf ops/s\n", sum_throughput); 121 | 122 | #if false 123 | #pragma omp for schedule(dynamic, 64) 124 | for(size_t i=0;i(i*scache::CACHE_PAGE_SIZE); 127 | if(res != count[i]) 128 | { 129 | printf("[%lu] %lu != %lu, \n", i, res, count[i].load()); 130 | throw std::runtime_error("Check Error"); 131 | } 132 | if(i % 10000000 == 0 && i) printf("Checked %lu pages\n", i); 133 | } 134 | #endif 135 | } 136 | 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /bench/bench_shared_cache.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "shared_cache.hpp" 16 | #include "type.hpp" 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | const size_t virt_size = 128lu * (1 << 30); 24 | const size_t num_vpages = virt_size / scache::CACHE_PAGE_SIZE; 25 | const size_t phy_size = 16lu * (1 << 30); 26 | const size_t num_requests = 1000000; 27 | 28 | int main(int argc, char **argv) 29 | { 30 | if (argc <= 1) 31 | { 32 | printf("usage: %s cpu_id,file_path ...\n", argv[0]); 33 | return 0; 34 | } 35 | 36 | std::vector server_cpus; 37 | std::vector server_paths; 38 | 39 | for (int i = 1; i < argc; i++) 40 | { 41 | auto str = std::string(argv[i]); 42 | auto pos = str.find(","); 43 | auto cpu = std::stoul(str.substr(0, pos)); 44 | auto path = str.substr(pos + 1); 45 | printf("%lu %s\n", cpu, path.c_str()); 46 | server_cpus.emplace_back(cpu); 47 | server_paths.emplace_back(path); 48 | } 49 | 50 | scache::SharedCache cache(virt_size, phy_size, server_cpus, server_paths, std::thread::hardware_concurrency()); 51 | 52 | std::vector count(num_vpages); 53 | for (auto &c : count) 54 | c = 0; 55 | 56 | double sum_throughput = 0; 57 | #pragma omp parallel 58 | { 59 | auto my_cpu = sched_getcpu(); 60 | bool is_server = false; 61 | for (auto cpu : server_cpus) 62 | { 63 | if (cpu == my_cpu || cpu + std::thread::hardware_concurrency() / 2 == my_cpu) 64 | is_server = true; 65 | } 66 | if (!is_server) 67 | { 68 | std::mt19937_64 rand(omp_get_thread_num()); 69 | 70 | auto start = std::chrono::high_resolution_clock::now(); 71 | 72 | const size_t num_fibers = scache::MAX_FIBERS_PER_THREAD; 73 | std::vector fibers; 74 | for (size_t i = 0; i < num_fibers; i++) 75 | { 76 | auto fid = 0; 77 | fibers.emplace_back(boost::fibers::launch::dispatch, 78 | [&, fid = i]() 79 | { 80 | for (size_t i = fid; i < num_requests; i += num_fibers) 81 | { 82 | auto key = rand() % num_vpages; 83 | auto pointer = cache.pin(key); 84 | // auto pre = __atomic_fetch_add((size_t*)pointer, 1, __ATOMIC_SEQ_CST); 85 | // printf("[%lu] %p: %lu %lu\n", key, pointer, pre, *(size_t*)pointer); 86 | // count[key]+=1; 87 | cache.unpin(key, true); 88 | } 89 | }); 90 | } 91 | for (auto &f : fibers) 92 | f.join(); 93 | 94 | auto end = std::chrono::high_resolution_clock::now(); 95 | 96 | #pragma omp critical 97 | { 98 | double throughput = 1e9 * num_requests / (end - start).count(); 99 | printf("\t[%d] : %lf ops/s\n", my_cpu, throughput); 100 | sum_throughput += throughput; 101 | } 102 | 103 | cache.del_client(); 104 | } 105 | } 106 | 107 | printf("Request : %lf ops/s\n", sum_throughput); 108 | 109 | return 0; 110 | 111 | #pragma omp parallel for schedule(dynamic, 64) 112 | for (size_t i = 0; i < num_vpages; i++) 113 | { 114 | auto res = cache.get(i * scache::CACHE_PAGE_SIZE); 115 | if (res != count[i]) 116 | { 117 | printf("[%lu] %lu != %lu, \n", i, res, count[i].load()); 118 | throw std::runtime_error("Check Error"); 119 | } 120 | } 121 | 122 | #pragma omp parallel 123 | { 124 | cache.del_client(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /bench/bench_single_thread_cache.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "page_table.hpp" 16 | #include "replacement.hpp" 17 | #include "single_thread_cache.hpp" 18 | #include "type.hpp" 19 | #include 20 | #include 21 | #include 22 | 23 | const uint64_t num = 1 * (1lu << 30); 24 | const uint64_t size = 64 * (1lu << 30) / (1 << 12); 25 | const uint64_t range = 4096 * (1lu << 30) / (1 << 12); 26 | 27 | int main() 28 | { 29 | struct Empty 30 | { 31 | }; 32 | auto evict_func = [](Empty, scache::vpage_id_type, scache::ppage_id_type, bool, const Empty &) { return true; }; 33 | auto load_func = [](Empty, scache::vpage_id_type, scache::ppage_id_type, Empty &) { return true; }; 34 | scache::SingleThreadCache 36 | cache(range, size, evict_func, load_func); 37 | std::mt19937 rand; 38 | static_assert(std::mt19937::max() > range); 39 | 40 | std::this_thread::sleep_for(std::chrono::seconds(1)); 41 | 42 | { 43 | std::this_thread::sleep_for(std::chrono::seconds(1)); 44 | auto start = std::chrono::high_resolution_clock::now(); 45 | for (uint64_t i = 0; i < num; i++) 46 | { 47 | auto key = rand() % range; 48 | auto pin = cache.pin(key); 49 | while (pin.phase != decltype(pin)::Phase::End) 50 | cache.process(pin); 51 | auto unpin = cache.unpin(key); 52 | while (unpin.phase != decltype(unpin)::Phase::End) 53 | cache.process(unpin); 54 | } 55 | auto end = std::chrono::high_resolution_clock::now(); 56 | fprintf(stderr, "Pin/Unpin %.3lf OPs/s\n", 57 | 1e9 * num / std::chrono::duration_cast(end - start).count()); 58 | } 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /bench/bench_terasort_gnu.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #ifdef WITH_CACHE 25 | extern "C" void cache_reset_profile(); 26 | extern "C" void cache_dump_profile(); 27 | #else 28 | void cache_reset_profile() {} 29 | void cache_dump_profile() {} 30 | #endif 31 | 32 | const size_t item_size = 100; 33 | const size_t key_size = 10; 34 | 35 | struct Item 36 | { 37 | char str[item_size]; 38 | }; 39 | 40 | static_assert(sizeof(Item) == item_size); 41 | 42 | bool cmp_item(const Item &a, const Item &b) 43 | { 44 | for (int i = 0; i < key_size; i++) 45 | { 46 | if (a.str[i] < b.str[i]) 47 | return true; 48 | if (a.str[i] > b.str[i]) 49 | return false; 50 | } 51 | return false; 52 | } 53 | 54 | int main(int argc, char **argv) 55 | { 56 | if (argc <= 2) 57 | printf("usage: %s path num_threads\n", argv[0]); 58 | 59 | size_t num_threads = std::stoul(argv[2]); 60 | 61 | size_t total_items = 0; 62 | 63 | std::vector> files; 64 | auto directory = std::filesystem::path(argv[1]); 65 | for (auto f : std::filesystem::directory_iterator(directory)) 66 | { 67 | if (f.is_regular_file() && f.file_size() > 0 && f.file_size() % item_size == 0) 68 | { 69 | files.emplace_back(f.path(), total_items, f.file_size() / item_size); 70 | total_items += f.file_size() / item_size; 71 | } 72 | } 73 | 74 | printf("%lu items\n", total_items); 75 | 76 | Item *items = (Item *)malloc(total_items * sizeof(Item)); 77 | 78 | const size_t read_num_threads = 32; 79 | for (size_t i = 0; i < files.size(); i += read_num_threads) 80 | { 81 | printf("load %lu files\n", i); 82 | std::vector load_threads; 83 | for (size_t j = 0; j < read_num_threads && i + j < files.size(); j++) 84 | { 85 | auto [path, start, num_items] = files[i + j]; 86 | load_threads.emplace_back( 87 | [&, path = path, start = start, num_items = num_items]() 88 | { 89 | auto f = std::ifstream(path); 90 | f.read((char *)(items + start), num_items * item_size); 91 | }); 92 | } 93 | for (auto &t : load_threads) 94 | t.join(); 95 | } 96 | 97 | cache_reset_profile(); 98 | auto start = std::chrono::high_resolution_clock::now(); 99 | __gnu_parallel::sort(items, items + total_items, cmp_item, __gnu_parallel::multiway_mergesort_tag()); 100 | auto end = std::chrono::high_resolution_clock::now(); 101 | cache_dump_profile(); 102 | 103 | #if (!DISABLE_DIRECT_CACHE && !DISABLE_PRIVATE_CACHE) 104 | size_t checksum = 0; 105 | #pragma omp parallel for reduction(+:checksum) 106 | for (size_t i = 0; i < total_items; i++) 107 | { 108 | for (size_t j = 0; j < item_size; j++) 109 | { 110 | checksum += j ^ items[i].str[j]; 111 | } 112 | } 113 | 114 | size_t errors = 0; 115 | #pragma omp parallel for reduction(+:errors) 116 | for (size_t i = 0; i < total_items - 1; i++) 117 | { 118 | if (cmp_item(items[i + 1], items[i])) 119 | errors += 1; 120 | } 121 | 122 | printf("checksum %lu, errors %lu\n", checksum, errors); 123 | #endif 124 | 125 | printf("exec %lf s\n", 1e-9 * (end - start).count()); 126 | 127 | free(items); 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /bench/bench_terasort_manual.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #ifdef WITH_CACHE 29 | extern "C" void cache_reset_profile(); 30 | extern "C" void cache_dump_profile(); 31 | #else 32 | void cache_reset_profile() {} 33 | void cache_dump_profile() {} 34 | #endif 35 | 36 | const size_t item_size = 100; 37 | const size_t key_size = 10; 38 | 39 | struct Item 40 | { 41 | char str[item_size]; 42 | }; 43 | 44 | static_assert(sizeof(Item) == item_size); 45 | 46 | bool cmp_item(const Item &a, const Item &b) 47 | { 48 | for (int i = 0; i < key_size; i++) 49 | { 50 | if (a.str[i] < b.str[i]) 51 | return true; 52 | if (a.str[i] > b.str[i]) 53 | return false; 54 | } 55 | return false; 56 | } 57 | 58 | int main(int argc, char **argv) 59 | { 60 | if (argc <= 1) 61 | printf("usage: %s path\n", argv[0]); 62 | 63 | size_t num_threads = omp_get_max_threads(); 64 | 65 | size_t total_items = 0; 66 | 67 | std::vector> files; 68 | auto directory = std::filesystem::path(argv[1]); 69 | for (auto f : std::filesystem::directory_iterator(directory)) 70 | { 71 | if (f.is_regular_file() && f.file_size() > 0 && f.file_size() % item_size == 0) 72 | { 73 | files.emplace_back(f.path(), total_items, f.file_size() / item_size); 74 | total_items += f.file_size() / item_size; 75 | } 76 | } 77 | 78 | printf("%lu items\n", total_items); 79 | 80 | Item *items = (Item *)malloc(total_items * sizeof(Item)); 81 | 82 | const size_t read_num_threads = 32; 83 | for (size_t i = 0; i < files.size(); i += read_num_threads) 84 | { 85 | printf("load %lu files\n", i); 86 | std::vector load_threads; 87 | for (size_t j = 0; j < read_num_threads && i + j < files.size(); j++) 88 | { 89 | auto [path, start, num_items] = files[i + j]; 90 | load_threads.emplace_back( 91 | [&, path = path, start = start, num_items = num_items]() 92 | { 93 | auto f = std::ifstream(path); 94 | f.read((char *)(items + start), num_items * item_size); 95 | }); 96 | } 97 | for (auto &t : load_threads) 98 | t.join(); 99 | } 100 | 101 | cache_reset_profile(); 102 | 103 | Item *sorted_items = (Item *)malloc(total_items * sizeof(Item)); 104 | 105 | auto pre = std::chrono::high_resolution_clock::now(); 106 | 107 | const size_t char_range = 1 << 8; 108 | 109 | std::atomic_size_t counts[char_range * num_threads + 1]; 110 | for (size_t i = 0; i <= char_range * num_threads; i++) 111 | counts[i] = 0; 112 | 113 | #pragma omp parallel for schedule(static) 114 | for (size_t i = 0; i < total_items; i++) 115 | { 116 | auto slot = num_threads * (unsigned char)(items[i].str[0] + (1 << 7)) + omp_get_thread_num(); 117 | counts[slot] += 1; 118 | } 119 | 120 | for (size_t i = 1; i <= char_range * num_threads; i++) 121 | counts[i] += counts[i - 1]; 122 | 123 | auto pre1 = std::chrono::high_resolution_clock::now(); 124 | 125 | #pragma omp parallel for schedule(static) 126 | for (size_t i = 0; i < total_items; i++) 127 | { 128 | auto slot = num_threads * (unsigned char)(items[i].str[0] + (1 << 7)) + omp_get_thread_num(); 129 | memcpy(sorted_items[--counts[slot]].str, items[i].str, item_size); 130 | } 131 | 132 | free(items); 133 | 134 | auto start = std::chrono::high_resolution_clock::now(); 135 | for (size_t i = 0; i < char_range; i++) 136 | { 137 | __gnu_parallel::sort(sorted_items + counts[i * num_threads], sorted_items + counts[(i + 1) * num_threads], 138 | cmp_item, __gnu_parallel::multiway_mergesort_tag()); 139 | } 140 | auto end = std::chrono::high_resolution_clock::now(); 141 | cache_dump_profile(); 142 | 143 | #if (!DISABLE_DIRECT_CACHE && !DISABLE_PRIVATE_CACHE) 144 | size_t checksum = 0; 145 | #pragma omp parallel for reduction(+:checksum) 146 | for (size_t i = 0; i < total_items; i++) 147 | { 148 | for (size_t j = 0; j < item_size; j++) 149 | { 150 | checksum += j ^ sorted_items[i].str[j]; 151 | } 152 | } 153 | 154 | size_t errors = 0; 155 | #pragma omp parallel for reduction(+:errors) 156 | for (size_t i = 0; i < total_items - 1; i++) 157 | { 158 | if (cmp_item(sorted_items[i + 1], sorted_items[i])) 159 | errors += 1; 160 | } 161 | 162 | printf("checksum %lu, errors %lu\n", checksum, errors); 163 | #endif 164 | 165 | printf("pre1 %lf s\n", 1e-9 * (pre1 - pre).count()); 166 | printf("pre2 %lf s\n", 1e-9 * (start - pre1).count()); 167 | printf("exec %lf s\n", 1e-9 * (end - pre).count()); 168 | 169 | free(sorted_items); 170 | return 0; 171 | } 172 | -------------------------------------------------------------------------------- /bind/cache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Guanyu Feng and Huanqi Cao, Tsinghua University 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" 23 | { 24 | #endif 25 | extern size_t *__client_cpus; 26 | extern size_t __num_client_cpus; 27 | 28 | // load env: CACHE_PHY_SIZE, CACHE_VIRT_SIZE, CACHE_CONFIG, CACHE_NUM_CLIENTS 29 | extern __attribute__((constructor)) void init(); 30 | extern __attribute__((destructor)) void deinit(); 31 | extern bool cache_space_ptr(const void *ptr); 32 | extern const void *cache_get_raw_ptr_load(const void *ptr); 33 | extern void *cache_get_raw_ptr_store(void *ptr); 34 | extern void *cache_alloc(size_t size); 35 | extern void cache_free(void *ptr, size_t size); 36 | extern void *cache_pin(void *ptr); 37 | extern void cache_unpin(void *ptr, bool is_write); 38 | extern void cache_flush(); 39 | 40 | extern void *cache_memcpy(void *__restrict dst, const void *__restrict src, size_t size); 41 | extern void *cache_memset(void *dst, int ch, size_t size); 42 | extern void *cache_memmove(void *dst, const void *src, size_t size); 43 | extern void *cache_memchr(const void *str, int c, size_t n); 44 | 45 | extern void *cache_malloc_hook(size_t size); 46 | extern void *cache_calloc_hook(size_t n_elem, size_t elem_sz); 47 | extern void *cache_realloc_hook(void *ptr, size_t size); 48 | extern void *cache_aligned_alloc_hook(size_t alignment, size_t size); 49 | extern void *cache_mmap_hook(void *addr, size_t len, int prot, int flags, int fd, off_t offset); 50 | 51 | extern void cache_reset_profile(); 52 | extern void cache_dump_profile(); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /bind/hook.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng and Huanqi Cao, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "cache.h" 16 | 17 | extern "C" 18 | { 19 | extern void *memcpy(void *__restrict dst, const void *__restrict src, size_t size); 20 | extern void *memset(void *dst, int ch, size_t size); 21 | extern void *memmove(void *dst, const void *src, size_t size); 22 | extern void *memchr(const void *str, int c, size_t n); 23 | } 24 | 25 | void *memcpy(void *__restrict dst, const void *__restrict src, size_t n) { return cache_memcpy(dst, src, n); } 26 | 27 | void *memset(void *dst, int c, size_t n) { return cache_memset(dst, c, n); } 28 | 29 | void *memmove(void *dst, const void *src, size_t n) { return cache_memmove(dst, src, n); } 30 | 31 | void *memchr(const void *str, int c, size_t n) { return cache_memchr(str, c, n); } 32 | 33 | // void* operator new(size_t size) { return cache_malloc_hook(size); } 34 | // void* operator new[](size_t size) { return cache_malloc_hook(size); } 35 | void operator delete(void *ptr) noexcept { free(ptr); } 36 | void operator delete[](void *ptr) noexcept { free(ptr); } 37 | -------------------------------------------------------------------------------- /cmake/Findaio.cmake: -------------------------------------------------------------------------------- 1 | # - Find aio 2 | # 3 | # AIO_INCLUDE - Where to find libaio.h 4 | # AIO_LIBS - List of libraries when using AIO. 5 | # AIO_FOUND - True if AIO found. 6 | 7 | find_path(AIO_INCLUDE_DIR 8 | libaio.h 9 | HINTS ${AIO_ROOT}/include) 10 | 11 | find_library(AIO_LIBRARIES 12 | libaio.a 13 | aio 14 | HINTS ${AIO_ROOT}/lib) 15 | 16 | include(FindPackageHandleStandardArgs) 17 | find_package_handle_standard_args(aio DEFAULT_MSG AIO_LIBRARIES AIO_INCLUDE_DIR) 18 | 19 | mark_as_advanced(AIO_INCLUDE_DIR AIO_LIBRARIES) 20 | 21 | -------------------------------------------------------------------------------- /cmake/Findnuma.cmake: -------------------------------------------------------------------------------- 1 | # Module for locating libnuma 2 | # 3 | # Read-only variables: 4 | # NUMA_FOUND 5 | # Indicates that the library has been found. 6 | # 7 | # NUMA_INCLUDE_DIR 8 | # Points to the libnuma include directory. 9 | # 10 | # NUMA_LIBRARY_DIRS 11 | # Points to the directory that contains the libraries. 12 | # The content of this variable can be passed to link_directories. 13 | # 14 | # NUMA_LIBRARIES 15 | # Points to the libnuma that can be passed to target_link_libararies. 16 | # 17 | # Copyright (c) 2013-2020 MulticoreWare, Inc 18 | 19 | include(FindPackageHandleStandardArgs) 20 | 21 | find_path(NUMA_ROOT_DIR 22 | NAMES include/numa.h 23 | PATHS ENV NUMA_ROOT 24 | DOC "NUMA root directory") 25 | 26 | find_path(NUMA_INCLUDE_DIR 27 | NAMES numa.h 28 | HINTS ${NUMA_ROOT_DIR} 29 | PATH_SUFFIXES include 30 | DOC "NUMA include directory") 31 | 32 | find_library(NUMA_LIBRARIES 33 | NAMES numa 34 | HINTS ${NUMA_ROOT_DIR} 35 | DOC "NUMA library") 36 | 37 | if (NUMA_LIBRARY) 38 | get_filename_component(NUMA_LIBRARY_DIRS ${NUMA_LIBRARY} PATH) 39 | endif() 40 | 41 | mark_as_advanced(NUMA_INCLUDE_DIR NUMA_LIBRARY_DIRS NUMA_LIBRARIES) 42 | 43 | find_package_handle_standard_args(numa REQUIRED_VARS NUMA_ROOT_DIR NUMA_INCLUDE_DIR NUMA_LIBRARIES) 44 | -------------------------------------------------------------------------------- /cmake/Finduring.cmake: -------------------------------------------------------------------------------- 1 | # - Find uring 2 | # 3 | # URING_INCLUDE_DIR - Where to find liburing.h 4 | # URING_LIBRARIES - List of libraries when using uring. 5 | # URING_FOUND - True if uring found. 6 | 7 | find_path(URING_INCLUDE_DIR 8 | liburing.h 9 | HINTS ${URING_ROOT}/include) 10 | 11 | find_library(URING_LIBRARIES 12 | liburing.a 13 | uring 14 | HINTS ${URING_ROOT}/lib) 15 | 16 | include(FindPackageHandleStandardArgs) 17 | find_package_handle_standard_args(uring DEFAULT_MSG URING_LIBRARIES URING_INCLUDE_DIR) 18 | 19 | mark_as_advanced(URING_INCLUDE_DIR URING_LIBRARIES) 20 | 21 | -------------------------------------------------------------------------------- /deps/spdk.patch: -------------------------------------------------------------------------------- 1 | # For SPDK 21.04 2 | Submodule dpdk contains modified content 3 | diff --git a/dpdk/config/rte_config.h b/dpdk/config/rte_config.h 4 | index a0b5160ff2..3811242cc2 100644 5 | --- a/dpdk/config/rte_config.h 6 | +++ b/dpdk/config/rte_config.h 7 | @@ -31,8 +31,8 @@ 8 | /* EAL defines */ 9 | #define RTE_MAX_HEAPS 32 10 | #define RTE_MAX_MEMSEG_LISTS 128 11 | -#define RTE_MAX_MEMSEG_PER_LIST 8192 12 | -#define RTE_MAX_MEM_MB_PER_LIST 32768 13 | +#define RTE_MAX_MEMSEG_PER_LIST 32768 14 | +#define RTE_MAX_MEM_MB_PER_LIST 65536 15 | #define RTE_MAX_MEMSEG_PER_TYPE 32768 16 | #define RTE_MAX_MEM_MB_PER_TYPE 65536 17 | #define RTE_MAX_MEMZONE 2560 18 | diff --git a/dpdkbuild/Makefile b/dpdkbuild/Makefile 19 | index b540d2fa0..f51a6fefb 100644 20 | --- a/dpdkbuild/Makefile 21 | +++ b/dpdkbuild/Makefile 22 | @@ -81,6 +81,8 @@ with e.g. `meson build --cross-file config/arm/arm64_armv8_linux_gcc`) 23 | endif 24 | endif 25 | 26 | +DPDK_OPTS += -Dmax_lcores=256 -Dmax_numa_nodes=8 27 | + 28 | DPDK_CFLAGS += -fPIC 29 | 30 | ifeq ($(CONFIG_WERROR),y) 31 | diff --git a/module/Makefile b/module/Makefile 32 | index 98b4b7757..f2dcb1062 100644 33 | --- a/module/Makefile 34 | +++ b/module/Makefile 35 | @@ -73,7 +73,7 @@ $(SOCK_MODULES_PKGCONFIG): 36 | $(Q)$(SPDK_ROOT_DIR)/scripts/pc_modules.sh sock "$(SOCK_MODULES_LIST:%=spdk_%)" > $@ 37 | 38 | $(SYSLIBS_PKGCONFIG): 39 | - $(Q)$(SPDK_ROOT_DIR)/scripts/pc_libs.sh "" "$(PRIVATE_SYSLIBS)" System spdk_syslibs > $@ 40 | + $(Q)$(SPDK_ROOT_DIR)/scripts/pc_libs.sh "$(PRIVATE_SYSLIBS)" "" System spdk_syslibs > $@ 41 | 42 | all: $(DIRS-y) $(MODULES_PKGCONFIG) 43 | 44 | -------------------------------------------------------------------------------- /include/access_counter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | 17 | #include 18 | #include 19 | 20 | namespace 21 | { 22 | inline uint64_t rdtsc() 23 | { 24 | unsigned int tmp; 25 | return __rdtscp(&tmp); 26 | } 27 | } // namespace 28 | 29 | #ifdef ENABLE_PROFILE 30 | class AccessCounter 31 | { 32 | private: 33 | std::atomic_uint64_t profile_num_access, profile_num_miss, profile_cycle_access, profile_cycle_miss; 34 | 35 | public: 36 | uint64_t get_profile_num_access() const { return profile_num_access; } 37 | uint64_t get_profile_num_miss() const { return profile_num_miss; } 38 | uint64_t get_profile_cycle_access() const { return profile_cycle_access; } 39 | uint64_t get_profile_cycle_miss() const { return profile_cycle_miss; } 40 | 41 | void count_access() { profile_num_access++; } 42 | void count_miss() { profile_num_miss++; } 43 | void count_access_with_cycles(uint64_t t) 44 | { 45 | count_access(); 46 | profile_cycle_access += t; 47 | } 48 | void count_miss_with_cycles(uint64_t t) 49 | { 50 | count_miss(); 51 | profile_cycle_miss += t; 52 | } 53 | void clear() { profile_num_access = profile_num_miss = profile_cycle_access = profile_cycle_miss = 0; } 54 | void flush(AccessCounter &other) 55 | { 56 | other.profile_num_access += profile_num_access; 57 | other.profile_num_miss += profile_num_miss; 58 | other.profile_cycle_access += profile_cycle_access; 59 | other.profile_cycle_miss += profile_cycle_miss; 60 | clear(); 61 | } 62 | 63 | AccessCounter() { clear(); } 64 | AccessCounter(const AccessCounter &other) 65 | { 66 | profile_num_access = other.profile_num_access.load(); 67 | profile_num_miss = other.profile_num_miss.load(); 68 | profile_cycle_access = other.profile_cycle_access.load(); 69 | profile_cycle_miss = other.profile_cycle_miss.load(); 70 | }; 71 | 72 | struct access_guard 73 | { 74 | AccessCounter &counter; 75 | uint64_t t; 76 | access_guard(AccessCounter &counter) : counter(counter), t(rdtsc()) {} 77 | ~access_guard() { counter.count_access_with_cycles(rdtsc() - t); } 78 | }; 79 | access_guard guard_access() { return *this; } 80 | 81 | struct miss_guard 82 | { 83 | AccessCounter &counter; 84 | uint64_t t; 85 | miss_guard(AccessCounter &counter) : counter(counter), t(rdtsc()) {} 86 | ~miss_guard() { counter.count_miss_with_cycles(rdtsc() - t); } 87 | }; 88 | miss_guard guard_miss() { return *this; } 89 | }; 90 | #else 91 | class AccessCounter 92 | { 93 | public: 94 | uint64_t get_profile_num_access() const { return 0; } 95 | uint64_t get_profile_num_miss() const { return 0; } 96 | uint64_t get_profile_cycle_access() const { return 0; } 97 | uint64_t get_profile_cycle_miss() const { return 0; } 98 | 99 | void count_access() {} 100 | void count_miss() {} 101 | void count_access_with_cycles(uint64_t t) {} 102 | void count_miss_with_cycles(uint64_t t) {} 103 | void clear() {} 104 | void flush(AccessCounter &other) {} 105 | 106 | struct empty_guard 107 | { 108 | }; 109 | empty_guard guard_access() { return {}; } 110 | empty_guard guard_miss() { return {}; } 111 | }; 112 | #endif 113 | 114 | enum GlobalCounters 115 | { 116 | GLOBAL_DIRECT, 117 | GLOBAL_PRIVATE, 118 | GLOBAL_COUNTER_NUM 119 | }; 120 | namespace 121 | { 122 | AccessCounter global_counters[GLOBAL_COUNTER_NUM]; 123 | } -------------------------------------------------------------------------------- /include/direct_cache.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include "access_counter.hpp" 17 | #include "private_cache.hpp" 18 | #include "shared_cache.hpp" 19 | #include "type.hpp" 20 | #include "util.hpp" 21 | 22 | namespace scache 23 | { 24 | template class DirectCache 25 | { 26 | public: 27 | DirectCache(Cache &_cache) 28 | : cache(_cache), 29 | num_pinned(std::min( 30 | MAX_NUM_PINNED, 31 | std::max(nextPowerOf2(_cache.actual_num_ppages_per_thread) / 4 / MAX_FIBERS_PER_THREAD, 1lu))), 32 | num_pinned_mask(num_pinned - 1) 33 | { 34 | store = (std::pair *)mmap_alloc( 35 | num_pinned * sizeof(std::pair), CACHELINE_SIZE); 36 | dirty = (bool *)mmap_alloc(num_pinned * sizeof(bool), CACHELINE_SIZE); 37 | for (size_t i = 0; i < num_pinned; i++) 38 | { 39 | store[i] = {EMPTY, nullptr}; 40 | dirty[i] = false; 41 | } 42 | } 43 | 44 | DirectCache(const DirectCache &) = delete; 45 | DirectCache(DirectCache &&) = delete; 46 | 47 | ~DirectCache() 48 | { 49 | flush(); 50 | mmap_free(store, num_pinned * sizeof(std::pair)); 51 | mmap_free(dirty, num_pinned * sizeof(bool)); 52 | } 53 | 54 | FORCE_INLINE void flush() 55 | { 56 | counter.flush(global_counters[GLOBAL_DIRECT]); 57 | for (size_t i = 0; i < num_pinned; i++) 58 | { 59 | if (store[i].first != EMPTY) 60 | cache.unpin(store[i].first, dirty[i]); 61 | store[i] = {EMPTY, nullptr}; 62 | dirty[i] = false; 63 | } 64 | } 65 | 66 | // The pointer is safe before next memory access 67 | FORCE_INLINE void *access(vpage_id_type vpage_id, bool is_write) 68 | { 69 | auto ga = counter.guard_access(); 70 | if (store[vpage_id & num_pinned_mask].first != vpage_id) 71 | { 72 | auto gm = counter.guard_miss(); 73 | if (store[vpage_id & num_pinned_mask].first != EMPTY) 74 | cache.unpin(store[vpage_id & num_pinned_mask].first, dirty[vpage_id & num_pinned_mask]); 75 | store[vpage_id & num_pinned_mask].first = vpage_id; 76 | store[vpage_id & num_pinned_mask].second = cache.pin(vpage_id); 77 | dirty[vpage_id & num_pinned_mask] = false; 78 | } 79 | dirty[vpage_id & num_pinned_mask] |= is_write; 80 | return store[vpage_id & num_pinned_mask].second; 81 | } 82 | 83 | private: 84 | constexpr static vpage_id_type EMPTY = std::numeric_limits::max(); 85 | constexpr static size_t MAX_NUM_PINNED = 1 << 30; 86 | Cache &cache; 87 | const size_t num_pinned; 88 | const size_t num_pinned_mask; 89 | std::pair *store; 90 | bool *dirty; 91 | 92 | AccessCounter counter; 93 | }; 94 | } // namespace scache 95 | -------------------------------------------------------------------------------- /include/memory_pool.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include "type.hpp" 17 | #include "util.hpp" 18 | #include 19 | 20 | namespace scache 21 | { 22 | class MemoryPool 23 | { 24 | public: 25 | MemoryPool(ppage_id_type _num_pages, void *_pool = nullptr) : num_pages(_num_pages) 26 | { 27 | if (_pool) 28 | { 29 | pool = (uint8_t *)_pool; 30 | is_external = true; 31 | } 32 | else 33 | { 34 | mmap_pool = (uint8_t *)mmap_alloc(num_pages * CACHE_PAGE_SIZE + CACHE_PAGE_SIZE); 35 | pool = mmap_pool + (CACHE_PAGE_SIZE - (uintptr_t)mmap_pool % CACHE_PAGE_SIZE) % CACHE_PAGE_SIZE; 36 | is_external = false; 37 | } 38 | 39 | first_loaded = (bool *)mmap_alloc(num_pages); 40 | } 41 | 42 | MemoryPool(const MemoryPool &) = delete; 43 | MemoryPool(MemoryPool &&) = delete; 44 | 45 | ~MemoryPool() 46 | { 47 | if (!is_external) 48 | mmap_free(mmap_pool, num_pages * CACHE_PAGE_SIZE + CACHE_PAGE_SIZE); 49 | 50 | mmap_free(first_loaded, num_pages); 51 | } 52 | 53 | void *from_page_id(const ppage_id_type &id) const 54 | { 55 | assert(id < num_pages); 56 | return pool + id * CACHE_PAGE_SIZE; 57 | } 58 | 59 | ppage_id_type to_page_id(void *ptr) const 60 | { 61 | assert((uintptr_t)ptr % num_pages == 0 && ptr > pool && ptr < pool + num_pages * CACHE_PAGE_SIZE); 62 | return ((uint8_t *)ptr - pool) / num_pages; 63 | } 64 | 65 | bool loaded(const ppage_id_type &id) 66 | { 67 | auto before = first_loaded[id]; 68 | first_loaded[id] = true; 69 | return before; 70 | } 71 | 72 | private: 73 | ppage_id_type num_pages; 74 | uint8_t *pool = nullptr; 75 | uint8_t *mmap_pool = nullptr; 76 | bool *first_loaded = nullptr; 77 | bool is_external; 78 | }; 79 | } // namespace scache 80 | -------------------------------------------------------------------------------- /include/page_table.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include "type.hpp" 17 | #include "util.hpp" 18 | #include 19 | #include 20 | #include 21 | 22 | namespace scache 23 | { 24 | template class HashPageTable 25 | { 26 | public: 27 | using value_type = ValueType; 28 | HashPageTable(const vpage_id_type &_max_vpage_id, 29 | const ppage_id_type &_max_ppage_id, 30 | const value_type &_empty_value = value_type()) 31 | : max_vpage_id(_max_vpage_id), max_ppage_id(_max_ppage_id), store(max_ppage_id) 32 | { 33 | } 34 | 35 | bool put(const vpage_id_type &vpage_id, const value_type &value) 36 | { 37 | auto iter = store.find(vpage_id); 38 | if (iter != store.end()) 39 | { 40 | iter.value() = value; 41 | return false; 42 | } 43 | store.emplace_hint(iter, vpage_id, value); 44 | return true; 45 | } 46 | 47 | std::optional get(const vpage_id_type &vpage_id) const 48 | { 49 | auto iter = store.find(vpage_id); 50 | if (iter == store.end()) 51 | return {}; 52 | return iter->second; 53 | } 54 | 55 | bool del(const vpage_id_type &vpage_id) { return store.erase(vpage_id); } 56 | 57 | void prefetch(const vpage_id_type &vpage_id) const {} 58 | 59 | private: 60 | const vpage_id_type max_vpage_id; 61 | const ppage_id_type max_ppage_id; 62 | tsl::hopscotch_map store; 63 | }; 64 | 65 | template class DirectPageTable 66 | { 67 | public: 68 | using value_type = ValueType; 69 | DirectPageTable(const vpage_id_type &_max_vpage_id, 70 | const ppage_id_type &_max_ppage_id, 71 | const value_type &_empty_value = value_type()) 72 | : max_vpage_id(_max_vpage_id), max_ppage_id(_max_ppage_id), empty_value(_empty_value) 73 | { 74 | store = (value_type *)mmap_alloc(max_vpage_id * sizeof(value_type)); 75 | for (size_t i = 0; i < max_vpage_id; i++) 76 | { 77 | store[i] = empty_value; 78 | } 79 | } 80 | 81 | DirectPageTable(const DirectPageTable &) = delete; 82 | DirectPageTable(DirectPageTable &&) = delete; 83 | 84 | ~DirectPageTable() { mmap_free(store, max_vpage_id * sizeof(value_type)); } 85 | 86 | bool put(const vpage_id_type &vpage_id, const value_type &value) 87 | { 88 | bool is_insert = store[vpage_id] == empty_value; 89 | store[vpage_id] = value; 90 | return is_insert; 91 | } 92 | 93 | std::optional get(const vpage_id_type &vpage_id) const 94 | { 95 | if (store[vpage_id] == empty_value) 96 | return {}; 97 | return store[vpage_id]; 98 | } 99 | 100 | bool del(const vpage_id_type &vpage_id) 101 | { 102 | bool is_del = store[vpage_id] != empty_value; 103 | store[vpage_id] = empty_value; 104 | return is_del; 105 | } 106 | 107 | void prefetch(const vpage_id_type &vpage_id) const 108 | { 109 | // if(vpage_id < max_vpage_id) 110 | _mm_prefetch(&store[vpage_id], _MM_HINT_T1); 111 | } 112 | 113 | private: 114 | const vpage_id_type max_vpage_id; 115 | const ppage_id_type max_ppage_id; 116 | const value_type empty_value; 117 | value_type *store; 118 | }; 119 | } // namespace scache 120 | -------------------------------------------------------------------------------- /include/partition_type.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include "type.hpp" 17 | #include "util.hpp" 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace scache 25 | { 26 | constexpr size_t MAX_THREADS = 2048; 27 | constexpr size_t MAX_NUMANODES = 8; 28 | constexpr bool PURE_THREADING = true; 29 | constexpr size_t MAX_FIBERS_PER_THREAD = PURE_THREADING ? 1 : 16; 30 | constexpr size_t MAX_CACHES = 1; 31 | constexpr size_t MESSAGE_SIZE = PURE_THREADING ? CACHELINE_SIZE * 1 : CACHELINE_SIZE * 2; 32 | constexpr bool USING_SINGLE_CACHELINE = false; 33 | constexpr bool USING_FIBER_ASYNC_RESPONSE = true; // PURE_THREADING ? false : true; 34 | constexpr size_t HYBRID_SPIN_THRESHOLD = PURE_THREADING ? (1lu << 0) : (1lu << 30); 35 | constexpr size_t FIBER_CHANNEL_DEPTH = MAX_THREADS * MESSAGE_SIZE / sizeof(vpage_id_type); 36 | constexpr bool ENABLE_SERVER_PRE_PROCESSING = PURE_THREADING ? false : true; 37 | constexpr bool ENABLE_CLIENT_TIMER_FIBER = false; 38 | constexpr bool ENABLE_DIRECT_PIN = true; 39 | constexpr bool ENABLE_DIRECT_UNPIN = true; 40 | constexpr bool ENABLE_IOPS_STATS = true; 41 | 42 | struct header_type 43 | { 44 | bool toggle; 45 | uint8_t num_comm; 46 | }; 47 | 48 | struct response_type 49 | { 50 | void *pointer; 51 | }; 52 | 53 | struct request_type 54 | { 55 | enum class Type : uint8_t 56 | { 57 | None = 0, 58 | Pin = 1, 59 | Unpin = 2, 60 | DirtyUnpin = 3, 61 | NotifyDirectPin = 4, 62 | NotifyDirectUnpin = 5, 63 | } type; 64 | vpage_id_type page_id : (sizeof(vpage_id_type) * 8 - CACHE_PAGE_BITS); 65 | response_type *resp; 66 | }; 67 | static_assert(sizeof(request_type) == 2 * sizeof(vpage_id_type)); 68 | static_assert(sizeof(request_type) == 2 * sizeof(response_type)); 69 | 70 | struct alignas(MESSAGE_SIZE) message_type 71 | { 72 | static constexpr uint8_t MAX_COMMS = MESSAGE_SIZE / sizeof(request_type) - 1; 73 | 74 | header_type header; 75 | union 76 | { 77 | request_type reqs[MAX_COMMS]; 78 | response_type resps[MAX_COMMS]; 79 | }; 80 | message_type &operator=(const message_type &c) 81 | { 82 | uint64_t *l = (uint64_t *)this; 83 | uint64_t *r = (uint64_t *)&c; 84 | constexpr size_t num_uint64 = sizeof(request_type) / sizeof(uint64_t); 85 | #pragma unroll 86 | for (int8_t i = 1; i < MAX_COMMS * num_uint64 + 1; i++) 87 | { 88 | l[i] = r[i]; 89 | } 90 | save_fence(); 91 | l[0] = r[0]; 92 | return *this; 93 | } 94 | }; 95 | static_assert(sizeof(message_type) == MESSAGE_SIZE); 96 | 97 | template class alignas(CACHELINE_SIZE) cacheline_aligned_type 98 | { 99 | public: 100 | T &operator()() { return data; } 101 | 102 | private: 103 | T data; 104 | }; 105 | 106 | void inline nano_spin() 107 | { 108 | if constexpr (PURE_THREADING) 109 | { 110 | compiler_fence(); 111 | } 112 | else 113 | { 114 | if (likely(boost::fibers::context::active() != nullptr)) 115 | boost::this_fiber::yield(); 116 | else 117 | compiler_fence(); 118 | } 119 | } 120 | 121 | void inline hybrid_spin(size_t &loops) 122 | { 123 | if (loops++ < HYBRID_SPIN_THRESHOLD) 124 | { 125 | nano_spin(); 126 | } 127 | else 128 | { 129 | std::this_thread::yield(); 130 | loops = 0; 131 | } 132 | } 133 | 134 | } // namespace scache 135 | -------------------------------------------------------------------------------- /include/partitioner.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include "type.hpp" 17 | #include 18 | 19 | namespace scache 20 | { 21 | class RoundRobinPartitioner 22 | { 23 | public: 24 | RoundRobinPartitioner(partition_id_type _num_partitions, vpage_id_type _num_vpages) 25 | : num_partitions(_num_partitions), num_vpages(_num_vpages) 26 | { 27 | } 28 | 29 | std::tuple operator()(vpage_id_type vpage_id) const 30 | { 31 | return {vpage_id % num_partitions, vpage_id / num_partitions}; 32 | } 33 | 34 | block_id_type num_blocks(partition_id_type partition_id) const 35 | { 36 | return num_vpages / num_partitions + (partition_id < num_vpages % num_partitions); 37 | } 38 | 39 | vpage_id_type operator()(partition_id_type partition_id, block_id_type block_id) const 40 | { 41 | return block_id * num_partitions + partition_id; 42 | } 43 | 44 | private: 45 | const partition_id_type num_partitions; 46 | const vpage_id_type num_vpages; 47 | }; 48 | 49 | } // namespace scache 50 | -------------------------------------------------------------------------------- /include/replacement.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include "type.hpp" 17 | #include "util.hpp" 18 | #include 19 | #include 20 | 21 | namespace scache 22 | { 23 | class LRU 24 | { 25 | public: 26 | using list_type = std::list>; 27 | using state_type = typename list_type::iterator; 28 | 29 | LRU(const ppage_id_type &_max_ppage_id) : max_ppage_id(_max_ppage_id) 30 | { 31 | states = (state_type *)mmap_alloc(max_ppage_id * sizeof(state_type), CACHELINE_SIZE); 32 | for (size_t i = 0; i < max_ppage_id; i++) 33 | states[i] = list.end(); 34 | } 35 | 36 | LRU(const LRU &) = delete; 37 | LRU(LRU &&) = delete; 38 | 39 | ~LRU() { mmap_free(states, max_ppage_id * sizeof(state_type)); } 40 | 41 | void push(const ppage_id_type &ppage_id) 42 | { 43 | if (states[ppage_id] == list.end()) 44 | { 45 | list.emplace_front(ppage_id); 46 | states[ppage_id] = list.begin(); 47 | } 48 | else 49 | { 50 | access(ppage_id); 51 | } 52 | } 53 | 54 | std::pair pop() 55 | { 56 | assert(list.size() > 0); 57 | auto ppage_id = list.back(); 58 | states[ppage_id] = list.end(); 59 | list.pop_back(); 60 | auto next_id = 0; 61 | if (!list.empty()) 62 | next_id = list.back(); 63 | return {ppage_id, next_id}; 64 | } 65 | 66 | void access(const ppage_id_type &ppage_id) 67 | { 68 | assert(states[ppage_id] != list.end()); 69 | list.splice(list.begin(), list, states[ppage_id]); 70 | } 71 | 72 | void erase(const ppage_id_type &ppage_id) 73 | { 74 | if (states[ppage_id] != list.end()) 75 | { 76 | list.erase(states[ppage_id]); 77 | states[ppage_id] = list.end(); 78 | } 79 | } 80 | 81 | ppage_id_type size() const { return list.size(); } 82 | 83 | private: 84 | const ppage_id_type max_ppage_id; 85 | list_type list; 86 | state_type *states; 87 | }; 88 | 89 | class Clock 90 | { 91 | public: 92 | using state_type = uint8_t; 93 | 94 | Clock(const ppage_id_type &_max_ppage_id) : max_ppage_id(_max_ppage_id), hand(0), count(0) 95 | { 96 | states = (state_type *)mmap_alloc(max_ppage_id * sizeof(state_type), CACHELINE_SIZE); 97 | for (size_t i = 0; i < max_ppage_id; i++) 98 | states[i] = 0; 99 | } 100 | 101 | Clock(const Clock &) = delete; 102 | Clock(Clock &&) = delete; 103 | 104 | ~Clock() { mmap_free(states, max_ppage_id * sizeof(state_type)); } 105 | 106 | void push(const ppage_id_type &ppage_id) 107 | { 108 | if (states[ppage_id] == 0) 109 | { 110 | count++; 111 | states[ppage_id] = 2; 112 | } 113 | else 114 | { 115 | access(ppage_id); 116 | } 117 | } 118 | 119 | std::pair pop() 120 | { 121 | assert(count > 0); 122 | while (states[hand] != 1) 123 | { 124 | if (states[hand] == 2) 125 | states[hand] = 1; 126 | hand = (hand + 1) % max_ppage_id; 127 | } 128 | states[hand] = 0; 129 | count--; 130 | auto del_hand = hand; 131 | size_t loops = 1024; 132 | while (states[hand] != 1 && --loops) 133 | { 134 | hand = (hand + 1) % max_ppage_id; 135 | } 136 | return {del_hand, hand}; 137 | } 138 | 139 | void access(const ppage_id_type &ppage_id) 140 | { 141 | assert(states[ppage_id] != 0); 142 | states[ppage_id] = 2; 143 | } 144 | 145 | void erase(const ppage_id_type &ppage_id) 146 | { 147 | if (states[ppage_id] != 0) 148 | { 149 | states[ppage_id] = 0; 150 | count--; 151 | } 152 | } 153 | 154 | ppage_id_type size() const { return count; } 155 | 156 | private: 157 | const ppage_id_type max_ppage_id; 158 | ppage_id_type hand; 159 | ppage_id_type count; 160 | state_type *states; 161 | }; 162 | 163 | } // namespace scache 164 | -------------------------------------------------------------------------------- /include/type.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #pragma once 16 | #include 17 | #include 18 | 19 | #define FORCE_INLINE __attribute__((always_inline)) 20 | #define likely(x) __builtin_expect((x), 1) 21 | #define unlikely(x) __builtin_expect((x), 0) 22 | 23 | namespace scache 24 | { 25 | using vpage_id_type = uint64_t; 26 | using ppage_id_type = uint64_t; 27 | using block_id_type = uint64_t; 28 | using partition_id_type = uint64_t; 29 | constexpr size_t CACHELINE_SIZE = 64; 30 | #ifndef DEF_PAGE_BITS 31 | constexpr size_t CACHE_PAGE_BITS = 12; 32 | #else 33 | constexpr size_t CACHE_PAGE_BITS = DEF_PAGE_BITS; 34 | #endif 35 | constexpr size_t CACHE_PAGE_SIZE = 1lu << CACHE_PAGE_BITS; 36 | constexpr uintptr_t CACHE_PAGE_MASK = CACHE_PAGE_SIZE - 1; 37 | } // namespace scache 38 | -------------------------------------------------------------------------------- /llvm-plugin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13.4) 2 | project(tricache-instrument) 3 | 4 | find_package(LLVM 13 REQUIRED CONFIG) 5 | 6 | message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") 7 | 8 | list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") 9 | include(AddLLVM) 10 | include_directories(${LLVM_INCLUDE_DIRS}) 11 | 12 | add_subdirectory(TriCacheAlloc) 13 | add_subdirectory(TriCacheInstrument) 14 | 15 | set(TRI_INST_OUTPUT "$") 16 | set(TRI_ALLOC_OUTPUT "$") 17 | 18 | add_custom_target(tri-inst-output DEPENDS "${TRI_INST_OUTPUT}") 19 | add_dependencies(tri-inst-output TriCacheInstrument) 20 | add_custom_target(tri-inst-alloc-output DEPENDS "${TRI_ALLOC_OUTPUT}") 21 | add_dependencies(tri-inst-alloc-output TriCacheAlloc) 22 | 23 | add_library(instrument INTERFACE) 24 | add_dependencies(instrument tri-inst-output) 25 | target_compile_options(instrument INTERFACE "-fpass-plugin=${TRI_INST_OUTPUT}") 26 | 27 | add_library(instrument-alloc INTERFACE) 28 | add_dependencies(instrument-alloc tri-inst-alloc-output) 29 | target_link_libraries(instrument-alloc INTERFACE instrument) 30 | target_compile_options(instrument-alloc INTERFACE "-fpass-plugin=${TRI_ALLOC_OUTPUT}") 31 | -------------------------------------------------------------------------------- /llvm-plugin/TriCacheAlloc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | ADD_LLVM_PASS_PLUGIN(TriCacheAlloc TriCacheAlloc.cpp 3 | 4 | DEPENDS intrinsics_gen) 5 | -------------------------------------------------------------------------------- /llvm-plugin/TriCacheAlloc/TriCacheAlloc.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Huanqi Cao, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #include "llvm/ADT/Statistic.h" 17 | #include "llvm/IR/Function.h" 18 | #include "llvm/IR/IRBuilder.h" 19 | #include "llvm/IR/Instructions.h" 20 | #include "llvm/IR/IntrinsicInst.h" 21 | #include "llvm/IR/LLVMContext.h" 22 | #include "llvm/IR/MDBuilder.h" 23 | #include "llvm/IR/Module.h" 24 | #include "llvm/Pass.h" 25 | #include "llvm/Passes/PassBuilder.h" 26 | #include "llvm/Passes/PassPlugin.h" 27 | #include "llvm/Support/CommandLine.h" 28 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" 29 | 30 | using namespace llvm; 31 | 32 | class TriCacheAllocPass : public PassInfoMixin 33 | { 34 | public: 35 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 36 | static bool isRequired() { return true; } 37 | }; 38 | 39 | PreservedAnalyses TriCacheAllocPass::run(Function &F, FunctionAnalysisManager &AM) 40 | { 41 | auto &C = F.getContext(); 42 | auto &M = *F.getParent(); 43 | auto ptrTy = Type::getInt8PtrTy(C); 44 | auto sizeTy = Type::getInt64Ty(C); 45 | auto intTy = Type::getInt32Ty(C); 46 | std::unordered_map HookedFunc; 47 | HookedFunc["malloc"] = M.getOrInsertFunction("cache_malloc_hook", ptrTy, sizeTy); 48 | HookedFunc["_Znwm"] = M.getOrInsertFunction("cache_malloc_hook", ptrTy, sizeTy); 49 | HookedFunc["_Znam"] = M.getOrInsertFunction("cache_malloc_hook", ptrTy, sizeTy); 50 | HookedFunc["calloc"] = M.getOrInsertFunction("cache_calloc_hook", ptrTy, sizeTy, sizeTy); 51 | HookedFunc["realloc"] = M.getOrInsertFunction("cache_realloc_hook", ptrTy, ptrTy, sizeTy); 52 | HookedFunc["aligned_alloc"] = M.getOrInsertFunction("cache_aligned_alloc_hook", ptrTy, sizeTy, sizeTy); 53 | HookedFunc["mmap"] = M.getOrInsertFunction("cache_mmap_hook", ptrTy, ptrTy, sizeTy, intTy, intTy, intTy, sizeTy); 54 | for (auto &BB : F) 55 | { 56 | SmallVector, 4> CIs; 57 | for (auto &I : BB) 58 | { 59 | if (auto CI = dyn_cast(&I)) 60 | if (auto Callee = CI->getCalledFunction()) 61 | { 62 | auto Name = Callee->getName().str(); 63 | if (HookedFunc.count(Name)) 64 | CIs.emplace_back(CI, std::move(Name)); 65 | } 66 | } 67 | for (auto &[CI, Name] : CIs) 68 | { 69 | SmallVector args; 70 | for (auto &argUse : CI->args()) 71 | args.emplace_back(argUse); 72 | ReplaceInstWithInst(CI, CallInst::Create(HookedFunc[Name], args)); 73 | } 74 | } 75 | return PreservedAnalyses::none(); 76 | } 77 | 78 | extern "C" ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() 79 | { 80 | return {LLVM_PLUGIN_API_VERSION, "TriCache Instrumentation for Allocation", "0.0.1", 81 | [](PassBuilder &PB) 82 | { 83 | PB.registerPipelineStartEPCallback( 84 | [&](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) 85 | { MPM.addPass(createModuleToFunctionPassAdaptor(TriCacheAllocPass())); }); 86 | }}; 87 | } 88 | -------------------------------------------------------------------------------- /llvm-plugin/TriCacheAlloc/TriCacheAlloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Huanqi Cao, Tsinghua University 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef LLVM_TRANSFORMS_UTILS_TRICACHEINSTRUMENT_H 19 | #define LLVM_TRANSFORMS_UTILS_TRICACHEINSTRUMENT_H 20 | 21 | #include "llvm/IR/PassManager.h" 22 | 23 | namespace llvm 24 | { 25 | 26 | class TriCacheInstrumentPass : public PassInfoMixin 27 | { 28 | public: 29 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 30 | static bool isRequired() { return true; } 31 | }; 32 | 33 | } // namespace llvm 34 | 35 | #endif // LLVM_TRANSFORMS_UTILS_TRICACHEINSTRUMENT_H 36 | -------------------------------------------------------------------------------- /llvm-plugin/TriCacheInstrument/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | ADD_LLVM_PASS_PLUGIN(TriCacheInstrument TriCacheInstrument.cpp 3 | 4 | DEPENDS intrinsics_gen) 5 | -------------------------------------------------------------------------------- /llvm-plugin/TriCacheInstrument/TriCacheInstrument.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Huanqi Cao, Tsinghua University 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | 18 | #ifndef LLVM_TRANSFORMS_UTILS_TRICACHEINSTRUMENT_H 19 | #define LLVM_TRANSFORMS_UTILS_TRICACHEINSTRUMENT_H 20 | 21 | #include "llvm/IR/PassManager.h" 22 | 23 | namespace llvm 24 | { 25 | 26 | class TriCacheInstrumentPass : public PassInfoMixin 27 | { 28 | public: 29 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 30 | static bool isRequired() { return true; } 31 | }; 32 | 33 | } // namespace llvm 34 | 35 | #endif // LLVM_TRANSFORMS_UTILS_TRICACHEINSTRUMENT_H 36 | -------------------------------------------------------------------------------- /playground/manual_parallel_sort.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "cached_allocator.hpp" 16 | #include "integrated_cache.hpp" 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | const size_t virt_size = 128lu * (1 << 30); 24 | const size_t phy_size = 128lu * (1 << 30); 25 | 26 | template void swap(T a, T b) 27 | { 28 | auto t = *a; 29 | *a = *b; 30 | *b = t; 31 | } 32 | 33 | template int partition(T arr, int low, int high) 34 | { 35 | auto pivot = arr[high]; 36 | int i = (low - 1); 37 | 38 | for (int j = low; j <= high - 1; j++) 39 | { 40 | if (arr[j] <= pivot) 41 | { 42 | i++; 43 | swap(arr + i, arr + j); 44 | } 45 | } 46 | swap(arr + i + 1, arr + high); 47 | return (i + 1); 48 | } 49 | 50 | template void quick_sort(T arr, int low, int high) 51 | { 52 | if (low < high) 53 | { 54 | int pi = partition(arr, low, high); 55 | 56 | quick_sort(arr, low, pi - 1); 57 | quick_sort(arr, pi + 1, high); 58 | } 59 | } 60 | 61 | int main(int argc, char **argv) 62 | { 63 | const size_t len = std::atoi(argv[1]); 64 | 65 | if (argc <= 2) 66 | { 67 | printf("usage: %s len cpu_id,file_path ...\n", argv[0]); 68 | return 0; 69 | } 70 | 71 | std::vector server_cpus; 72 | std::vector server_paths; 73 | 74 | for (int i = 2; i < argc; i++) 75 | { 76 | auto str = std::string(argv[i]); 77 | auto pos = str.find(","); 78 | auto cpu = std::stoul(str.substr(0, pos)); 79 | auto path = str.substr(pos + 1); 80 | printf("%lu %s\n", cpu, path.c_str()); 81 | server_cpus.emplace_back(cpu); 82 | server_paths.emplace_back(path); 83 | } 84 | 85 | auto func = [&](auto &allocator) 86 | { 87 | #pragma omp parallel 88 | { 89 | auto my_cpu = sched_getcpu(); 90 | bool is_server = false; 91 | for (auto cpu : server_cpus) 92 | { 93 | if (cpu == my_cpu || cpu + std::thread::hardware_concurrency() / 2 == my_cpu) 94 | is_server = true; 95 | } 96 | if (!is_server) 97 | { 98 | auto t1 = std::chrono::high_resolution_clock::now(); 99 | auto arr = allocator.allocate(len); 100 | 101 | auto rd = std::mt19937(); 102 | int64_t ref = 0, sum = 0; 103 | for (size_t i = 0; i < len; i++) 104 | { 105 | int data = rd(); 106 | ref += data; 107 | arr[i] = data; 108 | } 109 | 110 | sum = 0; 111 | for (size_t i = 0; i < len; i++) 112 | sum += arr[i]; 113 | if (ref != sum) 114 | throw std::runtime_error("before sum check error\n"); 115 | 116 | #pragma omp barrier 117 | auto t2 = std::chrono::high_resolution_clock::now(); 118 | quick_sort(arr, 0, len - 1); 119 | #pragma omp barrier 120 | auto t3 = std::chrono::high_resolution_clock::now(); 121 | 122 | sum = 0; 123 | for (size_t i = 0; i < len; i++) 124 | sum += arr[i]; 125 | if (ref != sum) 126 | throw std::runtime_error("later sum check error\n"); 127 | 128 | for (size_t i = 0; i < len - 1; i++) 129 | { 130 | int l = arr[i]; 131 | int r = arr[i + 1]; 132 | if (l > r) 133 | throw std::runtime_error("compare check error\n"); 134 | } 135 | #pragma omp barrier 136 | auto t4 = std::chrono::high_resolution_clock::now(); 137 | 138 | #pragma omp single 139 | printf("exec time: %lf %lf %lf\n", 1e-9 * (t2 - t1).count(), 1e-9 * (t3 - t2).count(), 140 | 1e-9 * (t4 - t3).count()); 141 | 142 | allocator.deallocate(arr, len); 143 | } 144 | else 145 | { 146 | #pragma omp barrier 147 | #pragma omp barrier 148 | #pragma omp barrier 149 | #pragma omp barrier 150 | } 151 | } 152 | printf("end\n"); 153 | }; 154 | 155 | scache::IntegratedCache cache(virt_size, phy_size, server_cpus, server_paths, omp_get_max_threads()); 156 | scache::CachedAllocator cache_allocator(&cache); 157 | std::allocator std_allocator; 158 | func(std_allocator); 159 | func(cache_allocator); 160 | } 161 | -------------------------------------------------------------------------------- /playground/parallel_sort.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "cached_allocator.hpp" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | const size_t virt_size = 128lu * (1 << 30); 25 | const size_t num_vpages = virt_size / scache::CACHE_PAGE_SIZE; 26 | const size_t phy_size = 128lu * (1 << 30); 27 | const size_t num_ppages = phy_size / scache::CACHE_PAGE_SIZE; 28 | 29 | const size_t size = 8lu << 30; 30 | 31 | int main(int argc, char **argv) 32 | { 33 | if (argc <= 1) 34 | { 35 | printf("usage: %s cpu_id,file_path ...\n", argv[0]); 36 | return 0; 37 | } 38 | 39 | std::vector server_cpus; 40 | std::vector server_paths; 41 | 42 | for (int i = 1; i < argc; i++) 43 | { 44 | auto str = std::string(argv[i]); 45 | auto pos = str.find(","); 46 | auto cpu = std::stoul(str.substr(0, pos)); 47 | auto path = str.substr(pos + 1); 48 | printf("%lu %s\n", cpu, path.c_str()); 49 | server_cpus.emplace_back(cpu); 50 | server_paths.emplace_back(path); 51 | } 52 | 53 | const size_t num_threads = omp_get_max_threads() - server_cpus.size(); 54 | 55 | scache::IntegratedCache global_cache(virt_size, phy_size, server_cpus, server_paths, num_threads * 5); 56 | 57 | scache::CachedAllocator allocator(&global_cache); 58 | // std::allocator allocator; 59 | 60 | auto ptr = allocator.allocate(size); 61 | 62 | // #pragma omp parallel 63 | // { 64 | // std::mt19937_64 rand(omp_get_thread_num()); 65 | // #pragma omp for schedule(dynamic, 4096) 66 | // for(size_t i=0;i threads; 80 | for (size_t i = 0; i < num_threads; i++) 81 | { 82 | threads.emplace_back( 83 | [&, tid = i]() 84 | { 85 | std::mt19937_64 rand(tid); 86 | auto per_size = (size + num_threads - 1) / num_threads; 87 | auto start = tid * per_size; 88 | auto end = std::min((tid + 1) * per_size, size); 89 | for (size_t i = start; i < end; i++) 90 | { 91 | ptr[i] = rand(); 92 | } 93 | ptr.flush(); 94 | }); 95 | } 96 | for (auto &t : threads) 97 | t.join(); 98 | threads.clear(); 99 | 100 | printf("Finish init\n"); 101 | 102 | auto start = std::chrono::high_resolution_clock::now(); 103 | boost::sort::sample_sort(ptr, ptr + size, num_threads); 104 | auto end = std::chrono::high_resolution_clock::now(); 105 | 106 | printf("%lf s\n", 1e-9 * (end - start).count()); 107 | 108 | for (size_t i = 0; i < num_threads; i++) 109 | { 110 | threads.emplace_back( 111 | [&, tid = i]() 112 | { 113 | std::mt19937_64 rand(tid); 114 | auto per_size = (size + num_threads - 1) / num_threads; 115 | auto start = tid * per_size; 116 | auto end = std::min((tid + 1) * per_size, size); 117 | for (size_t i = start; i < end - 1; i++) 118 | { 119 | if (ptr[i] > ptr[i + 1]) 120 | { 121 | printf("Check Error, %lu %lu\n", ptr[i], ptr[i + 1]); 122 | } 123 | } 124 | ptr.flush(); 125 | }); 126 | } 127 | for (auto &t : threads) 128 | t.join(); 129 | threads.clear(); 130 | 131 | printf("Finish Check\n"); 132 | 133 | allocator.deallocate(ptr, size); 134 | } 135 | -------------------------------------------------------------------------------- /playground/test_instrument.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | void swap(int *a, int *b) 21 | { 22 | int t = *a; 23 | *a = *b; 24 | *b = t; 25 | } 26 | 27 | int partition(int arr[], int low, int high) 28 | { 29 | int pivot = *(arr + high); 30 | int i = (low - 1); 31 | 32 | for (int j = low; j <= high - 1; j++) 33 | { 34 | if (*(arr + j) <= pivot) 35 | { 36 | i++; 37 | swap(&arr[i], &arr[j]); 38 | } 39 | } 40 | swap(&arr[i + 1], &arr[high]); 41 | return (i + 1); 42 | } 43 | 44 | void quick_sort(int *arr, int low, int high) 45 | { 46 | if (low < high) 47 | { 48 | int pi = partition(arr, low, high); 49 | 50 | quick_sort(arr, low, pi - 1); 51 | quick_sort(arr, pi + 1, high); 52 | } 53 | } 54 | 55 | extern "C" void cache_reset_profile(); 56 | extern "C" void cache_dump_profile(); 57 | 58 | int main() 59 | { 60 | const size_t len = 4000000; 61 | const size_t num_ops = 2000; 62 | 63 | // auto arr = (int *)mmap(NULL, len * sizeof(int), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 64 | auto arr = (int *)cache_alloc(len * sizeof(int)); 65 | auto ref_arr = (int *)malloc(len * sizeof(int)); 66 | 67 | cache_reset_profile(); 68 | arr[0] = 0; 69 | arr[100000] = 100000; 70 | cache_dump_profile(); 71 | 72 | auto rd = std::mt19937(); 73 | int64_t ref = 0, sum = 0; 74 | for (size_t i = 0; i < len; i++) 75 | { 76 | int data = rd(); 77 | ref += data; 78 | *(arr + i) = data; 79 | } 80 | 81 | sum = 0; 82 | for (size_t i = 0; i < len; i++) 83 | sum += *(arr + i); 84 | if (ref != sum) 85 | throw std::runtime_error("before sum check error\n"); 86 | 87 | cache_reset_profile(); 88 | quick_sort(arr, 0, len - 1); 89 | cache_dump_profile(); 90 | 91 | sum = 0; 92 | for (size_t i = 0; i < len; i++) 93 | sum += *(arr + i); 94 | if (ref != sum) 95 | throw std::runtime_error("later sum check error\n"); 96 | 97 | for (size_t i = 0; i < len - 1; i++) 98 | { 99 | int l = *(arr + i); 100 | int r = *(arr + i + 1); 101 | if (l > r) 102 | throw std::runtime_error("compare check error\n"); 103 | } 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /playground/test_instrument_mmap.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | void swap(int *a, int *b) 22 | { 23 | int t = *a; 24 | *a = *b; 25 | *b = t; 26 | } 27 | 28 | int partition(int arr[], int low, int high) 29 | { 30 | int pivot = *(arr + high); 31 | int i = (low - 1); 32 | 33 | for (int j = low; j <= high - 1; j++) 34 | { 35 | if (*(arr + j) <= pivot) 36 | { 37 | i++; 38 | swap(&arr[i], &arr[j]); 39 | } 40 | } 41 | swap(&arr[i + 1], &arr[high]); 42 | return (i + 1); 43 | } 44 | 45 | void quick_sort(int *arr, int low, int high) 46 | { 47 | if (low < high) 48 | { 49 | int pi = partition(arr, low, high); 50 | 51 | quick_sort(arr, low, pi - 1); 52 | quick_sort(arr, pi + 1, high); 53 | } 54 | } 55 | 56 | int main() 57 | { 58 | const size_t len = 4000000; 59 | const size_t num_ops = 2000; 60 | 61 | // get function pointer; this will work around the hooking easily 62 | volatile auto p_malloc = malloc; 63 | 64 | auto arr = (int *)mmap(NULL, len * sizeof(int), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 65 | // auto arr = (int *)cache_alloc(len * sizeof(int)); 66 | auto ref_arr = (int *)p_malloc(len * sizeof(int)); 67 | 68 | auto rd = std::mt19937(); 69 | int64_t ref = 0, sum = 0; 70 | for (size_t i = 0; i < len; i++) 71 | { 72 | int data = rd(); 73 | ref += data; 74 | *(arr + i) = data; 75 | } 76 | 77 | sum = 0; 78 | for (size_t i = 0; i < len; i++) 79 | sum += *(arr + i); 80 | if (ref != sum) 81 | throw std::runtime_error("before sum check error\n"); 82 | 83 | quick_sort(arr, 0, len - 1); 84 | 85 | sum = 0; 86 | for (size_t i = 0; i < len; i++) 87 | sum += *(arr + i); 88 | if (ref != sum) 89 | throw std::runtime_error("later sum check error\n"); 90 | 91 | for (size_t i = 0; i < len - 1; i++) 92 | { 93 | int l = *(arr + i); 94 | int r = *(arr + i + 1); 95 | if (l > r) 96 | throw std::runtime_error("compare check error\n"); 97 | } 98 | 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /playground/test_libcache.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | void swap(int *a, int *b) 21 | { 22 | int t = *(int *)cache_get_raw_ptr_load(a); 23 | *(int *)cache_get_raw_ptr_store(a) = *(int *)cache_get_raw_ptr_load(b); 24 | *(int *)cache_get_raw_ptr_store(b) = t; 25 | } 26 | 27 | int partition(int arr[], int low, int high) 28 | { 29 | int pivot = *(int *)cache_get_raw_ptr_load(arr + high); 30 | int i = (low - 1); 31 | 32 | for (int j = low; j <= high - 1; j++) 33 | { 34 | if (*(int *)cache_get_raw_ptr_load(arr + j) <= pivot) 35 | { 36 | i++; 37 | swap(&arr[i], &arr[j]); 38 | } 39 | } 40 | swap(&arr[i + 1], &arr[high]); 41 | return (i + 1); 42 | } 43 | 44 | void quick_sort(int *arr, int low, int high) 45 | { 46 | if (low < high) 47 | { 48 | 49 | if (high - low > 512) 50 | printf("quick_sort %d %d\n", low, high); 51 | 52 | int pi = partition(arr, low, high); 53 | 54 | quick_sort(arr, low, pi - 1); 55 | quick_sort(arr, pi + 1, high); 56 | } 57 | } 58 | 59 | int main() 60 | { 61 | const size_t len = 4000000; 62 | const size_t num_ops = 2000; 63 | 64 | auto arr = (int *)cache_alloc(len * sizeof(int)); 65 | auto ref_arr = (int *)malloc(len * sizeof(int)); 66 | 67 | auto rd = std::mt19937(); 68 | int64_t ref = 0, sum = 0; 69 | for (size_t i = 0; i < len; i++) 70 | { 71 | int data = rd(); 72 | ref += data; 73 | *(int *)cache_get_raw_ptr_store(arr + i) = data; 74 | } 75 | 76 | sum = 0; 77 | for (size_t i = 0; i < len; i++) 78 | sum += *(int *)cache_get_raw_ptr_load(arr + i); 79 | if (ref != sum) 80 | throw std::runtime_error("before sum check error\n"); 81 | 82 | quick_sort(arr, 0, len - 1); 83 | 84 | sum = 0; 85 | for (size_t i = 0; i < len; i++) 86 | sum += *(int *)cache_get_raw_ptr_load(arr + i); 87 | if (ref != sum) 88 | throw std::runtime_error("later sum check error\n"); 89 | 90 | for (size_t i = 0; i < len - 1; i++) 91 | { 92 | int l = *(int *)cache_get_raw_ptr_load(arr + i); 93 | int r = *(int *)cache_get_raw_ptr_load(arr + i + 1); 94 | if (l > r) 95 | throw std::runtime_error("compare check error\n"); 96 | } 97 | 98 | for (size_t i = 0; i < len; i++) 99 | ref_arr[i] += *(int *)cache_get_raw_ptr_load(arr + i); 100 | 101 | for (size_t i = 0; i < num_ops; i++) 102 | { 103 | if (i % 100 == 0) 104 | printf("op %lu\n", i); 105 | 106 | switch (rd() % 3) 107 | { 108 | case 0: 109 | { 110 | int src = rd() % len; 111 | int dst = rd() % len; 112 | int n = rd() % std::min(len - src, len - dst); 113 | 114 | memmove(ref_arr + dst, ref_arr + src, n); 115 | cache_memmove(arr + dst, arr + src, n); 116 | 117 | break; 118 | } 119 | case 1: 120 | { 121 | int dst = rd() % len; 122 | int n = rd() % (len - dst); 123 | 124 | int set = rd(); 125 | memset(ref_arr + dst, set, n); 126 | cache_memset(arr + dst, set, n); 127 | 128 | break; 129 | } 130 | case 2: 131 | { 132 | int src = rd() % (len / 2); 133 | int dst = rd() % (len / 2); 134 | int n = rd() % std::min(len / 2 - src, len / 2 - dst); 135 | 136 | if (rd() % 2 == 0) 137 | src += len / 2; 138 | else 139 | dst += len / 2; 140 | 141 | memcpy(ref_arr + dst, ref_arr + src, n); 142 | cache_memcpy(arr + dst, arr + src, n); 143 | } 144 | } 145 | } 146 | 147 | for (size_t i = 0; i < len; i++) 148 | { 149 | int data = *(int *)cache_get_raw_ptr_load(arr + i); 150 | int ref = ref_arr[i]; 151 | if (data != ref) 152 | throw std::runtime_error("compare check error\n"); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /playground/test_memcpy.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Guanyu Feng, Tsinghua University 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "cache.h" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | const size_t TOTAL_SIZE = 1lu << 15; 25 | const size_t TOTAL_TESTS = 1lu << 15; 26 | 27 | char *buf_dst, *buf_dst_2, *buf_dst_mem, *buf_dst_ref, *buf_src, *buf_src_ref; 28 | 29 | void validate_data() 30 | { 31 | for (size_t i = 0; i < TOTAL_SIZE; i++) 32 | { 33 | if (buf_dst[i] != buf_dst_ref[i]) 34 | { 35 | throw std::runtime_error("check dst error"); 36 | } 37 | if (buf_dst_2[i] != buf_dst_ref[i]) 38 | { 39 | throw std::runtime_error("check dst2 error"); 40 | } 41 | if (buf_dst_mem[i] != buf_dst_ref[i]) 42 | { 43 | throw std::runtime_error("check mem error"); 44 | } 45 | if (buf_src[i] != buf_src_ref[i]) 46 | { 47 | throw std::runtime_error("check src error"); 48 | } 49 | } 50 | } 51 | 52 | int main() 53 | { 54 | buf_dst = (char *)cache_alloc(TOTAL_SIZE); 55 | buf_dst_2 = (char *)cache_alloc(TOTAL_SIZE); 56 | buf_dst_mem = (char *)malloc(TOTAL_SIZE); 57 | buf_dst_ref = (char *)malloc(TOTAL_SIZE); 58 | buf_src = (char *)cache_alloc(TOTAL_SIZE); 59 | buf_src_ref = (char *)malloc(TOTAL_SIZE); 60 | 61 | auto rand = std::mt19937(); 62 | for (size_t i = 0; i < TOTAL_SIZE; i++) 63 | { 64 | char c = (char)rand(); 65 | buf_dst_ref[i] = c; 66 | buf_dst[i] = c; 67 | buf_dst_2[i] = c; 68 | buf_dst_mem[i] = c; 69 | } 70 | for (size_t i = 0; i < TOTAL_SIZE; i++) 71 | { 72 | char c = (char)rand(); 73 | buf_src_ref[i] = c; 74 | buf_src[i] = c; 75 | } 76 | 77 | validate_data(); 78 | 79 | printf("inited\n"); 80 | 81 | for (size_t i = 0; i < TOTAL_TESTS; i++) 82 | { 83 | auto len = std::rand() % TOTAL_SIZE + 1; 84 | auto dst_start = std::rand() % (TOTAL_SIZE - len + 1); 85 | auto src_start = std::rand() % (TOTAL_SIZE - len + 1); 86 | 87 | memcpy(buf_dst + dst_start, buf_src + src_start, len); 88 | memcpy(buf_dst_2 + dst_start, buf_src_ref + src_start, len); 89 | memcpy(buf_dst_mem + dst_start, buf_src + src_start, len); 90 | memcpy(buf_dst_ref + dst_start, buf_src_ref + src_start, len); 91 | 92 | validate_data(); 93 | } 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cmake -S $TRICACHE_ROOT -B $TRICACHE_ROOT/build -DCMAKE_C_COMPILER=/usr/bin/clang-13 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-13 -DCMAKE_AR=/usr/bin/llvm-ar-13 -DCMAKE_RANLIB=/usr/bin/llvm-ranlib-13 -DCMAKE_BUILD_TYPE=Release -DENABLE_LIBCACHE=ON -DENABLE_BENCHMARK=on 3 | cmake --build $TRICACHE_ROOT/build -j 4 | -------------------------------------------------------------------------------- /scripts/build_flashgraph.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cmake -S $TRICACHE_ROOT/ae-projects/FlashX -B $TRICACHE_ROOT/ae-projects/FlashX/build -DCMAKE_BUILD_TYPE=Release 3 | cmake --build $TRICACHE_ROOT/ae-projects/FlashX/build -j 4 | 5 | -------------------------------------------------------------------------------- /scripts/build_ligra.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | pushd $TRICACHE_ROOT/ae-projects/ligra/apps 3 | OPENMP=1 LONG=1 make -j 4 | popd 5 | -------------------------------------------------------------------------------- /scripts/build_livegraph.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cmake -S $TRICACHE_ROOT/ae-projects/LiveGraph-snb -B $TRICACHE_ROOT/ae-projects/LiveGraph-snb/build-mmap -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=clang++-13 -DCMAKE_C_COMPILER=clang-13 -DWITH_TRICACHE=OFF 3 | cmake -S $TRICACHE_ROOT/ae-projects/LiveGraph-snb -B $TRICACHE_ROOT/ae-projects/LiveGraph-snb/build-cache -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=clang++-13 -DCMAKE_C_COMPILER=clang-13 -DWITH_TRICACHE=ON 4 | cmake --build $TRICACHE_ROOT/ae-projects/LiveGraph-snb/build-mmap -j 5 | cmake --build $TRICACHE_ROOT/ae-projects/LiveGraph-snb/build-cache -j 6 | pushd $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations 7 | ./dependency.sh 8 | ./build.sh 9 | popd 10 | -------------------------------------------------------------------------------- /scripts/build_rocksdb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cmake -S $TRICACHE_ROOT/ae-projects/rocksdb -B $TRICACHE_ROOT/ae-projects/rocksdb/build-orig -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=clang++-13 -DCMAKE_C_COMPILER=clang-13 -DWITH_TRICACHE=OFF -DWITH_SNAPPY=OFF -DWITH_TESTS=OFF -DWITH_ALL_TESTS=OFF -DFAIL_ON_WARNINGS=OFF 3 | cmake -S $TRICACHE_ROOT/ae-projects/rocksdb -B $TRICACHE_ROOT/ae-projects/rocksdb/build-cache -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=clang++-13 -DCMAKE_C_COMPILER=clang-13 -DWITH_TRICACHE=ON -DWITH_SNAPPY=OFF -DWITH_TESTS=OFF -DWITH_ALL_TESTS=OFF -DFAIL_ON_WARNINGS=OFF 4 | cmake --build $TRICACHE_ROOT/ae-projects/rocksdb/build-orig -j --target db_bench 5 | cmake --build $TRICACHE_ROOT/ae-projects/rocksdb/build-cache -j --target db_bench 6 | -------------------------------------------------------------------------------- /scripts/build_terasort_spark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pushd $TRICACHE_ROOT/ae-projects/terasort_spark 3 | ./dependency.sh 4 | ./config.sh 5 | ./build.sh 6 | popd 7 | -------------------------------------------------------------------------------- /scripts/cgroups.sh: -------------------------------------------------------------------------------- 1 | sudo mkdir -p /sys/fs/cgroup/limit 2 | echo "max" | sudo tee /sys/fs/cgroup/limit/memory.max 3 | -------------------------------------------------------------------------------- /scripts/clearcache.sh: -------------------------------------------------------------------------------- 1 | sync; echo 3 > /proc/sys/vm/drop_caches 2 | -------------------------------------------------------------------------------- /scripts/config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export SSDArray=(nvme-INTEL_SSDPECKE064T8_PHLN0236010Y6P4EGN-1 nvme-INTEL_SSDPECKE064T8_PHLN0236010Y6P4EGN-2 3 | nvme-INTEL_SSDPECKE064T8_PHLN0210016D6P4EGN-1 nvme-INTEL_SSDPECKE064T8_PHLN0210016D6P4EGN-2 4 | nvme-INTEL_SSDPECKE064T8_PHLN920400WY6P4EGN-1 nvme-INTEL_SSDPECKE064T8_PHLN920400WY6P4EGN-2 5 | nvme-INTEL_SSDPECKE064T8_PHLN920401096P4EGN-1 nvme-INTEL_SSDPECKE064T8_PHLN920401096P4EGN-2 6 | nvme-INTEL_SSDPECKE064T8_PHLN1073000D6P4EGN-1 nvme-INTEL_SSDPECKE064T8_PHLN1073000D6P4EGN-2 7 | nvme-INTEL_SSDPECKE064T8_PHLN920500026P4EGN-1 nvme-INTEL_SSDPECKE064T8_PHLN920500026P4EGN-2 8 | nvme-INTEL_SSDPECKE064T8_PHLN920400MH6P4EGN-1 nvme-INTEL_SSDPECKE064T8_PHLN920400MH6P4EGN-2 9 | nvme-INTEL_SSDPECKE064T8_PHLN020501HC6P4EGN-1 nvme-INTEL_SSDPECKE064T8_PHLN020501HC6P4EGN-2 10 | ) 11 | export SSDPCIe="0000:87:00.0 0000:88:00.0 0000:27:00.0 0000:28:00.0 0000:23:00.0 0000:24:00.0 0000:03:00.0 0000:04:00.0 0000:c7:00.0 0000:c8:00.0 0000:c3:00.0 0000:c4:00.0 0000:a3:00.0 0000:a4:00.0 0000:83:00.0 0000:84:00.0" 12 | # server-core-id,disk-pci-address,nsid,disk-offset 13 | export CACHE_16_SERVER_CONFIG="0,87:00.0,1,0 128,88:00.0,1,0 16,27:00.0,1,0 144,28:00.0,1,0 32,23:00.0,1,0 160,24:00.0,1,0 48,03:00.0,1,0 176,04:00.0,1,0 64,c7:00.0,1,0 192,c8:00.0,1,0 80,c3:00.0,1,0 208,c4:00.0,1,0 96,a3:00.0,1,0 224,a4:00.0,1,0 112,83:00.0,1,0 240,84:00.0,1,0" 14 | # avoid to use server cores 15 | export CACHE_16_SERVER_CORES="0,128,16,144,32,160,48,176,64,192,80,208,96,224,112,240" 16 | 17 | export CACHE_32_SERVER_CONFIG="0,87:00.0,1,0 128,88:00.0,1,0 16,27:00.0,1,0 144,28:00.0,1,0 32,23:00.0,1,0 160,24:00.0,1,0 48,03:00.0,1,0 176,04:00.0,1,0 64,c7:00.0,1,0 192,c8:00.0,1,0 80,c3:00.0,1,0 208,c4:00.0,1,0 96,a3:00.0,1,0 224,a4:00.0,1,0 112,83:00.0,1,0 240,84:00.0,1,0 1,87:00.0,1,1099511627776 129,88:00.0,1,1099511627776 17,27:00.0,1,1099511627776 145,28:00.0,1,1099511627776 33,23:00.0,1,1099511627776 161,24:00.0,1,1099511627776 49,03:00.0,1,1099511627776 177,04:00.0,1,1099511627776 65,c7:00.0,1,1099511627776 193,c8:00.0,1,1099511627776 81,c3:00.0,1,1099511627776 209,c4:00.0,1,1099511627776 97,a3:00.0,1,1099511627776 225,a4:00.0,1,1099511627776 113,83:00.0,1,1099511627776 241,84:00.0,1,1099511627776" 18 | export CACHE_32_SERVER_CORES="0,128,16,144,32,160,48,176,64,192,80,208,96,224,112,240,1,129,17,145,33,161,49,177,65,193,81,209,97,225,113,241" 19 | 20 | sleep 10 21 | -------------------------------------------------------------------------------- /scripts/convert_to_flashgraph.sh: -------------------------------------------------------------------------------- 1 | $TRICACHE_ROOT/ae-projects/FlashX/build/flash-graph/utils/el2fg -e $TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/run_test.txt /mnt/data/backup/graph/uk-2014.txt uk-2014 2 | 3 | -------------------------------------------------------------------------------- /scripts/convert_to_ligra.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export OMP_PROC_BIND=true 3 | export CACHE_VIRT_SIZE=$(expr 32 \* 1024 \* 1024 \* 1024 \* 1024) 4 | 5 | export CACHE_MALLOC_THRESHOLD=$(expr 32 \* 1024 \* 1024) 6 | 7 | source $TRICACHE_ROOT/scripts/config.sh 8 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 9 | 10 | export THREADS=240 11 | export CACHE_NUM_CLIENTS=$(expr $THREADS \+ 16 \* 4) 12 | export OMP_NUM_THREADS=$THREADS 13 | 14 | export CACHE_PHY_SIZE=$(expr 250 \* 1024 \* 1024 \* 1024) 15 | 16 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" stdbuf -oL /usr/bin/time -v numactl -i all -C !$CACHE_16_SERVER_CORES \ 17 | $TRICACHE_ROOT/ae-projects/ligra/apps/convert_to_ligra /mnt/data/TriCache/graph/uk-2014.bin /mnt/data/TriCache/ligra/uk-2014-new 18 | -------------------------------------------------------------------------------- /scripts/install_4.14_kernel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TEMP_DIR=$(mktemp -d) 3 | pushd $TEMP_DIR 4 | wget https://kernel.ubuntu.com/\~kernel-ppa/mainline/v4.14.215/amd64/linux-headers-4.14.215-0414215-generic_4.14.215-0414215.202101122110_amd64.deb 5 | wget https://kernel.ubuntu.com/\~kernel-ppa/mainline/v4.14.215/amd64/linux-image-unsigned-4.14.215-0414215-generic_4.14.215-0414215.202101122110_amd64.deb 6 | wget https://kernel.ubuntu.com/\~kernel-ppa/mainline/v4.14.215/amd64/linux-modules-4.14.215-0414215-generic_4.14.215-0414215.202101122110_amd64.deb 7 | wget https://kernel.ubuntu.com/\~kernel-ppa/mainline/v4.14.215/amd64/linux-headers-4.14.215-0414215_4.14.215-0414215.202101122110_all.deb 8 | sudo dpkg -i *.deb 9 | popd 10 | rm $TEMP_DIR -r 11 | -------------------------------------------------------------------------------- /scripts/kexec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo sync 3 | sudo sync 4 | sudo sync 5 | sudo kexec -l /boot/vmlinuz-4.14.215-0414215-generic --initrd=/boot/initrd.img-4.14.215-0414215-generic --command-line="$( cat /proc/cmdline )" 6 | sudo kexec -e 7 | -------------------------------------------------------------------------------- /scripts/livegraph_cp_dataset_cache.sh: -------------------------------------------------------------------------------- 1 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 2 | 3 | sudo mkdir -p /mnt/data/TriCache/temp 4 | sudo rsync -avhP --delete /mnt/data/TriCache/livegraph/livegraph_$1g /mnt/data/TriCache/temp 5 | sudo chown -R $(id -u):$(id -g) /mnt/data/TriCache/temp/livegraph_$1g 6 | -------------------------------------------------------------------------------- /scripts/livegraph_cp_dataset_mmap.sh: -------------------------------------------------------------------------------- 1 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 2 | rm /mnt/raid/temp/livegraph_$1g -rf 3 | sudo cp /mnt/data/TriCache/livegraph/livegraph_$1g /mnt/raid/temp -r 4 | sudo chown -R $(id -u):$(id -g) /mnt/raid/temp/livegraph_$1g 5 | -------------------------------------------------------------------------------- /scripts/livegraph_exec_cache.sh: -------------------------------------------------------------------------------- 1 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 2 | export OMP_PROC_BIND=true 3 | export CACHE_VIRT_SIZE=$(expr 32 \* 1024 \* 1024 \* 1024 \* 1024) 4 | source $TRICACHE_ROOT/scripts/config.sh 5 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 6 | export CACHE_NUM_CLIENTS=$(expr $LIVEGRAPH_NUM_CLIENTS + 1) 7 | export OMP_NUM_THREADS=32 8 | 9 | export CACHE_MALLOC_THRESHOLD=$(expr 64 \* 1024 \* 1024 \* 1024) 10 | 11 | TZ=UTC sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -C !$CACHE_16_SERVER_CORES \ 12 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/LiveGraph-snb/build-cache/snb_server /mnt/data/TriCache/temp/livegraph_$1g dummy 9090 13 | -------------------------------------------------------------------------------- /scripts/livegraph_exec_mmap.sh: -------------------------------------------------------------------------------- 1 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 2 | export OMP_NUM_THREADS=$LIVEGRAPH_NUM_CLIENTS 3 | TZ=UTC $TRICACHE_ROOT/ae-projects/LiveGraph-snb/build-mmap/snb_server /mnt/raid/temp/livegraph_$1g dummy 9090 4 | -------------------------------------------------------------------------------- /scripts/load_to_flashgraph.sh: -------------------------------------------------------------------------------- 1 | for i in $(seq 0 15) 2 | do 3 | sudo rsync -avhP /mnt/data/TriCache/flashgraph/ssd$i/ /mnt/ssd$i/ 4 | sudo chmod -R a+rw /mnt/ssd$i/* 5 | done 6 | sudo $TRICACHE_ROOT/scripts/clearcache.sh 7 | -------------------------------------------------------------------------------- /scripts/mkraid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $TRICACHE_ROOT/scripts/config.sh 3 | 4 | dev="" 5 | for i in ${!SSDArray[@]}; do 6 | id="${SSDArray[$i]}" 7 | path="/dev/disk/by-id/$id" 8 | name=$(basename $(readlink $path)) 9 | numa=$(cat /sys/block/$name/device/numa_node) 10 | 11 | echo $i $id $path $name $numa 12 | 13 | dev="$dev $path" 14 | done 15 | 16 | sudo mdadm --stop /dev/md* 17 | echo yes | sudo mdadm --create --force --verbose /dev/md0 --level=0 --raid-devices=16 $dev 18 | sudo mkfs.xfs -f /dev/md0 19 | sudo mkdir -p /mnt/raid 20 | sudo mount /dev/md0 /mnt/raid 21 | sudo mkdir /mnt/raid/temp 22 | sudo chmod a+rw -R /mnt/raid/temp 23 | 24 | -------------------------------------------------------------------------------- /scripts/mkswap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $TRICACHE_ROOT/scripts/config.sh 3 | 4 | for i in ${!SSDArray[@]}; do 5 | id="${SSDArray[$i]}" 6 | path="/dev/disk/by-id/$id" 7 | name=$(basename $(readlink $path)) 8 | numa=$(cat /sys/block/$name/device/numa_node) 9 | 10 | echo $i $id $path $name $numa 11 | 12 | sudo mkswap $path 13 | sudo swapon $path 14 | 15 | done 16 | -------------------------------------------------------------------------------- /scripts/mkxfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $TRICACHE_ROOT/scripts/config.sh 3 | 4 | for i in ${!SSDArray[@]}; do 5 | id="${SSDArray[$i]}" 6 | path="/dev/disk/by-id/$id" 7 | name=$(basename $(readlink $path)) 8 | numa=$(cat /sys/block/$name/device/numa_node) 9 | 10 | echo $i $id $path $name $numa 11 | 12 | sudo mkfs.xfs -f $path 13 | sudo mkdir -p /mnt/ssd${i} 14 | sudo mount -t xfs $path /mnt/ssd${i} 15 | sudo mkdir /mnt/ssd${i}/shm 16 | sudo chmod a+rw /mnt/ssd${i}/shm 17 | done 18 | -------------------------------------------------------------------------------- /scripts/plot_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | case $1 in 3 | graph_processing) 4 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_graph_processing.py $2 5 | ;; 6 | 7 | rocksdb) 8 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_rocksdb.py $2 9 | ;; 10 | 11 | terasort) 12 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_terasort.py $2 13 | ;; 14 | 15 | livegraph) 16 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_livegraph.py $2 17 | ;; 18 | 19 | microbenchmark) 20 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_heatmap.py $2 21 | ;; 22 | 23 | breakdown) 24 | python3 $TRICACHE_ROOT/ae-plot-scripts/calc_breakdown.py $2 25 | ;; 26 | 27 | small) 28 | python3 $TRICACHE_ROOT/ae-plot-scripts/calc_small.py $2 29 | ;; 30 | 31 | *) 32 | echo ---------------- 33 | echo graph_processing 34 | echo 35 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_graph_processing.py $1 36 | echo ---------------- 37 | echo rocksdb 38 | echo 39 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_rocksdb.py $1 40 | echo ---------------- 41 | echo terasort 42 | echo 43 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_terasort.py $1 44 | echo ---------------- 45 | echo livegraph 46 | echo 47 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_livegraph.py $1 48 | echo ---------------- 49 | echo microbenchmark 50 | echo 51 | python3 $TRICACHE_ROOT/ae-plot-scripts/draw_heatmap.py $1 52 | echo ---------------- 53 | echo breakdown 54 | echo 55 | python3 $TRICACHE_ROOT/ae-plot-scripts/calc_breakdown.py $1 56 | echo ---------------- 57 | ;; 58 | esac 59 | -------------------------------------------------------------------------------- /scripts/prepare_fastmap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $TRICACHE_ROOT/scripts/config.sh 3 | 4 | dev="" 5 | for i in ${!SSDArray[@]}; do 6 | id="${SSDArray[$i]}" 7 | path="/dev/disk/by-id/$id" 8 | name=$(basename $(readlink $path)) 9 | 10 | echo $i $id $path $name 11 | 12 | dev="$dev $path" 13 | done 14 | 15 | sudo mdadm --stop /dev/md* 16 | echo yes | sudo mdadm --create --verbose /dev/md0 --level=0 --raid-devices=16 $dev 17 | sudo sgdisk -n 0:0:+1TB /dev/md0 18 | sudo dd if=/dev/zero of=/dev/md0p1 bs=1G count=256 19 | sudo $TRICACHE_ROOT/scripts/clearcache.sh 20 | -------------------------------------------------------------------------------- /scripts/reset_spdk.sh: -------------------------------------------------------------------------------- 1 | sleep 10 2 | echo 0 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages 3 | sudo $SPDK_ROOT/scripts/setup.sh reset 4 | echo 0 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages 5 | -------------------------------------------------------------------------------- /scripts/rmraid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo umount /mnt/raid 3 | sudo mdadm --stop /dev/md* 4 | -------------------------------------------------------------------------------- /scripts/rmswap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $TRICACHE_ROOT/scripts/config.sh 3 | 4 | for i in ${!SSDArray[@]}; do 5 | id="${SSDArray[$i]}" 6 | path="/dev/disk/by-id/$id" 7 | name=$(basename $(readlink $path)) 8 | numa=$(cat /sys/block/$name/device/numa_node) 9 | 10 | echo $i $id $path $name $numa 11 | 12 | sudo swapoff $path 13 | done 14 | -------------------------------------------------------------------------------- /scripts/rmxfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $TRICACHE_ROOT/scripts/config.sh 3 | 4 | for i in ${!SSDArray[@]}; do 5 | id="${SSDArray[$i]}" 6 | path="/dev/disk/by-id/$id" 7 | name=$(basename $(readlink $path)) 8 | numa=$(cat /sys/block/$name/device/numa_node) 9 | 10 | echo $i $id $path $name $numa 11 | 12 | sudo umount /mnt/ssd${i} 13 | done 14 | -------------------------------------------------------------------------------- /scripts/run_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/build.sh 3 | case $1 in 4 | graph_processing) 5 | $TRICACHE_ROOT/scripts/run_graph_processing.sh $2 6 | ;; 7 | 8 | rocksdb) 9 | $TRICACHE_ROOT/scripts/run_rocksdb.sh $2 10 | ;; 11 | 12 | terasort) 13 | $TRICACHE_ROOT/scripts/run_terasort.sh $2 14 | ;; 15 | 16 | livegraph) 17 | $TRICACHE_ROOT/scripts/run_livegraph.sh $2 18 | ;; 19 | 20 | breakdown) 21 | $TRICACHE_ROOT/scripts/run_breakdown.sh $2 22 | ;; 23 | 24 | microbenchmark) 25 | $TRICACHE_ROOT/scripts/run_microbenchmark.sh $2 26 | ;; 27 | 28 | *) 29 | $TRICACHE_ROOT/scripts/run_graph_processing.sh 30 | $TRICACHE_ROOT/scripts/run_rocksdb.sh 31 | $TRICACHE_ROOT/scripts/run_terasort.sh 32 | $TRICACHE_ROOT/scripts/run_livegraph.sh 33 | $TRICACHE_ROOT/scripts/run_microbenchmark.sh 34 | $TRICACHE_ROOT/scripts/run_breakdown.sh 35 | ;; 36 | esac 37 | -------------------------------------------------------------------------------- /scripts/run_all_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/build.sh 3 | 4 | $TRICACHE_ROOT/scripts/build_ligra.sh 5 | $TRICACHE_ROOT/scripts/setup_spdk.sh 128 6 | $TRICACHE_ROOT/scripts/run_ligra_cache_small.sh 7 | $TRICACHE_ROOT/scripts/reset_spdk.sh 8 | 9 | $TRICACHE_ROOT/scripts/build_ligra.sh 10 | $TRICACHE_ROOT/scripts/mkswap.sh 11 | $TRICACHE_ROOT/scripts/run_ligra_swap_small.sh 12 | $TRICACHE_ROOT/scripts/rmswap.sh 13 | 14 | $TRICACHE_ROOT/scripts/build_flashgraph.sh 15 | $TRICACHE_ROOT/scripts/mkxfs.sh 16 | $TRICACHE_ROOT/scripts/load_to_flashgraph.sh 17 | $TRICACHE_ROOT/scripts/run_flashgraph_small.sh 18 | $TRICACHE_ROOT/scripts/rmxfs.sh 19 | 20 | $TRICACHE_ROOT/scripts/build_rocksdb.sh 21 | $TRICACHE_ROOT/scripts/setup_spdk.sh 64 22 | $TRICACHE_ROOT/scripts/run_rocksdb_cache_small.sh 23 | $TRICACHE_ROOT/scripts/reset_spdk.sh 24 | 25 | $TRICACHE_ROOT/scripts/build_rocksdb.sh 26 | $TRICACHE_ROOT/scripts/mkraid.sh 27 | $TRICACHE_ROOT/scripts/run_rocksdb_block_small.sh 28 | $TRICACHE_ROOT/scripts/run_rocksdb_mmap_small.sh 29 | $TRICACHE_ROOT/scripts/rmraid.sh 30 | 31 | $TRICACHE_ROOT/scripts/setup_spdk.sh 64 32 | $TRICACHE_ROOT/scripts/run_terasort_cache_small.sh 33 | $TRICACHE_ROOT/scripts/reset_spdk.sh 34 | 35 | $TRICACHE_ROOT/scripts/mkswap.sh 36 | $TRICACHE_ROOT/scripts/run_terasort_swap_small.sh 37 | $TRICACHE_ROOT/scripts/rmswap.sh 38 | 39 | $TRICACHE_ROOT/scripts/build_terasort_spark.sh 40 | $TRICACHE_ROOT/scripts/mkxfs.sh 41 | $TRICACHE_ROOT/scripts/run_terasort_spark_small.sh 42 | sleep 60 43 | $TRICACHE_ROOT/scripts/rmxfs.sh 44 | 45 | $TRICACHE_ROOT/scripts/build_livegraph.sh 46 | $TRICACHE_ROOT/scripts/setup_spdk.sh 32 47 | $TRICACHE_ROOT/scripts/run_livegraph_cache_small.sh 48 | $TRICACHE_ROOT/scripts/reset_spdk.sh 49 | 50 | $TRICACHE_ROOT/scripts/build_livegraph.sh 51 | $TRICACHE_ROOT/scripts/mkraid.sh 52 | $TRICACHE_ROOT/scripts/run_livegraph_mmap_small.sh 53 | sleep 60 54 | $TRICACHE_ROOT/scripts/rmraid.sh 55 | 56 | $TRICACHE_ROOT/scripts/setup_spdk.sh 260 57 | $TRICACHE_ROOT/scripts/run_microbenchmark_cache_small.sh 58 | $TRICACHE_ROOT/scripts/reset_spdk.sh 59 | 60 | $TRICACHE_ROOT/scripts/mkraid.sh 61 | $TRICACHE_ROOT/scripts/run_microbenchmark_mmap_small.sh 62 | $TRICACHE_ROOT/scripts/rmraid.sh 63 | -------------------------------------------------------------------------------- /scripts/run_breakdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/build.sh 3 | $TRICACHE_ROOT/scripts/build_ligra.sh 4 | 5 | $TRICACHE_ROOT/scripts/setup_spdk.sh 64 6 | $TRICACHE_ROOT/scripts/run_terasort_breakdown.sh 7 | $TRICACHE_ROOT/scripts/run_ligra_breakdown.sh 8 | $TRICACHE_ROOT/scripts/reset_spdk.sh 9 | -------------------------------------------------------------------------------- /scripts/run_flashgraph.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | mkdir -p results_flashgraph 6 | 7 | function update_config 8 | { 9 | sed -i "s:root_conf=.*:root_conf=$TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/data_files.txt:" $1 10 | } 11 | 12 | for i in 512 256 128 64 32 16 13 | do 14 | echo $(expr $i \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 15 | 16 | update_config $TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/run_test_${i}G.txt 17 | 18 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/FlashX/build/flash-graph/test-algs/test_algs \ 19 | $TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/run_test_${i}G.txt uk-2014.adj uk-2014.index \ 20 | bfs -s 5 2>&1 | tee results_flashgraph/uk2014_BFS_${i}G.txt 21 | 22 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/FlashX/build/flash-graph/test-algs/test_algs \ 23 | $TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/run_test_${i}G.txt uk-2014.adj uk-2014.index \ 24 | pagerank -i 20 2>&1 | tee results_flashgraph/uk2014_PR_${i}G.txt 25 | 26 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/FlashX/build/flash-graph/test-algs/test_algs \ 27 | $TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/run_test_${i}G.txt uk-2014.adj uk-2014.index \ 28 | wcc -s 2>&1 | tee results_flashgraph/uk2014_WCC_${i}G.txt 29 | 30 | done 31 | -------------------------------------------------------------------------------- /scripts/run_flashgraph_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | mkdir -p results_small 6 | 7 | function update_config 8 | { 9 | sed -i "s:root_conf=.*:root_conf=$TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/data_files.txt:" $1 10 | } 11 | 12 | for i in 128 13 | do 14 | echo $(expr $i \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 15 | 16 | update_config $TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/run_test_${i}G.txt 17 | 18 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/FlashX/build/flash-graph/test-algs/test_algs \ 19 | $TRICACHE_ROOT/ae-projects/FlashX/flash-graph/conf/run_test_${i}G.txt uk-2014.adj uk-2014.index \ 20 | pagerank -i 20 2>&1 | tee results_small/PageRank_flashgraph.txt 21 | 22 | done 23 | -------------------------------------------------------------------------------- /scripts/run_graph_processing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function run_ligra_cache 3 | { 4 | $TRICACHE_ROOT/scripts/build_ligra.sh 5 | $TRICACHE_ROOT/scripts/setup_spdk.sh 362 6 | $TRICACHE_ROOT/scripts/run_ligra_cache.sh 7 | $TRICACHE_ROOT/scripts/reset_spdk.sh 8 | } 9 | 10 | function run_ligra_swap 11 | { 12 | $TRICACHE_ROOT/scripts/build_ligra.sh 13 | $TRICACHE_ROOT/scripts/mkswap.sh 14 | $TRICACHE_ROOT/scripts/run_ligra_swap.sh 15 | $TRICACHE_ROOT/scripts/rmswap.sh 16 | } 17 | 18 | function run_ligra_swap_slow 19 | { 20 | $TRICACHE_ROOT/scripts/build_ligra.sh 21 | $TRICACHE_ROOT/scripts/mkswap.sh 22 | $TRICACHE_ROOT/scripts/run_ligra_swap_slow.sh 23 | $TRICACHE_ROOT/scripts/rmswap.sh 24 | } 25 | 26 | function run_flashgraph 27 | { 28 | $TRICACHE_ROOT/scripts/build_flashgraph.sh 29 | $TRICACHE_ROOT/scripts/mkxfs.sh 30 | $TRICACHE_ROOT/scripts/load_to_flashgraph.sh 31 | $TRICACHE_ROOT/scripts/run_flashgraph.sh 32 | $TRICACHE_ROOT/scripts/rmxfs.sh 33 | } 34 | 35 | case $1 in 36 | ligra_cache) 37 | run_ligra_cache 38 | ;; 39 | 40 | ligra_swap) 41 | run_ligra_swap 42 | ;; 43 | 44 | ligra_swap_slow) 45 | run_ligra_swap_slow 46 | ;; 47 | 48 | flashgraph) 49 | run_flashgraph 50 | ;; 51 | 52 | *) 53 | run_ligra_cache 54 | run_ligra_swap 55 | run_flashgraph 56 | ;; 57 | esac 58 | -------------------------------------------------------------------------------- /scripts/run_ligra_breakdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | export CACHE_VIRT_SIZE=$(expr 32 \* 1024 \* 1024 \* 1024 \* 1024 ) 7 | source $TRICACHE_ROOT/scripts/config.sh 8 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 9 | export CACHE_DISABLE_PARALLEL_READ_WRITE=true 10 | 11 | function set_schedule { 12 | SCHEDULE=$1 13 | export OMP_SCHEDULE="${SCHEDULE}" 14 | } 15 | 16 | mkdir -p results_breakdown 17 | 18 | export CACHE_MALLOC_THRESHOLD=$(expr 4294967296 \* 2) 19 | set_schedule "dynamic,64" 20 | for threads in 960 21 | do 22 | export CACHE_NUM_CLIENTS=$threads 23 | export OMP_NUM_THREADS=$threads 24 | 25 | for i in 64 26 | do 27 | echo $(expr \( $i \/ 8 + 27 \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 28 | export CACHE_PHY_SIZE=$(expr \( $i - $i \/ 8 - 27 \) \* 1024 \* 1024 \* 1024 ) 29 | echo $CACHE_PHY_SIZE $CACHE_VIRT_SIZE 30 | 31 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 32 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta-cache -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_breakdown/PageRank_uk-2014.txt 33 | 34 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 35 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta-cache-profile -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_breakdown/PageRank_uk-2014_profile.txt 36 | 37 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 38 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta-cache-disable-direct -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_breakdown/PageRank_uk-2014_disable_direct.txt 39 | 40 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 41 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta-cache-disable-private -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_breakdown/PageRank_uk-2014_disable_private.txt 42 | 43 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 44 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta-cache-disable-direct-private -maxiters 20 -rounds 1 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_breakdown/PageRank_uk-2014_disable_direct_private.txt 45 | 46 | done 47 | done 48 | 49 | -------------------------------------------------------------------------------- /scripts/run_ligra_cache_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | export CACHE_VIRT_SIZE=$(expr 32 \* 1024 \* 1024 \* 1024 \* 1024 ) 7 | source $TRICACHE_ROOT/scripts/config.sh 8 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 9 | export CACHE_DISABLE_PARALLEL_READ_WRITE=true 10 | 11 | function set_schedule { 12 | SCHEDULE=$1 13 | export OMP_SCHEDULE="${SCHEDULE}" 14 | } 15 | 16 | mkdir -p results_small 17 | 18 | export CACHE_MALLOC_THRESHOLD=$(expr 4294967296 \* 4) 19 | set_schedule "dynamic,128" 20 | for threads in 960 21 | do 22 | export CACHE_NUM_CLIENTS=$threads 23 | export OMP_NUM_THREADS=$threads 24 | 25 | for i in 128 26 | do 27 | echo $(expr \( $i \/ 8 + 48 \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 28 | export CACHE_PHY_SIZE=$(expr \( $i - $i \/ 8 - 48 \) \* 1024 \* 1024 \* 1024 ) 29 | echo $CACHE_PHY_SIZE $CACHE_VIRT_SIZE 30 | 31 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 32 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta-cache -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_small/PageRank_ligra_cache.txt 33 | 34 | done 35 | done 36 | 37 | -------------------------------------------------------------------------------- /scripts/run_ligra_swap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | 7 | function set_schedule { 8 | SCHEDULE=$1 9 | export OMP_SCHEDULE="${SCHEDULE}" 10 | } 11 | 12 | mkdir -p results_ligra_swap 13 | 14 | for threads in 256 15 | do 16 | export OMP_NUM_THREADS=$threads 17 | 18 | for i in 512 19 | do 20 | echo $(expr \( $i \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 21 | set_schedule "dynamic,256" 22 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/BFS -r 5 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_ligra_swap/BFS_uk-2014_${i}G_${threads}.txt 23 | set_schedule "guided" 24 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_ligra_swap/PageRankDelta_uk-2014_${i}G_${threads}.txt 25 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/Components -s -b /mnt/data/TriCache/ligra/uk-2014-sym 2>&1 | tee results_ligra_swap/CC_uk-2014_${i}G_${threads}.txt 26 | done 27 | done 28 | 29 | for threads in 256 30 | do 31 | export OMP_NUM_THREADS=$threads 32 | 33 | for i in 256 34 | do 35 | echo $(expr \( $i \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 36 | set_schedule "dynamic,64" 37 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/BFS -r 5 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_ligra_swap/BFS_uk-2014_${i}G_${threads}.txt 38 | set_schedule "static,64" 39 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_ligra_swap/PageRankDelta_uk-2014_${i}G_${threads}.txt 40 | set_schedule "dynamic,64" 41 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/Components -rounds 1 -s -b /mnt/data/TriCache/ligra/uk-2014-sym 2>&1 | tee results_ligra_swap/CC_uk-2014_${i}G_${threads}.txt 42 | done 43 | done 44 | 45 | set_schedule "dynamic,64" 46 | for threads in 256 47 | do 48 | export OMP_NUM_THREADS=$threads 49 | 50 | for i in 128 #64 32 16 51 | do 52 | echo $(expr \( $i \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 53 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/BFS -rounds 1 -r 5 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_ligra_swap/BFS_uk-2014_${i}G_${threads}.txt 54 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta -rounds 1 -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_ligra_swap/PageRankDelta_uk-2014_${i}G_${threads}.txt 55 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/Components -rounds 1 -s -b /mnt/data/TriCache/ligra/uk-2014-sym 2>&1 | tee results_ligra_swap/CC_uk-2014_${i}G_${threads}.txt 56 | done 57 | done 58 | -------------------------------------------------------------------------------- /scripts/run_ligra_swap_slow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | 7 | function set_schedule { 8 | SCHEDULE=$1 9 | export OMP_SCHEDULE="${SCHEDULE}" 10 | } 11 | 12 | mkdir -p results_ligra_swap 13 | 14 | set_schedule "dynamic,64" 15 | for threads in 256 16 | do 17 | export OMP_NUM_THREADS=$threads 18 | 19 | for i in 64 32 16 20 | do 21 | echo $(expr \( $i \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 22 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/BFS -rounds 1 -r 5 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_ligra_swap/BFS_uk-2014_${i}G_${threads}.txt 23 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta -rounds 1 -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_ligra_swap/PageRankDelta_uk-2014_${i}G_${threads}.txt 24 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/Components -rounds 1 -s -b /mnt/data/TriCache/ligra/uk-2014-sym 2>&1 | tee results_ligra_swap/CC_uk-2014_${i}G_${threads}.txt 25 | done 26 | done 27 | -------------------------------------------------------------------------------- /scripts/run_ligra_swap_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | 7 | function set_schedule { 8 | SCHEDULE=$1 9 | export OMP_SCHEDULE="${SCHEDULE}" 10 | } 11 | 12 | mkdir -p results_small 13 | 14 | set_schedule "dynamic,64" 15 | for threads in 256 16 | do 17 | export OMP_NUM_THREADS=$threads 18 | 19 | for i in 128 20 | do 21 | echo $(expr \( $i \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 22 | stdbuf -oL /usr/bin/time -v numactl -i all $TRICACHE_ROOT/ae-projects/ligra/apps/PageRankDelta -rounds 1 -maxiters 20 -b /mnt/data/TriCache/ligra/uk-2014 2>&1 | tee results_small/PageRank_ligra_swap.txt 23 | done 24 | done 25 | -------------------------------------------------------------------------------- /scripts/run_livegraph.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function run_livegraph_cache 3 | { 4 | $TRICACHE_ROOT/scripts/build_livegraph.sh 5 | $TRICACHE_ROOT/scripts/setup_spdk.sh 260 6 | $TRICACHE_ROOT/scripts/run_livegraph_cache.sh 7 | $TRICACHE_ROOT/scripts/reset_spdk.sh 8 | } 9 | 10 | function run_livegraph_mmap 11 | { 12 | $TRICACHE_ROOT/scripts/build_livegraph.sh 13 | $TRICACHE_ROOT/scripts/mkraid.sh 14 | $TRICACHE_ROOT/scripts/run_livegraph_mmap.sh 15 | sleep 60 16 | $TRICACHE_ROOT/scripts/rmraid.sh 17 | } 18 | 19 | case $1 in 20 | livegraph_cache) 21 | run_livegraph_cache 22 | ;; 23 | 24 | livegraph_mmap) 25 | run_livegraph_mmap 26 | ;; 27 | 28 | *) 29 | run_livegraph_cache 30 | run_livegraph_mmap 31 | ;; 32 | esac 33 | -------------------------------------------------------------------------------- /scripts/run_livegraph_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | 4 | export LIVEGRAPH_NUM_CLIENTS=480 5 | 6 | mkdir -p results_livegraph_cache 7 | 8 | for i in 256 128 64 32 16 9 | do 10 | echo $(expr \( $i \/ 8 \* 2 + 8 \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 11 | export CACHE_PHY_SIZE=$(expr \( $i \/ 8 \* 6 - 8 \) \* 1024 \* 1024 \* 1024 ) 12 | echo $CACHE_PHY_SIZE $CACHE_VIRT_SIZE 13 | $TRICACHE_ROOT/scripts/livegraph_cp_dataset_cache.sh 30 14 | $TRICACHE_ROOT/scripts/livegraph_exec_cache.sh 30 & 15 | sleep 10000000 16 | sleep 10 17 | java -Xms32g -Xmx32g -cp $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/target/livegraph-0.3.5-SNAPSHOT.jar com.ldbc.driver.Client -P $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/interactive-benchmark-cache-sf30.properties --results_dir results_livegraph_cache/results_all_16_sf30_cache_${i}G 18 | sudo killall -9 snb_server 19 | sleep 30 20 | done 21 | 22 | for i in 256 128 64 32 16 23 | do 24 | echo $(expr \( $i \/ 8 \* 2 + 10 \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 25 | export CACHE_PHY_SIZE=$(expr \( $i \/ 8 \* 6 - 10 \) \* 1024 \* 1024 \* 1024 ) 26 | echo $CACHE_PHY_SIZE $CACHE_VIRT_SIZE 27 | $TRICACHE_ROOT/scripts/livegraph_cp_dataset_cache.sh 100 28 | $TRICACHE_ROOT/scripts/livegraph_exec_cache.sh 100 & 29 | sleep 10000000 30 | sleep 10 31 | java -Xms32g -Xmx32g -cp $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/target/livegraph-0.3.5-SNAPSHOT.jar com.ldbc.driver.Client -P $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/interactive-benchmark-cache-sf100.properties --results_dir results_livegraph_cache/results_all_16_sf100_cache_${i}G 32 | sudo killall -9 snb_server 33 | sleep 30 34 | done 35 | -------------------------------------------------------------------------------- /scripts/run_livegraph_cache_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | 4 | export LIVEGRAPH_NUM_CLIENTS=480 5 | 6 | mkdir -p results_small 7 | 8 | for i in 32 9 | do 10 | echo $(expr \( $i \/ 8 \* 2 + 8 \) \* 1024 \* 1024 \* 1024) | sudo tee /sys/fs/cgroup/limit/memory.max 11 | export CACHE_PHY_SIZE=$(expr \( $i \/ 8 \* 6 - 8 \) \* 1024 \* 1024 \* 1024 ) 12 | echo $CACHE_PHY_SIZE $CACHE_VIRT_SIZE 13 | $TRICACHE_ROOT/scripts/livegraph_cp_dataset_cache.sh 30 14 | $TRICACHE_ROOT/scripts/livegraph_exec_cache.sh 30 & 15 | sleep 10000000 16 | sleep 10 17 | java -Xms32g -Xmx32g -cp $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/target/livegraph-0.3.5-SNAPSHOT.jar com.ldbc.driver.Client -P $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/interactive-benchmark-cache-sf30.properties --results_dir results_small/livegraph_cache 18 | sudo killall -9 snb_server 19 | sleep 30 20 | done 21 | -------------------------------------------------------------------------------- /scripts/run_livegraph_mmap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | 4 | export LIVEGRAPH_NUM_CLIENTS=512 5 | 6 | mkdir -p results_livegraph_mmap 7 | 8 | for i in 256 128 64 9 | do 10 | echo ${i}G | sudo tee /sys/fs/cgroup/limit/memory.max 11 | $TRICACHE_ROOT/scripts/livegraph_cp_dataset_mmap.sh 30 12 | $TRICACHE_ROOT/scripts/livegraph_exec_mmap.sh 30 & 13 | sleep 10000000 14 | sleep 10 15 | java -Xms32g -Xmx32g -cp $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/target/livegraph-0.3.5-SNAPSHOT.jar com.ldbc.driver.Client -P $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/interactive-benchmark-mmap-sf30.properties --results_dir results_livegraph_mmap/results_all_16_sf30_mmap_${i}G 16 | sudo killall -9 snb_server 17 | done 18 | 19 | for i in 32 16 20 | do 21 | echo ${i}G | sudo tee /sys/fs/cgroup/limit/memory.max 22 | $TRICACHE_ROOT/scripts/livegraph_cp_dataset_mmap.sh 30 23 | $TRICACHE_ROOT/scripts/livegraph_exec_mmap.sh 30 & 24 | sleep 10000000 25 | sleep 10 26 | java -Xms32g -Xmx32g -cp $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/target/livegraph-0.3.5-SNAPSHOT.jar com.ldbc.driver.Client -P $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/interactive-benchmark-mmap-sf30-slow.properties --results_dir results_livegraph_mmap/results_all_16_sf30_mmap_${i}G 27 | sudo killall -9 snb_server 28 | done 29 | 30 | for i in 256 128 31 | do 32 | echo ${i}G | sudo tee /sys/fs/cgroup/limit/memory.max 33 | $TRICACHE_ROOT/scripts/livegraph_cp_dataset_mmap.sh 100 34 | $TRICACHE_ROOT/scripts/livegraph_exec_mmap.sh 100 & 35 | sleep 10000000 36 | sleep 10 37 | java -Xms32g -Xmx32g -cp $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/target/livegraph-0.3.5-SNAPSHOT.jar com.ldbc.driver.Client -P $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/interactive-benchmark-mmap-sf100.properties --results_dir results_livegraph_mmap/results_all_16_sf100_mmap_${i}G 38 | sudo killall -9 snb_server 39 | done 40 | 41 | for i in 64 32 16 42 | do 43 | echo ${i}G | sudo tee /sys/fs/cgroup/limit/memory.max 44 | $TRICACHE_ROOT/scripts/livegraph_cp_dataset_mmap.sh 100 45 | $TRICACHE_ROOT/scripts/livegraph_exec_mmap.sh 100 & 46 | sleep 10000000 47 | sleep 10 48 | java -Xms32g -Xmx32g -cp $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/target/livegraph-0.3.5-SNAPSHOT.jar com.ldbc.driver.Client -P $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/interactive-benchmark-mmap-sf100-slow.properties --results_dir results_livegraph_mmap/results_all_16_sf100_mmap_${i}G 49 | sudo killall -9 snb_server 50 | done 51 | 52 | -------------------------------------------------------------------------------- /scripts/run_livegraph_mmap_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | 4 | export LIVEGRAPH_NUM_CLIENTS=512 5 | 6 | mkdir -p results_small 7 | 8 | for i in 32 9 | do 10 | echo ${i}G | sudo tee /sys/fs/cgroup/limit/memory.max 11 | $TRICACHE_ROOT/scripts/livegraph_cp_dataset_mmap.sh 30 12 | $TRICACHE_ROOT/scripts/livegraph_exec_mmap.sh 30 & 13 | sleep 10000000 14 | sleep 10 15 | java -Xms32g -Xmx32g -cp $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/target/livegraph-0.3.5-SNAPSHOT.jar com.ldbc.driver.Client -P $TRICACHE_ROOT/ae-projects/ldbc_snb_implementations/livegraph/interactive-benchmark-mmap-sf30-slow.properties --results_dir results_small/livegraph_mmap 16 | sudo killall -9 snb_server 17 | done 18 | -------------------------------------------------------------------------------- /scripts/run_microbenchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function run_microbenchmark_cache 3 | { 4 | $TRICACHE_ROOT/scripts/setup_spdk.sh 260 5 | $TRICACHE_ROOT/scripts/run_microbenchmark_cache.sh 6 | $TRICACHE_ROOT/scripts/reset_spdk.sh 7 | } 8 | 9 | function run_microbenchmark_mmap 10 | { 11 | $TRICACHE_ROOT/scripts/mkraid.sh 12 | $TRICACHE_ROOT/scripts/run_microbenchmark_mmap.sh 13 | $TRICACHE_ROOT/scripts/rmraid.sh 14 | } 15 | 16 | case $1 in 17 | microbenchmark_cache) 18 | run_microbenchmark_cache 19 | ;; 20 | 21 | microbenchmark_mmap) 22 | run_microbenchmark_mmap 23 | ;; 24 | 25 | *) 26 | run_microbenchmark_cache 27 | run_microbenchmark_mmap 28 | ;; 29 | esac 30 | -------------------------------------------------------------------------------- /scripts/run_microbenchmark_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export CACHE_PHY_SIZE=137438953472 6 | export CACHE_VIRT_SIZE=2199023255552 7 | export OMP_PROC_BIND=true 8 | source $TRICACHE_ROOT/scripts/config.sh 9 | export CACHE_CONFIG=$CACHE_32_SERVER_CONFIG 10 | 11 | vmemory=256 12 | export CACHE_VIRT_SIZE=$(expr $vmemory \* 1024 \* 1024 \* 1024) 13 | export CACHE_MALLOC_THRESHOLD=$(expr 1024 \* 1024 \* 1024) 14 | 15 | mkdir -p results_microbenchmark_cache 16 | 17 | export THREADS=1792 18 | export CACHE_NUM_CLIENTS=$THREADS 19 | export OMP_NUM_THREADS=$THREADS 20 | 21 | for i in 1.0 22 | do 23 | export CACHE_PHY_SIZE=$(echo "print(int($CACHE_VIRT_SIZE / 4096 * $i) * 4096)" | python3) 24 | echo $CACHE_PHY_SIZE 25 | 26 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 27 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 28 | 5000000 \ 29 | $vmemory \ 30 | $i \ 31 | 0 \ 32 | 2>&1 | tee results_microbenchmark_cache/micro_${i}_$THREADS.log 33 | done 34 | 35 | for i in 0.9 36 | do 37 | export CACHE_PHY_SIZE=$(echo "print(int($CACHE_VIRT_SIZE / 4096 * $i) * 4096)" | python3) 38 | echo $CACHE_PHY_SIZE 39 | 40 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 41 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 42 | 800000 \ 43 | $vmemory \ 44 | $i \ 45 | 0 \ 46 | 2>&1 | tee results_microbenchmark_cache/micro_${i}_$THREADS.log 47 | 48 | done 49 | 50 | export THREADS=896 51 | export CACHE_NUM_CLIENTS=$THREADS 52 | export OMP_NUM_THREADS=$THREADS 53 | 54 | for i in 1.0 55 | do 56 | export CACHE_PHY_SIZE=$(echo "print(int($CACHE_VIRT_SIZE / 4096 * $i) * 4096)" | python3) 57 | echo $CACHE_PHY_SIZE 58 | 59 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 60 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 61 | 1000000 \ 62 | $vmemory \ 63 | $i \ 64 | 1 \ 65 | 2>&1 | tee results_microbenchmark_cache/micro_allpage_${i}_$THREADS.log 66 | done 67 | 68 | for i in 0.9 69 | do 70 | export CACHE_PHY_SIZE=$(echo "print(int($CACHE_VIRT_SIZE / 4096 * $i) * 4096)" | python3) 71 | echo $CACHE_PHY_SIZE 72 | 73 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 74 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 75 | 800000 \ 76 | $vmemory \ 77 | $i \ 78 | 1 \ 79 | 2>&1 | tee results_microbenchmark_cache/micro_allpage_${i}_$THREADS.log 80 | 81 | done 82 | 83 | export THREADS=1792 84 | export CACHE_NUM_CLIENTS=$THREADS 85 | export OMP_NUM_THREADS=$THREADS 86 | 87 | for i in 0.8 0.7 88 | do 89 | export CACHE_PHY_SIZE=$(echo "print(int($CACHE_VIRT_SIZE / 4096 * $i) * 4096)" | python3) 90 | echo $CACHE_PHY_SIZE 91 | 92 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 93 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 94 | 400000 \ 95 | $vmemory \ 96 | $i \ 97 | 0 \ 98 | 2>&1 | tee results_microbenchmark_cache/micro_${i}_$THREADS.log 99 | 100 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 101 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 102 | 400000 \ 103 | $vmemory \ 104 | $i \ 105 | 1 \ 106 | 2>&1 | tee results_microbenchmark_cache/micro_allpage_${i}_$THREADS.log 107 | 108 | done 109 | 110 | for i in 0.6 0.5 0.4 0.3 0.2 0.1 111 | do 112 | export CACHE_PHY_SIZE=$(echo "print(int($CACHE_VIRT_SIZE / 4096 * $i) * 4096)" | python3) 113 | echo $CACHE_PHY_SIZE 114 | 115 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 116 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 117 | 200000 \ 118 | $vmemory \ 119 | $i \ 120 | 0 \ 121 | 2>&1 | tee results_microbenchmark_cache/micro_${i}_$THREADS.log 122 | 123 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 124 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 125 | 200000 \ 126 | $vmemory \ 127 | $i \ 128 | 1 \ 129 | 2>&1 | tee results_microbenchmark_cache/micro_allpage_${i}_$THREADS.log 130 | done 131 | -------------------------------------------------------------------------------- /scripts/run_microbenchmark_cache_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export CACHE_PHY_SIZE=137438953472 6 | export CACHE_VIRT_SIZE=2199023255552 7 | export OMP_PROC_BIND=true 8 | source $TRICACHE_ROOT/scripts/config.sh 9 | export CACHE_CONFIG=$CACHE_32_SERVER_CONFIG 10 | 11 | vmemory=256 12 | export CACHE_VIRT_SIZE=$(expr $vmemory \* 1024 \* 1024 \* 1024) 13 | export CACHE_MALLOC_THRESHOLD=$(expr 1024 \* 1024 \* 1024) 14 | 15 | mkdir -p results_small 16 | 17 | export THREADS=1792 18 | export CACHE_NUM_CLIENTS=$THREADS 19 | export OMP_NUM_THREADS=$THREADS 20 | 21 | for i in 0.9 22 | do 23 | export CACHE_PHY_SIZE=$(echo "print(int($CACHE_VIRT_SIZE / 4096 * $i) * 4096)" | python3) 24 | echo $CACHE_PHY_SIZE 25 | 26 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 27 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 28 | 800000 \ 29 | $vmemory \ 30 | $i \ 31 | 0 \ 32 | 2>&1 | tee results_small/micro_cache.txt 33 | 34 | done 35 | 36 | export THREADS=896 37 | export CACHE_NUM_CLIENTS=$THREADS 38 | export OMP_NUM_THREADS=$THREADS 39 | 40 | for i in 0.9 41 | do 42 | export CACHE_PHY_SIZE=$(echo "print(int($CACHE_VIRT_SIZE / 4096 * $i) * 4096)" | python3) 43 | echo $CACHE_PHY_SIZE 44 | 45 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl --localalloc -C !$CACHE_32_SERVER_CORES \ 46 | stdbuf -oL $TRICACHE_ROOT/build/bench_hitrate_cache \ 47 | 800000 \ 48 | $vmemory \ 49 | $i \ 50 | 1 \ 51 | 2>&1 | tee results_small/micro_allpage_cache.txt 52 | 53 | done 54 | 55 | -------------------------------------------------------------------------------- /scripts/run_microbenchmark_fastmap_driver.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | for i in 1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 3 | do 4 | ssh -o ServerAliveInterval=90 $1 "source ~/.bashrc; cd $2; "'echo $PWD; bash $TRICACHE_ROOT/scripts/run_microbenchmark_fastmap.sh '"$i" 5 | sleep 30 6 | ssh -o ServerAliveInterval=90 $1 "source ~/.bashrc; cd $2; "'echo $PWD; bash $TRICACHE_ROOT/scripts/run_microbenchmark_fastmap.sh '"allpage_$i" 7 | sleep 30 8 | done 9 | sleep 30 10 | ssh -o ServerAliveInterval=90 $1 "source ~/.bashrc; cd $2; "'echo $PWD; bash $TRICACHE_ROOT/scripts/run_microbenchmark_fastmap.sh '"finish" 11 | 12 | -------------------------------------------------------------------------------- /scripts/run_microbenchmark_mmap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | vmemory=256 6 | export OMP_NUM_THREADS=256 7 | export OMP_PROC_BIND=true 8 | 9 | mkdir -p results_microbenchmark_mmap 10 | 11 | dd if=/dev/zero of=/mnt/raid/temp/data.mmap bs=1G count=256 12 | sudo $TRICACHE_ROOT/scripts/clearcache.sh 13 | 14 | for i in 1.0 15 | do 16 | echo "print(int($vmemory * 1024 * 1024 * 1024 * $i) + 2 * 1024 * 1024 * 1024)" | python3 | sudo tee /sys/fs/cgroup/limit/memory.max 17 | 18 | stdbuf -oL numactl --interleave all $TRICACHE_ROOT/build/bench_hitrate_mmap \ 19 | 5000000 \ 20 | $vmemory \ 21 | $i \ 22 | 0 \ 23 | /mnt/raid/temp/data.mmap \ 24 | 2>&1 | tee results_microbenchmark_mmap/micro_${i}_$OMP_NUM_THREADS.log 25 | 26 | stdbuf -oL numactl --interleave all $TRICACHE_ROOT/build/bench_hitrate_mmap \ 27 | 500000 \ 28 | $vmemory \ 29 | $i \ 30 | 1 \ 31 | /mnt/raid/temp/data.mmap \ 32 | 2>&1 | tee results_microbenchmark_mmap/micro_allpage_${i}_$OMP_NUM_THREADS.log 33 | 34 | done 35 | 36 | for i in 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 37 | do 38 | echo "print(int($vmemory * 1024 * 1024 * 1024 * $i) + 2 * 1024 * 1024 * 1024)" | python3 | sudo tee /sys/fs/cgroup/limit/memory.max 39 | 40 | stdbuf -oL numactl --interleave all $TRICACHE_ROOT/build/bench_hitrate_mmap \ 41 | 50000 \ 42 | $vmemory \ 43 | $i \ 44 | 0 \ 45 | /mnt/raid/temp/data.mmap \ 46 | 2>&1 | tee results_microbenchmark_mmap/micro_${i}_$OMP_NUM_THREADS.log 47 | 48 | stdbuf -oL numactl --interleave all $TRICACHE_ROOT/build/bench_hitrate_mmap \ 49 | 20000 \ 50 | $vmemory \ 51 | $i \ 52 | 1 \ 53 | /mnt/raid/temp/data.mmap \ 54 | 2>&1 | tee results_microbenchmark_mmap/micro_allpage_${i}_$OMP_NUM_THREADS.log 55 | done 56 | -------------------------------------------------------------------------------- /scripts/run_microbenchmark_mmap_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | vmemory=256 6 | export OMP_NUM_THREADS=256 7 | export OMP_PROC_BIND=true 8 | 9 | mkdir -p results_small 10 | 11 | dd if=/dev/zero of=/mnt/raid/temp/data.mmap bs=1G count=256 12 | sudo $TRICACHE_ROOT/scripts/clearcache.sh 13 | 14 | for i in 0.9 15 | do 16 | echo "print(int($vmemory * 1024 * 1024 * 1024 * $i) + 2 * 1024 * 1024 * 1024)" | python3 | sudo tee /sys/fs/cgroup/limit/memory.max 17 | 18 | stdbuf -oL numactl --interleave all $TRICACHE_ROOT/build/bench_hitrate_mmap \ 19 | 100000 \ 20 | $vmemory \ 21 | $i \ 22 | 0 \ 23 | /mnt/raid/temp/data.mmap \ 24 | 2>&1 | tee results_small/micro_mmap.txt 25 | 26 | stdbuf -oL numactl --interleave all $TRICACHE_ROOT/build/bench_hitrate_mmap \ 27 | 50000 \ 28 | $vmemory \ 29 | $i \ 30 | 1 \ 31 | /mnt/raid/temp/data.mmap \ 32 | 2>&1 | tee results_small/micro_allpage_mmap.txt 33 | done 34 | -------------------------------------------------------------------------------- /scripts/run_rocksdb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function run_rocksdb_cache 3 | { 4 | $TRICACHE_ROOT/scripts/build_rocksdb.sh 5 | $TRICACHE_ROOT/scripts/setup_spdk.sh 260 6 | $TRICACHE_ROOT/scripts/run_rocksdb_cache.sh 7 | $TRICACHE_ROOT/scripts/reset_spdk.sh 8 | } 9 | 10 | function run_rocksdb_block 11 | { 12 | $TRICACHE_ROOT/scripts/build_rocksdb.sh 13 | $TRICACHE_ROOT/scripts/mkraid.sh 14 | $TRICACHE_ROOT/scripts/run_rocksdb_block.sh 15 | $TRICACHE_ROOT/scripts/rmraid.sh 16 | } 17 | 18 | function run_rocksdb_mmap 19 | { 20 | $TRICACHE_ROOT/scripts/build_rocksdb.sh 21 | $TRICACHE_ROOT/scripts/mkraid.sh 22 | $TRICACHE_ROOT/scripts/run_rocksdb_mmap.sh 23 | $TRICACHE_ROOT/scripts/rmraid.sh 24 | } 25 | 26 | case $1 in 27 | rocksdb_cache) 28 | run_rocksdb_cache 29 | ;; 30 | 31 | rocksdb_block) 32 | run_rocksdb_block 33 | ;; 34 | 35 | rocksdb_mmap) 36 | run_rocksdb_mmap 37 | ;; 38 | 39 | *) 40 | run_rocksdb_cache 41 | run_rocksdb_block 42 | run_rocksdb_mmap 43 | ;; 44 | esac 45 | -------------------------------------------------------------------------------- /scripts/run_rocksdb_block.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | $TRICACHE_ROOT/scripts/cgroups.sh 4 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 5 | 6 | export THREADS=256 7 | export BACKGROUND=4 8 | 9 | export REQUESTS=100000000 10 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 11 | 12 | mkdir -p results_rocksdb_block 13 | 14 | for MEM_GB in 256 15 | do 16 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 17 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 18 | 19 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_block_4/ /mnt/raid/temp/2000M_block_run 20 | 21 | stdbuf -oL /usr/bin/time -v /usr/bin/time -v numactl -i all \ 22 | $TRICACHE_ROOT/ae-projects/rocksdb/build-orig/db_bench -benchmarks="levelstats,readrandom,mixgraph,levelstats" -disable_wal \ 23 | -use_direct_io_for_flush_and_compaction=true -use_direct_reads=true -cache_size=$(expr \( $MEM_GB \/ 8 \* 7 \) \* 1024 \* 1024 \* 1024) -cache_numshardbits=10 -compression_type=none \ 24 | -key_size=48 -value_size=43 \ 25 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 26 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 27 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 28 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 29 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 30 | -prefix_size=4 -use_hash_search=true \ 31 | -target_file_size_multiplier=10 \ 32 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 33 | -max_background_flushes=$BACKGROUND \ 34 | -max_background_compactions=$BACKGROUND \ 35 | -write_thread_max_yield_usec=100000000 \ 36 | -write_thread_slow_yield_usec=10000000 \ 37 | -write_buffer_size=1073741824 \ 38 | -db=/mnt/raid/temp/2000M_block_run -use_existing_db=true \ 39 | 2>&1 | tee results_rocksdb_block/block_${MEM_GB}G_${THREADS}.txt 40 | done 41 | 42 | for THREADS in 256 43 | do 44 | export BACKGROUND=4 45 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 46 | for MEM_GB in 128 64 47 | do 48 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 49 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 50 | 51 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_block_4/ /mnt/raid/temp/2000M_block_run 52 | 53 | stdbuf -oL /usr/bin/time -v /usr/bin/time -v numactl -i all \ 54 | $TRICACHE_ROOT/ae-projects/rocksdb/build-orig/db_bench -benchmarks="levelstats,readrandom,mixgraph,levelstats" -disable_wal \ 55 | -use_direct_io_for_flush_and_compaction=true -use_direct_reads=true -cache_size=$(expr \( $MEM_GB \/ 4 \* 2 \) \* 1024 \* 1024 \* 1024) -cache_numshardbits=10 -compression_type=none \ 56 | -key_size=48 -value_size=43 \ 57 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 58 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 59 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 60 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 61 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 62 | -prefix_size=4 -use_hash_search=true \ 63 | -target_file_size_multiplier=10 \ 64 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 65 | -max_background_flushes=$BACKGROUND \ 66 | -max_background_compactions=$BACKGROUND \ 67 | -write_thread_max_yield_usec=100000000 \ 68 | -write_thread_slow_yield_usec=10000000 \ 69 | -write_buffer_size=1073741824 \ 70 | -db=/mnt/raid/temp/2000M_block_run -use_existing_db=true \ 71 | 2>&1 | tee results_rocksdb_block/block_${MEM_GB}G_${THREADS}.txt 72 | done 73 | done 74 | 75 | export REQUESTS=20000000 76 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 77 | for THREADS in 256 78 | do 79 | export BACKGROUND=4 80 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 81 | for MEM_GB in 32 16 82 | do 83 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 84 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 85 | 86 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_block_4/ /mnt/raid/temp/2000M_block_run 87 | 88 | stdbuf -oL /usr/bin/time -v /usr/bin/time -v numactl -i all \ 89 | $TRICACHE_ROOT/ae-projects/rocksdb/build-orig/db_bench -benchmarks="levelstats,readrandom,mixgraph,levelstats" -disable_wal \ 90 | -use_direct_io_for_flush_and_compaction=true -use_direct_reads=true -cache_size=$(expr \( $MEM_GB \/ 8 \* 2 \) \* 1024 \* 1024 \* 1024) -cache_numshardbits=10 -compression_type=none \ 91 | -key_size=48 -value_size=43 \ 92 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 93 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 94 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 95 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 96 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 97 | -prefix_size=4 -use_hash_search=true \ 98 | -target_file_size_multiplier=10 \ 99 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 100 | -max_background_flushes=$BACKGROUND \ 101 | -max_background_compactions=$BACKGROUND \ 102 | -write_thread_max_yield_usec=100000000 \ 103 | -write_thread_slow_yield_usec=10000000 \ 104 | -write_buffer_size=1073741824 \ 105 | -db=/mnt/raid/temp/2000M_block_run -use_existing_db=true \ 106 | 2>&1 | tee results_rocksdb_block/block_${MEM_GB}G_${THREADS}.txt 107 | done 108 | done 109 | -------------------------------------------------------------------------------- /scripts/run_rocksdb_block_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | $TRICACHE_ROOT/scripts/cgroups.sh 4 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 5 | 6 | export THREADS=256 7 | export BACKGROUND=4 8 | 9 | export REQUESTS=100000000 10 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 11 | 12 | mkdir -p results_small 13 | 14 | for THREADS in 256 15 | do 16 | export BACKGROUND=4 17 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 18 | for MEM_GB in 64 19 | do 20 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 21 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 22 | 23 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_block_4/ /mnt/raid/temp/2000M_block_run 24 | 25 | stdbuf -oL /usr/bin/time -v /usr/bin/time -v numactl -i all \ 26 | $TRICACHE_ROOT/ae-projects/rocksdb/build-orig/db_bench -benchmarks="levelstats,readrandom,mixgraph,levelstats" -disable_wal \ 27 | -use_direct_io_for_flush_and_compaction=true -use_direct_reads=true -cache_size=$(expr \( $MEM_GB \/ 4 \* 2 \) \* 1024 \* 1024 \* 1024) -cache_numshardbits=10 -compression_type=none \ 28 | -key_size=48 -value_size=43 \ 29 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 30 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 31 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 32 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 33 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 34 | -prefix_size=4 -use_hash_search=true \ 35 | -target_file_size_multiplier=10 \ 36 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 37 | -max_background_flushes=$BACKGROUND \ 38 | -max_background_compactions=$BACKGROUND \ 39 | -write_thread_max_yield_usec=100000000 \ 40 | -write_thread_slow_yield_usec=10000000 \ 41 | -write_buffer_size=1073741824 \ 42 | -db=/mnt/raid/temp/2000M_block_run -use_existing_db=true \ 43 | 2>&1 | tee results_small/rocksdb_block.txt 44 | done 45 | done 46 | -------------------------------------------------------------------------------- /scripts/run_rocksdb_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | export CACHE_VIRT_SIZE=$(expr 32 \* 1024 \* 1024 \* 1024 \* 1024) 7 | source $TRICACHE_ROOT/scripts/config.sh 8 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 9 | export CACHE_NUM_CLIENTS=1024 10 | 11 | export CACHE_MALLOC_THRESHOLD=$(expr 500 \* 1024 \* 1024) 12 | export CACHE_MMAP_FILE_THRESHOLD=$(expr 16 \* 1024 \* 1024) 13 | 14 | export CACHE_DISABLE_PARALLEL_READ_WRITE=true 15 | 16 | mkdir -p results_rocksdb_cache 17 | 18 | sudo mkdir -p /mnt/data/TriCache/temp 19 | 20 | export CACHE_NUM_CLIENTS=256 21 | export REQUESTS=100000000 22 | export THREADS=238 23 | export BACKGROUND=4 24 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 25 | for MEM_GB in 256 26 | do 27 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 8 \* 7 \) \* 1024 \* 1024 \* 1024) 28 | export MEMORY=$(expr \( $MEM_GB \/ 8 \* 1 \) \* 1024 \* 1024 \* 1024) 29 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 30 | 31 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_plain_4/ /mnt/data/TriCache/temp/2000M_plain_run 32 | 33 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" stdbuf -oL /usr/bin/time -v numactl -i all -C !$CACHE_16_SERVER_CORES \ 34 | $TRICACHE_ROOT/ae-projects/rocksdb/build-cache/db_bench -benchmarks="levelstats,mixgraph,levelstats" -disable_wal \ 35 | -use_plain_table -mmap_read -mmap_write -compression_type=none \ 36 | -key_size=48 -value_size=43 \ 37 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 38 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 39 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 40 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 41 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 42 | -prefix_size=4 \ 43 | -target_file_size_multiplier=10 \ 44 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 45 | -max_background_flushes=$BACKGROUND \ 46 | -max_background_compactions=$BACKGROUND \ 47 | -write_thread_max_yield_usec=100000000 \ 48 | -write_thread_slow_yield_usec=10000000 \ 49 | -write_buffer_size=1073741824 \ 50 | -db=/mnt/data/TriCache/temp/2000M_plain_run -use_existing_db=true \ 51 | 2>&1 | tee results_rocksdb_cache/plain_cache_${MEM_GB}G_${THREADS}.txt 52 | 53 | done 54 | 55 | export CACHE_NUM_CLIENTS=1024 56 | export REQUESTS=100000000 57 | export THREADS=940 58 | export BACKGROUND=4 59 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 60 | for MEM_GB in 128 64 32 16 #128 #64 #128 64 #128 64 61 | do 62 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 16 \* 6 \) \* 1024 \* 1024 \* 1024) 63 | export MEMORY=$(expr \( $MEM_GB \/ 16 \* 10 \) \* 1024 \* 1024 \* 1024) 64 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 65 | 66 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_plain_4/ /mnt/data/TriCache/temp/2000M_plain_run 67 | 68 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" stdbuf -oL /usr/bin/time -v numactl -i all -C !$CACHE_16_SERVER_CORES \ 69 | $TRICACHE_ROOT/ae-projects/rocksdb/build-cache/db_bench -benchmarks="levelstats,mixgraph,levelstats" -disable_wal \ 70 | -use_plain_table -mmap_read -mmap_write -compression_type=none \ 71 | -key_size=48 -value_size=43 \ 72 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 73 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 74 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 75 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 76 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 77 | -prefix_size=4 \ 78 | -target_file_size_multiplier=10 \ 79 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 80 | -max_background_flushes=$BACKGROUND \ 81 | -max_background_compactions=$BACKGROUND \ 82 | -write_thread_max_yield_usec=100000000 \ 83 | -write_thread_slow_yield_usec=10000000 \ 84 | -write_buffer_size=1073741824 \ 85 | -db=/mnt/data/TriCache/temp/2000M_plain_run -use_existing_db=true \ 86 | 2>&1 | tee results_rocksdb_cache/plain_cache_${MEM_GB}G_${THREADS}.txt 87 | 88 | done 89 | -------------------------------------------------------------------------------- /scripts/run_rocksdb_cache_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | export CACHE_VIRT_SIZE=$(expr 32 \* 1024 \* 1024 \* 1024 \* 1024) 7 | source $TRICACHE_ROOT/scripts/config.sh 8 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 9 | export CACHE_NUM_CLIENTS=1024 10 | 11 | export CACHE_MALLOC_THRESHOLD=$(expr 500 \* 1024 \* 1024) 12 | export CACHE_MMAP_FILE_THRESHOLD=$(expr 16 \* 1024 \* 1024) 13 | 14 | export CACHE_DISABLE_PARALLEL_READ_WRITE=true 15 | 16 | mkdir -p results_small 17 | 18 | sudo mkdir -p /mnt/data/TriCache/temp 19 | 20 | export CACHE_NUM_CLIENTS=1024 21 | export REQUESTS=100000000 22 | export THREADS=940 23 | export BACKGROUND=4 24 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 25 | for MEM_GB in 64 26 | do 27 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 16 \* 6 \) \* 1024 \* 1024 \* 1024) 28 | export MEMORY=$(expr \( $MEM_GB \/ 16 \* 10 \) \* 1024 \* 1024 \* 1024) 29 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 30 | 31 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_plain_4/ /mnt/data/TriCache/temp/2000M_plain_run 32 | 33 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" stdbuf -oL /usr/bin/time -v numactl -i all -C !$CACHE_16_SERVER_CORES \ 34 | $TRICACHE_ROOT/ae-projects/rocksdb/build-cache/db_bench -benchmarks="levelstats,mixgraph,levelstats" -disable_wal \ 35 | -use_plain_table -mmap_read -mmap_write -compression_type=none \ 36 | -key_size=48 -value_size=43 \ 37 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 38 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 39 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 40 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 41 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 42 | -prefix_size=4 \ 43 | -target_file_size_multiplier=10 \ 44 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 45 | -max_background_flushes=$BACKGROUND \ 46 | -max_background_compactions=$BACKGROUND \ 47 | -write_thread_max_yield_usec=100000000 \ 48 | -write_thread_slow_yield_usec=10000000 \ 49 | -write_buffer_size=1073741824 \ 50 | -db=/mnt/data/TriCache/temp/2000M_plain_run -use_existing_db=true \ 51 | 2>&1 | tee results_small/rocksdb_plain_cache.txt 52 | 53 | done 54 | -------------------------------------------------------------------------------- /scripts/run_rocksdb_mmap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export THREADS=256 6 | export BACKGROUND=4 7 | 8 | export REQUESTS=100000000 9 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 10 | 11 | mkdir -p results_rocksdb_mmap 12 | 13 | for MEM_GB in 256 14 | do 15 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 16 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 17 | 18 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_plain_4/ /mnt/raid/temp/2000M_plain_run 19 | 20 | stdbuf -oL /usr/bin/time -v numactl -i all \ 21 | $TRICACHE_ROOT/ae-projects/rocksdb/build-orig/db_bench -benchmarks="levelstats,readrandom,mixgraph,levelstats" -disable_wal \ 22 | -use_plain_table -mmap_read -mmap_write -compression_type=none \ 23 | -key_size=48 -value_size=43 \ 24 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 25 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 26 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 27 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 28 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 29 | -prefix_size=4 \ 30 | -target_file_size_multiplier=10 \ 31 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 32 | -max_background_flushes=$BACKGROUND \ 33 | -max_background_compactions=$BACKGROUND \ 34 | -write_thread_max_yield_usec=100000000 \ 35 | -write_thread_slow_yield_usec=10000000 \ 36 | -write_buffer_size=1073741824 \ 37 | -db=/mnt/raid/temp/2000M_plain_run -use_existing_db=true \ 38 | 2>&1 | tee results_rocksdb_mmap/plain_mmap_${MEM_GB}G_${THREADS}.txt 39 | 40 | done 41 | 42 | export REQUESTS=1000000 43 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 44 | 45 | for MEM_GB in 128 64 32 16 46 | do 47 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 48 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 49 | 50 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_plain_4/ /mnt/raid/temp/2000M_plain_run 51 | 52 | stdbuf -oL /usr/bin/time -v numactl -i all \ 53 | $TRICACHE_ROOT/ae-projects/rocksdb/build-orig/db_bench -benchmarks="levelstats,mixgraph,levelstats" -disable_wal \ 54 | -use_plain_table -mmap_read -mmap_write -compression_type=none \ 55 | -key_size=48 -value_size=43 \ 56 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 57 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 58 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 59 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 60 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 61 | -prefix_size=4 \ 62 | -target_file_size_multiplier=10 \ 63 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 64 | -max_background_flushes=$BACKGROUND \ 65 | -max_background_compactions=$BACKGROUND \ 66 | -write_thread_max_yield_usec=100000000 \ 67 | -write_thread_slow_yield_usec=10000000 \ 68 | -write_buffer_size=1073741824 \ 69 | -db=/mnt/raid/temp/2000M_plain_run -use_existing_db=true \ 70 | 2>&1 | tee results_rocksdb_mmap/plain_mmap_${MEM_GB}G_${THREADS}.txt 71 | 72 | done 73 | -------------------------------------------------------------------------------- /scripts/run_rocksdb_mmap_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export THREADS=256 6 | export BACKGROUND=4 7 | 8 | export REQUESTS=100000000 9 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 10 | 11 | mkdir -p results_small 12 | 13 | export REQUESTS=1000000 14 | export REQUESTS_PER_THREAD=$(expr $REQUESTS \/ \( $THREADS - 2 \* $BACKGROUND \)) 15 | 16 | for MEM_GB in 64 17 | do 18 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 19 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 20 | 21 | sudo rsync -avhP --delete /mnt/data/TriCache/rocksdb/2000M_plain_4/ /mnt/raid/temp/2000M_plain_run 22 | 23 | stdbuf -oL /usr/bin/time -v numactl -i all \ 24 | $TRICACHE_ROOT/ae-projects/rocksdb/build-orig/db_bench -benchmarks="levelstats,mixgraph,levelstats" -disable_wal \ 25 | -use_plain_table -mmap_read -mmap_write -compression_type=none \ 26 | -key_size=48 -value_size=43 \ 27 | -keyrange_dist_a=14.18 -keyrange_dist_b=-2.917 -keyrange_dist_c=0.0164 -keyrange_dist_d=-0.08082 -keyrange_num=30 \ 28 | -value_k=0.2615 -value_sigma=25.45 -iter_k=2.517 -iter_sigma=14.236 \ 29 | -mix_get_ratio=0.83 -mix_put_ratio=0.14 -mix_seek_ratio=0.03 \ 30 | -sine_mix_rate_interval_milliseconds=5000 -sine_a=1000 -sine_b=0.000073 -sine_d=45000 \ 31 | -num=2000000000 -reads=$REQUESTS_PER_THREAD \ 32 | -prefix_size=4 \ 33 | -target_file_size_multiplier=10 \ 34 | -threads=$(expr $THREADS - 2 \* $BACKGROUND) \ 35 | -max_background_flushes=$BACKGROUND \ 36 | -max_background_compactions=$BACKGROUND \ 37 | -write_thread_max_yield_usec=100000000 \ 38 | -write_thread_slow_yield_usec=10000000 \ 39 | -write_buffer_size=1073741824 \ 40 | -db=/mnt/raid/temp/2000M_plain_run -use_existing_db=true \ 41 | 2>&1 | tee results_small/rocksdb_plain_mmap.txt 42 | 43 | done 44 | -------------------------------------------------------------------------------- /scripts/run_terasort.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | function run_terasort_cache 3 | { 4 | $TRICACHE_ROOT/scripts/setup_spdk.sh 362 5 | $TRICACHE_ROOT/scripts/run_terasort_cache.sh 6 | $TRICACHE_ROOT/scripts/reset_spdk.sh 7 | } 8 | 9 | function run_terasort_swap 10 | { 11 | $TRICACHE_ROOT/scripts/mkswap.sh 12 | $TRICACHE_ROOT/scripts/run_terasort_swap.sh 13 | $TRICACHE_ROOT/scripts/rmswap.sh 14 | } 15 | 16 | function run_terasort_swap_slow 17 | { 18 | $TRICACHE_ROOT/scripts/mkswap.sh 19 | $TRICACHE_ROOT/scripts/run_terasort_swap_slow.sh 20 | $TRICACHE_ROOT/scripts/rmswap.sh 21 | } 22 | 23 | function run_terasort_spark 24 | { 25 | $TRICACHE_ROOT/scripts/build_terasort_spark.sh 26 | $TRICACHE_ROOT/scripts/mkxfs.sh 27 | $TRICACHE_ROOT/scripts/run_terasort_spark.sh 28 | sleep 60 29 | $TRICACHE_ROOT/scripts/rmxfs.sh 30 | } 31 | 32 | case $1 in 33 | terasort_cache) 34 | run_terasort_cache 35 | ;; 36 | 37 | terasort_swap) 38 | run_terasort_swap 39 | ;; 40 | 41 | terasort_swap_slow) 42 | run_terasort_swap_slow 43 | ;; 44 | 45 | terasort_spark) 46 | run_terasort_spark 47 | ;; 48 | 49 | *) 50 | run_terasort_cache 51 | run_terasort_swap 52 | run_terasort_spark 53 | ;; 54 | esac 55 | -------------------------------------------------------------------------------- /scripts/run_terasort_breakdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | export CACHE_VIRT_SIZE=$(expr 32 \* 1024 \* 1024 \* 1024 \* 1024) 7 | 8 | export CACHE_DISABLE_PARALLEL_READ_WRITE=true 9 | 10 | source $TRICACHE_ROOT/scripts/config.sh 11 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 12 | 13 | mkdir -p results_breakdown 14 | 15 | export CACHE_MALLOC_THRESHOLD=$(expr 32 \* 1024 \* 1024 \* 1024) 16 | 17 | for THREADS in 240 18 | do 19 | export CACHE_NUM_CLIENTS=$(expr $THREADS \+ 16 \* 4) 20 | export OMP_NUM_THREADS=$THREADS 21 | 22 | for MEM_GB in 64 23 | do 24 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 8 \* 5 \) \* 1024 \* 1024 \* 1024) 25 | export MEMORY=$(expr \( $MEM_GB \/ 8 \* 3 \) \* 1024 \* 1024 \* 1024) 26 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 27 | 28 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 29 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_manual /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 30 | 2>&1 | tee results_breakdown/terasort_manual.txt 31 | 32 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 33 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_manual_profile /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 34 | 2>&1 | tee results_breakdown/terasort_manual_profile.txt 35 | 36 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 37 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_manual_disable_direct /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 38 | 2>&1 | tee results_breakdown/terasort_manual_disable_direct.txt 39 | 40 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 41 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_manual_disable_private /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 42 | 2>&1 | tee results_breakdown/terasort_manual_disable_private.txt 43 | 44 | done 45 | done 46 | 47 | export CACHE_MALLOC_THRESHOLD=$(expr 128 \* 1024 \* 1024) 48 | 49 | for THREADS in 960 50 | do 51 | export CACHE_NUM_CLIENTS=$(expr $THREADS \+ 16 \* 4) 52 | export OMP_NUM_THREADS=$THREADS 53 | 54 | for MEM_GB in 64 55 | do 56 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 8 \* 5 \) \* 1024 \* 1024 \* 1024) 57 | export MEMORY=$(expr \( $MEM_GB \/ 8 \* 3 \) \* 1024 \* 1024 \* 1024) 58 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 59 | 60 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 61 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_gnu /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 62 | 2>&1 | tee results_breakdown/terasort_gnu.txt 63 | 64 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 65 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_gnu_profile /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 66 | 2>&1 | tee results_breakdown/terasort_gnu_profile.txt 67 | 68 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 69 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_gnu_disable_direct /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 70 | 2>&1 | tee results_breakdown/terasort_gnu_disable_direct.txt 71 | 72 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 73 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_gnu_disable_private /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 74 | 2>&1 | tee results_breakdown/terasort_gnu_disable_private.txt 75 | done 76 | done 77 | 78 | export CACHE_MALLOC_THRESHOLD=$(expr 32 \* 1024 \* 1024 \* 1024) 79 | 80 | for THREADS in 240 81 | do 82 | export CACHE_NUM_CLIENTS=$(expr $THREADS \+ 16 \* 4) 83 | export OMP_NUM_THREADS=$THREADS 84 | 85 | for MEM_GB in 64 86 | do 87 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 8 \* 5 \) \* 1024 \* 1024 \* 1024) 88 | export MEMORY=$(expr \( $MEM_GB \/ 8 \* 3 \) \* 1024 \* 1024 \* 1024) 89 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 90 | 91 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 92 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_manual_disable_direct_private /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 93 | 2>&1 | tee results_breakdown/terasort_manual_disable_direct_private.txt 94 | 95 | done 96 | done 97 | 98 | exit 99 | 100 | export CACHE_MALLOC_THRESHOLD=$(expr 128 \* 1024 \* 1024) 101 | 102 | for THREADS in 960 103 | do 104 | export CACHE_NUM_CLIENTS=$(expr $THREADS \+ 16 \* 4) 105 | export OMP_NUM_THREADS=$THREADS 106 | 107 | for MEM_GB in 64 108 | do 109 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 8 \* 5 \) \* 1024 \* 1024 \* 1024) 110 | export MEMORY=$(expr \( $MEM_GB \/ 8 \* 3 \) \* 1024 \* 1024 \* 1024) 111 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 112 | 113 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 114 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_gnu_disable_direct_private /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 115 | 2>&1 | tee results_breakdown/terasort_gnu_disable_direct_private.txt 116 | done 117 | done 118 | -------------------------------------------------------------------------------- /scripts/run_terasort_cache_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | export CACHE_VIRT_SIZE=$(expr 32 \* 1024 \* 1024 \* 1024 \* 1024) 7 | 8 | export CACHE_MALLOC_THRESHOLD=$(expr 32 \* 1024 \* 1024 \* 1024) 9 | 10 | export CACHE_DISABLE_PARALLEL_READ_WRITE=true 11 | 12 | source $TRICACHE_ROOT/scripts/config.sh 13 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 14 | 15 | mkdir -p results_small 16 | 17 | for THREADS in 240 18 | do 19 | export CACHE_NUM_CLIENTS=$(expr $THREADS \+ 16 \* 4) 20 | export OMP_NUM_THREADS=$THREADS 21 | 22 | for MEM_GB in 64 23 | do 24 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 8 \* 5 \) \* 1024 \* 1024 \* 1024) 25 | export MEMORY=$(expr \( $MEM_GB \/ 8 \* 3 \) \* 1024 \* 1024 \* 1024) 26 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 27 | 28 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 29 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_manual /mnt/data/TriCache/terasort/terasort-150G $THREADS \ 30 | 2>&1 | tee results_small/terasort_manual_cache.txt 31 | done 32 | done 33 | 34 | export CACHE_MALLOC_THRESHOLD=$(expr 128 \* 1024 \* 1024) 35 | 36 | for THREADS in 480 37 | do 38 | export CACHE_NUM_CLIENTS=$(expr $THREADS \+ 16 \* 4) 39 | export OMP_NUM_THREADS=$THREADS 40 | 41 | for MEM_GB in 64 42 | do 43 | export CACHE_PHY_SIZE=$(expr \( $MEM_GB \/ 8 \* 6 \) \* 1024 \* 1024 \* 1024) 44 | export MEMORY=$(expr \( $MEM_GB \/ 8 \* 2 \) \* 1024 \* 1024 \* 1024) 45 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 46 | 47 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 48 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/terasort_gnu /mnt/data/TriCache/terasort/terasort-150G $THREADS \ 49 | 2>&1 | tee results_small/terasort_gnu_cache.txt 50 | done 51 | done 52 | -------------------------------------------------------------------------------- /scripts/run_terasort_spark_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | 4 | trap "kill 0" SIGINT 5 | (while true; do pgrep java | xargs -I {} sudo bash -c "echo {} > /sys/fs/cgroup/limit/cgroup.procs 2>/dev/null"; sleep 0.1; done) & 6 | echo max | sudo tee /sys/fs/cgroup/limit/memory.max 7 | 8 | mkdir -p results_small 9 | 10 | sudo rsync -avhP /mnt/data/TriCache/terasort/terasort-150G /mnt/ssd0/shm 11 | sudo rsync -avhP /mnt/data/TriCache/terasort/terasort-400G /mnt/ssd0/shm 12 | 13 | function start_spark 14 | { 15 | pushd $TRICACHE_ROOT/ae-projects/terasort_spark/spark-confs 16 | ln -sf spark-env-$1.sh spark-env.sh 17 | popd 18 | $TRICACHE_ROOT/ae-projects/terasort_spark/spark-3.2.0-bin-hadoop3.2/sbin/stop-all.sh 19 | sleep 5 20 | killall -q -9 java 21 | $TRICACHE_ROOT/ae-projects/terasort_spark/spark-3.2.0-bin-hadoop3.2/sbin/start-master.sh -h localhost 22 | $TRICACHE_ROOT/ae-projects/terasort_spark/spark-3.2.0-bin-hadoop3.2/sbin/start-slaves.sh 23 | } 24 | 25 | function stop_spark 26 | { 27 | $TRICACHE_ROOT/ae-projects/terasort_spark/spark-3.2.0-bin-hadoop3.2/sbin/stop-all.sh 28 | } 29 | 30 | echo 64G | sudo tee /sys/fs/cgroup/limit/memory.max 31 | start_spark 8 32 | stdbuf -oL $TRICACHE_ROOT/ae-projects/terasort_spark/spark-3.2.0-bin-hadoop3.2/bin/spark-submit --master spark://localhost:7077 --class com.github.ehiggs.spark.terasort.TeraSortComp --executor-memory 4G --driver-memory 16G $TRICACHE_ROOT/ae-projects/terasort_spark/spark-terasort/target/spark-terasort-1.2-SNAPSHOT-jar-with-dependencies.jar /mnt/ssd0/shm/terasort-150G /mnt/ssd0/shm/terasort-150G-out 4096 4096 1 2>&1 | tee results_small/terasort_spark.txt 33 | 34 | stop_spark 35 | 36 | kill -9 $(jobs -p) 37 | -------------------------------------------------------------------------------- /scripts/run_terasort_swap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | 7 | mkdir -p results_terasort_swap 8 | 9 | for THREADS in 256 10 | do 11 | export OMP_NUM_THREADS=$THREADS 12 | 13 | for MEM_GB in 512 256 128 64 32 16 14 | do 15 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 16 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 17 | 18 | stdbuf -oL /usr/bin/time -v numactl -i all \ 19 | $TRICACHE_ROOT/build/terasort_gnu_orig /mnt/data/TriCache/terasort/terasort-150G $THREADS \ 20 | 2>&1 | tee results_terasort_swap/terasort_gnu_150G_${MEM_GB}G_${THREADS}.txt 21 | 22 | stdbuf -oL /usr/bin/time -v numactl -i all \ 23 | $TRICACHE_ROOT/build/terasort_manual_orig /mnt/data/TriCache/terasort/terasort-150G $THREADS \ 24 | 2>&1 | tee results_terasort_swap/terasort_manual_150G_${MEM_GB}G_${THREADS}.txt 25 | done 26 | done 27 | 28 | exit 29 | 30 | for THREADS in 256 31 | do 32 | export OMP_NUM_THREADS=$THREADS 33 | 34 | for MEM_GB in 512 256 128 64 32 16 35 | do 36 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 37 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 38 | 39 | stdbuf -oL /usr/bin/time -v numactl -i all \ 40 | $TRICACHE_ROOT/build/terasort_manual_orig /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 41 | 2>&1 | tee results_terasort_swap/terasort_manual_400G_${MEM_GB}G_${THREADS}.txt 42 | done 43 | done 44 | 45 | for THREADS in 256 46 | do 47 | export OMP_NUM_THREADS=$THREADS 48 | 49 | for MEM_GB in 512 256 128 64 32 16 50 | do 51 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 52 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 53 | 54 | stdbuf -oL /usr/bin/time -v numactl -i all \ 55 | $TRICACHE_ROOT/build/terasort_gnu_orig /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 56 | 2>&1 | tee results_terasort_swap/terasort_gnu_400G_${MEM_GB}G_${THREADS}.txt 57 | done 58 | done 59 | -------------------------------------------------------------------------------- /scripts/run_terasort_swap_slow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | 7 | mkdir -p results_terasort_swap 8 | 9 | for THREADS in 256 10 | do 11 | export OMP_NUM_THREADS=$THREADS 12 | 13 | for MEM_GB in 512 256 128 64 32 16 14 | do 15 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 16 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 17 | 18 | stdbuf -oL /usr/bin/time -v numactl -i all \ 19 | $TRICACHE_ROOT/build/terasort_manual_orig /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 20 | 2>&1 | tee results_terasort_swap/terasort_manual_400G_${MEM_GB}G_${THREADS}.txt 21 | done 22 | done 23 | 24 | for THREADS in 256 25 | do 26 | export OMP_NUM_THREADS=$THREADS 27 | 28 | for MEM_GB in 512 256 128 64 32 16 29 | do 30 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 31 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 32 | 33 | stdbuf -oL /usr/bin/time -v numactl -i all \ 34 | $TRICACHE_ROOT/build/terasort_gnu_orig /mnt/data/TriCache/terasort/terasort-400G $THREADS \ 35 | 2>&1 | tee results_terasort_swap/terasort_gnu_400G_${MEM_GB}G_${THREADS}.txt 36 | done 37 | done 38 | -------------------------------------------------------------------------------- /scripts/run_terasort_swap_small.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | $TRICACHE_ROOT/scripts/cgroups.sh 3 | echo $$ | sudo tee /sys/fs/cgroup/limit/cgroup.procs 4 | 5 | export OMP_PROC_BIND=true 6 | 7 | mkdir -p results_small 8 | 9 | for THREADS in 256 10 | do 11 | export OMP_NUM_THREADS=$THREADS 12 | 13 | for MEM_GB in 64 14 | do 15 | export MEMORY=$(expr $MEM_GB \* 1024 \* 1024 \* 1024) 16 | echo $MEMORY | sudo tee /sys/fs/cgroup/limit/memory.max 17 | 18 | stdbuf -oL /usr/bin/time -v numactl -i all \ 19 | $TRICACHE_ROOT/build/terasort_gnu_orig /mnt/data/TriCache/terasort/terasort-150G $THREADS \ 20 | 2>&1 | tee results_small/terasort_gnu_swap.txt 21 | 22 | stdbuf -oL /usr/bin/time -v numactl -i all \ 23 | $TRICACHE_ROOT/build/terasort_manual_orig /mnt/data/TriCache/terasort/terasort-150G $THREADS \ 24 | 2>&1 | tee results_small/terasort_manual_swap.txt 25 | done 26 | done 27 | -------------------------------------------------------------------------------- /scripts/setup_spdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $TRICACHE_ROOT/scripts/config.sh 3 | sudo PCI_ALLOWED="$SSDPCIe" HUGEMEM=$(expr $1 \* 1024) HUGE_EVEN_ALLOC=yes CLEAR_HUGE=yes $SPDK_ROOT/scripts/setup.sh 4 | echo 1048576 | sudo tee /sys/module/vfio_iommu_type1/parameters/dma_entry_limit > /dev/null 5 | -------------------------------------------------------------------------------- /scripts/test_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export CACHE_VIRT_SIZE=$(expr 4 \* 1024 \* 1024 \* 1024) 3 | export CACHE_PHY_SIZE=$(expr 1 \* 1024 \* 1024 \* 1024) 4 | export CACHE_MALLOC_THRESHOLD=$(expr 16 \* 1024 \* 1024) 5 | export CACHE_NUM_CLIENTS=1 6 | 7 | source $TRICACHE_ROOT/scripts/config.sh 8 | export CACHE_CONFIG=$CACHE_16_SERVER_CONFIG 9 | 10 | sudo -E LD_LIBRARY_PATH="$LD_LIBRARY_PATH" numactl -i all -C !$CACHE_16_SERVER_CORES \ 11 | stdbuf -oL /usr/bin/time -v $TRICACHE_ROOT/build/test_instrument_mmap 12 | --------------------------------------------------------------------------------