├── .clang-format
├── .github
└── workflows
│ ├── cicada_build.yml
│ ├── ermia_build.yml
│ ├── mocc_build.yml
│ ├── si_build.yml
│ ├── silo_build.yml
│ ├── ss2pl_build.yml
│ ├── tictoc_build.yml
│ └── tpcc_silo_build_and_ctest.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── build_tools
├── bootstrap.sh
├── bootstrap_apt.sh
├── bootstrap_googletest.sh
├── bootstrap_mimalloc.sh
├── bootstrap_tbb.sh
└── ubuntu.deps
├── cc_format
├── Makefile
├── README.md
├── include
│ ├── atomic_tool.hh
│ ├── common.hh
│ ├── log.hh
│ ├── result.hh
│ ├── silo_op_element.hh
│ ├── transaction.hh
│ ├── tuple.hh
│ └── util.hh
├── result.cc
├── sv_format.cc
├── transaction.cc
└── util.cc
├── cicada
├── CMakeLists.txt
├── README.md
├── cicada.cc
├── include
│ ├── cicada_op_element.hh
│ ├── common.hh
│ ├── lock.hh
│ ├── result.hh
│ ├── time_stamp.hh
│ ├── transaction.hh
│ ├── tuple.hh
│ ├── util.hh
│ └── version.hh
├── result.cc
├── script
│ ├── test_cache_ana.sh
│ ├── test_t1k.sh
│ ├── test_t1m.sh
│ ├── test_t200.sh
│ ├── test_wal.sh
│ ├── test_wal4pair.sh
│ ├── tst200-1k-1m.sh
│ ├── ycsb-xgci.sh
│ ├── ycsb-xope.sh
│ ├── ycsb-xrratio.sh
│ ├── ycsb-xrs.sh
│ ├── ycsb-xskew.sh
│ ├── ycsb-xth.sh
│ ├── ycsb-xval.sh
│ ├── ycsbA-xgcidbsize-cache.sh
│ ├── ycsbA-xrs-cache.sh
│ ├── ycsbA.sh
│ ├── ycsbB.sh
│ └── ycsbC.sh
├── testzip.cc
├── transaction.cc
└── util.cc
├── cmake
├── CompileOptions.cmake
├── Findgflags.cmake
└── Findglog.cmake
├── common
├── Makefile
├── result.cc
└── util.cc
├── ermia
├── CMakeLists.txt
├── README.md
├── ermia.cc
├── garbage_collection.cc
├── include
│ ├── common.hh
│ ├── ermia_op_element.hh
│ ├── garbage_collection.hh
│ ├── lock.hh
│ ├── result.hh
│ ├── transaction.hh
│ ├── transaction_status.hh
│ ├── transaction_table.hh
│ ├── tuple.hh
│ ├── util.hh
│ └── version.hh
├── result.cc
├── script
│ ├── test_cache_ana.sh
│ ├── test_t1k.sh
│ ├── test_t1m.sh
│ ├── test_t200.sh
│ ├── tst200-1k-1m.sh
│ ├── ycsb-xope.sh
│ ├── ycsb-xrratio.sh
│ ├── ycsb-xrs.sh
│ ├── ycsb-xskew.sh
│ ├── ycsb-xth.sh
│ ├── ycsb-xval.sh
│ ├── ycsbA-xgcidbsize-cache.sh
│ ├── ycsbA-xgcidbsize.sh
│ ├── ycsbA-xrs-cache.sh
│ ├── ycsbA.sh
│ ├── ycsbB.sh
│ └── ycsbC.sh
├── transaction.cc
└── util.cc
├── include
├── Makefile
├── atomic_wrapper.hh
├── backoff.hh
├── cache_line_size.hh
├── check.hh
├── compiler.hh
├── config.hh
├── cpu.hh
├── debug.hh
├── delay.hh
├── fence.hh
├── fileio.hh
├── inline.hh
├── int64byte.hh
├── logger.h
├── masstree_wrapper.hh
├── op_element.hh
├── procedure.hh
├── random.hh
├── result.hh
├── rwlock.hh
├── string.hh
├── tsc.hh
├── util.hh
└── zipf.hh
├── instruction
├── Makefile
├── README.md
├── cache-test.cc
├── fetch_add.cc
├── include
│ └── common.hh
├── masstree_simple_test
│ ├── GNUmakefile
│ ├── script
│ │ ├── test.sh
│ │ └── xrs.sh
│ ├── unit-mt.cc
│ └── unit-mt2.cc
├── mcslock_with_timeout.c
├── membench.cc
├── pow_test.cc
├── rdtscBench.cc
├── script
│ ├── fetch_add.sh
│ └── membench.sh
├── test_fetch_add.sh
├── test_xoroshiro.sh
├── xoroshiro.cc
└── zipf_dist_test.cc
├── mocc
├── CMakeLists.txt
├── README.md
├── include
│ ├── atomic_tool.hh
│ ├── common.hh
│ ├── lock.hh
│ ├── mocc_op_element.hh
│ ├── result.hh
│ ├── transaction.hh
│ ├── tuple.hh
│ └── util.hh
├── lock.cc
├── mocc.cc
├── pseudo_mql.txt
├── result.cc
├── script
│ ├── test_cache_ana.sh
│ ├── test_t1k.sh
│ ├── test_t1m.sh
│ ├── test_t200.sh
│ ├── tst200-1k-1m.sh
│ ├── ycsb-xope.sh
│ ├── ycsb-xrratio.sh
│ ├── ycsb-xrs.sh
│ ├── ycsb-xskew.sh
│ ├── ycsb-xth.sh
│ ├── ycsb-xval.sh
│ ├── ycsbA-xrs-cache.sh
│ ├── ycsbA.sh
│ ├── ycsbB.sh
│ └── ycsbC.sh
├── transaction.cc
└── util.cc
├── occ
├── Makefile
├── README.md
├── include
│ ├── atomic_tool.hh
│ ├── common.hh
│ ├── log.hh
│ ├── occ_op_element.hh
│ ├── result.hh
│ ├── transaction.hh
│ ├── tuple.hh
│ └── util.hh
├── occ.cc
├── result.cc
├── transaction.cc
└── util.cc
├── si
├── CMakeLists.txt
├── README.md
├── garbage_collection.cc
├── include
│ ├── common.hh
│ ├── garbage_collection.hh
│ ├── result.hh
│ ├── si_op_element.hh
│ ├── transaction.hh
│ ├── transaction_table.hh
│ ├── tuple.hh
│ ├── util.hh
│ └── version.hh
├── result.cc
├── script
│ ├── tst200-1k-1m.sh
│ ├── ycsb-xope.sh
│ ├── ycsb-xrratio.sh
│ ├── ycsb-xrs.sh
│ ├── ycsb-xskew.sh
│ ├── ycsb-xth.sh
│ ├── ycsb-xval.sh
│ ├── ycsbA-xrs-cache.sh
│ ├── ycsbA.sh
│ ├── ycsbB.sh
│ └── ycsbC.sh
├── si.cc
├── transaction.cc
└── util.cc
├── silo
├── CMakeLists.txt
├── README.md
├── include
│ ├── atomic_tool.hh
│ ├── common.hh
│ ├── log.hh
│ ├── result.hh
│ ├── silo_op_element.hh
│ ├── transaction.hh
│ ├── tuple.hh
│ └── util.hh
├── replayTest.cc
├── result.cc
├── script
│ ├── test_cache_ana.sh
│ ├── test_t1k.sh
│ ├── test_t1m.sh
│ ├── test_t200.sh
│ ├── tst200-1k-1m.sh
│ ├── ycsb-xgci.sh
│ ├── ycsb-xope.sh
│ ├── ycsb-xrratio.sh
│ ├── ycsb-xrs.sh
│ ├── ycsb-xskew.sh
│ ├── ycsb-xslprp.sh
│ ├── ycsb-xth.sh
│ ├── ycsb-xval.sh
│ ├── ycsbA-xrs-cache.sh
│ ├── ycsbA.sh
│ ├── ycsbB.sh
│ └── ycsbC.sh
├── silo.cc
├── transaction.cc
└── util.cc
├── ss2pl
├── CMakeLists.txt
├── README.md
├── include
│ ├── common.hh
│ ├── result.hh
│ ├── ss2pl_op_element.hh
│ ├── transaction.hh
│ ├── tuple.hh
│ └── util.hh
├── result.cc
├── script
│ ├── test_cache_ana.sh
│ ├── test_t1k.sh
│ ├── test_t1m.sh
│ ├── test_t200.sh
│ ├── tst200-1k-1m.sh
│ ├── ycsb-xope.sh
│ ├── ycsb-xrratio.sh
│ ├── ycsb-xrs.sh
│ ├── ycsb-xskew.sh
│ ├── ycsb-xth.sh
│ ├── ycsb-xval.sh
│ ├── ycsbA-xrs-cache.sh
│ ├── ycsbA.sh
│ ├── ycsbB.sh
│ └── ycsbC.sh
├── ss2pl.cc
├── test
│ ├── CMakeLists.txt
│ └── make_db_test.cpp
├── transaction.cc
└── util.cc
├── tictoc
├── CMakeLists.txt
├── README.md
├── include
│ ├── common.hh
│ ├── result.hh
│ ├── tictoc_op_element.hh
│ ├── transaction.hh
│ ├── tuple.hh
│ └── util.hh
├── result.cc
├── script
│ ├── test_cache_ana.sh
│ ├── test_t1k.sh
│ ├── test_t1m.sh
│ ├── test_t200.sh
│ ├── tst200-1k-1m.sh
│ ├── ycsb-xope.sh
│ ├── ycsb-xrratio.sh
│ ├── ycsb-xrs.sh
│ ├── ycsb-xskew.sh
│ ├── ycsb-xslprp.sh
│ ├── ycsb-xth.sh
│ ├── ycsb-xval.sh
│ ├── ycsbA-xrs-cache.sh
│ ├── ycsbA.sh
│ ├── ycsbB.sh
│ └── ycsbC.sh
├── tictoc.cc
├── transaction.cc
└── util.cc
└── tpcc_silo
├── CMakeLists.txt
├── README.md
├── build_script.sh
├── epoch.cpp
├── garbage_collection.cpp
├── include
├── aligned_allocator.h
├── atomic_tool.hh
├── atomic_wrapper.h
├── clock.h
├── common.hh
├── compiler.h
├── cpu.h
├── epoch.h
├── error.h
├── fence.h
├── fileio.h
├── garbage_collection.h
├── heap_object.hpp
├── inline.h
├── log.h
├── memory.h
├── record.h
├── result.hh
├── scheme.h
├── scheme_global.h
├── session_info.h
├── session_info_table.h
├── tid.h
├── tsc.h
├── tuple.h
└── util.hh
├── index
└── masstree_beta
│ ├── include
│ └── masstree_beta_wrapper.h
│ └── masstree_beta_wrapper.cpp
├── interface
├── interface.h
├── interface_delete.cpp
├── interface_helper.cpp
├── interface_helper.h
├── interface_scan.cpp
├── interface_search.cpp
├── interface_termination.cpp
└── interface_update_insert.cpp
├── log.cpp
├── result.cpp
├── scheme.cpp
├── session_info.cpp
├── session_info_table.cpp
├── silo.cpp
├── test
├── CMakeLists.txt
├── aligned_allocator_test.cpp
├── scheme_global_test.cpp
├── tpcc_initializer_test.cpp
├── tpcc_tables_test.cpp
├── tpcc_util_test.cpp
└── unit_test.cpp
├── tid.cpp
├── tpcc
├── neworder.cpp
├── payment.cpp
├── tpcc_initializer.hpp
├── tpcc_query.cpp
├── tpcc_query.hpp
├── tpcc_tables.hpp
├── tpcc_txn.hpp
└── tpcc_util.hpp
└── util.cpp
/.clang-format:
--------------------------------------------------------------------------------
1 | # Generated from CLion C/C++ Code Style settings
2 | BasedOnStyle: LLVM
3 | AccessModifierOffset: -4
4 | AlignAfterOpenBracket: Align
5 | AlignConsecutiveAssignments: false
6 | AlignOperands: true
7 | AllowAllArgumentsOnNextLine: false
8 | AllowAllConstructorInitializersOnNextLine: false
9 | AllowAllParametersOfDeclarationOnNextLine: false
10 | AllowShortBlocksOnASingleLine: Always
11 | AllowShortCaseLabelsOnASingleLine: false
12 | AllowShortFunctionsOnASingleLine: All
13 | AllowShortIfStatementsOnASingleLine: Always
14 | AllowShortLambdasOnASingleLine: All
15 | AllowShortLoopsOnASingleLine: true
16 | AlwaysBreakAfterReturnType: None
17 | AlwaysBreakTemplateDeclarations: Yes
18 | BreakBeforeBraces: Custom
19 | BraceWrapping:
20 | AfterCaseLabel: false
21 | AfterClass: false
22 | AfterControlStatement: Never
23 | AfterEnum: false
24 | AfterFunction: false
25 | AfterNamespace: false
26 | AfterUnion: false
27 | BeforeCatch: false
28 | BeforeElse: false
29 | IndentBraces: false
30 | SplitEmptyFunction: false
31 | SplitEmptyRecord: true
32 | BreakBeforeBinaryOperators: None
33 | BreakBeforeTernaryOperators: true
34 | BreakConstructorInitializers: BeforeColon
35 | BreakInheritanceList: BeforeColon
36 | ColumnLimit: 80
37 | CompactNamespaces: false
38 | ContinuationIndentWidth: 8
39 | IndentCaseLabels: true
40 | IndentPPDirectives: None
41 | IndentWidth: 4
42 | KeepEmptyLinesAtTheStartOfBlocks: true
43 | MaxEmptyLinesToKeep: 2
44 | NamespaceIndentation: None
45 | ObjCSpaceAfterProperty: false
46 | ObjCSpaceBeforeProtocolList: true
47 | PointerAlignment: Left
48 | ReflowComments: false
49 | SpaceAfterCStyleCast: true
50 | SpaceAfterLogicalNot: false
51 | SpaceAfterTemplateKeyword: false
52 | SpaceBeforeAssignmentOperators: true
53 | SpaceBeforeCpp11BracedList: false
54 | SpaceBeforeCtorInitializerColon: true
55 | SpaceBeforeInheritanceColon: true
56 | SpaceBeforeParens: ControlStatements
57 | SpaceBeforeRangeBasedForLoopColon: true
58 | SpaceInEmptyParentheses: false
59 | SpacesBeforeTrailingComments: 1
60 | SpacesInAngles: false
61 | SpacesInCStyleCastParentheses: false
62 | SpacesInContainerLiterals: false
63 | SpacesInParentheses: false
64 | SpacesInSquareBrackets: false
65 | TabWidth: 4
66 | UseTab: Never
67 |
--------------------------------------------------------------------------------
/.github/workflows/cicada_build.yml:
--------------------------------------------------------------------------------
1 | name: cicada_build
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/cicada_build.yml'
7 | - 'cicada/**'
8 | - 'common/**'
9 | - 'include/**'
10 | - 'third_party/**'
11 | pull_request:
12 | paths:
13 | - '.github/workflows/cicada_build.yml'
14 | - 'cicada/**'
15 | - 'common/**'
16 | - 'include/**'
17 |
18 | jobs:
19 | Build:
20 | runs-on: ubuntu-latest
21 | timeout-minutes: 10
22 |
23 | steps:
24 | - id: Begin
25 | name: Begin
26 | run: |
27 | echo "Begin ${GITHUB_WORKFLOW}/${GITHUB_JOB}"
28 |
29 | - id: Checkout
30 | name: Checkout
31 | uses: actions/checkout@v2
32 |
33 | - id: Install_apt
34 | name: Install_apt
35 | run: |
36 | sudo apt update -y
37 | sudo apt-get install -y $(cat build_tools/ubuntu.deps)
38 |
39 | - id: Submodule_init_recursive
40 | name: Submodule_init_recursive
41 | run: |
42 | git submodule update --init --recursive
43 |
44 | - id: Build_third_party_masstree
45 | name: Build_third_party_masstree
46 | run: |
47 | ./build_tools/bootstrap.sh
48 |
49 | - id: Build_third_party_mimalloc
50 | name: Build_third_party_mimalloc
51 | run: |
52 | ./build_tools/bootstrap_mimalloc.sh
53 |
54 | - id: Build_third_party_googletest
55 | name: Build_third_party_googletest
56 | run: |
57 | ./build_tools/bootstrap_googletest.sh
58 |
59 | - id: Build_cicada
60 | name: Build_cicada
61 | run: |
62 | cd cicada
63 | mkdir build
64 | cd build
65 | cmake -DCMAKE_BUILD_TYPE=Debug ..
66 | cmake --build . --target all --clean-first -- -j
67 |
--------------------------------------------------------------------------------
/.github/workflows/ermia_build.yml:
--------------------------------------------------------------------------------
1 | name: ermia_build
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/ermia_build.yml'
7 | - 'common/**'
8 | - 'ermia/**'
9 | - 'third_party/**'
10 | pull_request:
11 | paths:
12 | - '.github/workflows/ermia_build.yml'
13 | - 'common/**'
14 | - 'ermia/**'
15 |
16 | jobs:
17 | Build:
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 10
20 |
21 | steps:
22 | - id: Begin
23 | name: Begin
24 | run: |
25 | echo "Begin ${GITHUB_WORKFLOW}/${GITHUB_JOB}"
26 |
27 | - id: Checkout
28 | name: Checkout
29 | uses: actions/checkout@v2
30 |
31 | - id: Install_apt
32 | name: Install_apt
33 | run: |
34 | sudo apt update -y
35 | sudo apt-get install -y $(cat build_tools/ubuntu.deps)
36 |
37 | - id: Submodule_init_recursive
38 | name: Submodule_init_recursive
39 | run: |
40 | git submodule update --init --recursive
41 |
42 | - id: Build_third_party_masstree
43 | name: Build_third_party_masstree
44 | run: |
45 | ./build_tools/bootstrap.sh
46 |
47 | - id: Build_third_party_mimalloc
48 | name: Build_third_party_mimalloc
49 | run: |
50 | ./build_tools/bootstrap_mimalloc.sh
51 |
52 | - id: Build_third_party_googletest
53 | name: Build_third_party_googletest
54 | run: |
55 | ./build_tools/bootstrap_googletest.sh
56 |
57 | - id: Build_ermia
58 | name: Build_ermia
59 | run: |
60 | cd ermia
61 | mkdir -p build
62 | cd build
63 | cmake -DCMAKE_BUILD_TYPE=Debug ..
64 | make -j
65 |
--------------------------------------------------------------------------------
/.github/workflows/mocc_build.yml:
--------------------------------------------------------------------------------
1 | name: mocc_build
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/mocc_build.yml'
7 | - 'common/**'
8 | - 'mocc/**'
9 | - 'third_party/**'
10 | pull_request:
11 | - '.github/workflows/mocc_build.yml'
12 | - 'common/**'
13 | - 'mocc/**'
14 |
15 | jobs:
16 | Build:
17 | runs-on: ubuntu-latest
18 | timeout-minutes: 10
19 |
20 | steps:
21 | - id: Begin
22 | name: Begin
23 | run: |
24 | echo "Begin ${GITHUB_WORKFLOW}/${GITHUB_JOB}"
25 |
26 | - id: Checkout
27 | name: Checkout
28 | uses: actions/checkout@v2
29 |
30 | - id: Install_apt
31 | name: Install_apt
32 | run: |
33 | sudo apt update -y
34 | sudo apt-get install -y $(cat build_tools/ubuntu.deps)
35 |
36 | - id: Submodule_init_recursive
37 | name: Submodule_init_recursive
38 | run: |
39 | git submodule update --init --recursive
40 |
41 | - id: Build_third_party_masstree
42 | name: Build_third_party_masstree
43 | run: |
44 | ./build_tools/bootstrap.sh
45 |
46 | - id: Build_third_party_mimalloc
47 | name: Build_third_party_mimalloc
48 | run: |
49 | ./build_tools/bootstrap_mimalloc.sh
50 |
51 | - id: Build_third_party_googletest
52 | name: Build_third_party_googletest
53 | run: |
54 | ./build_tools/bootstrap_googletest.sh
55 |
56 | - id: Build_mocc
57 | name: Build_mocc
58 | run: |
59 | cd mocc
60 | mkdir -p build
61 | cd build
62 | cmake -DCMAKE_BUILD_TYPE=Debug ..
63 | make -j
64 |
--------------------------------------------------------------------------------
/.github/workflows/si_build.yml:
--------------------------------------------------------------------------------
1 | name: si_build
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/si_build.yml'
7 | - 'common/**'
8 | - 'si/**'
9 | - 'third_party/**'
10 | pull_request:
11 | paths:
12 | - '.github/workflows/si_build.yml'
13 | - 'common/**'
14 | - 'si/**'
15 |
16 | jobs:
17 | Build:
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 10
20 |
21 | steps:
22 | - id: Begin
23 | name: Begin
24 | run: |
25 | echo "Begin ${GITHUB_WORKFLOW}/${GITHUB_JOB}"
26 |
27 | - id: Checkout
28 | name: Checkout
29 | uses: actions/checkout@v2
30 |
31 | - id: Install_apt
32 | name: Install_apt
33 | run: |
34 | sudo apt update -y
35 | sudo apt-get install -y $(cat build_tools/ubuntu.deps)
36 |
37 | - id: Submodule_init_recursive
38 | name: Submodule_init_recursive
39 | run: |
40 | git submodule update --init --recursive
41 |
42 | - id: Build_third_party_masstree
43 | name: Build_third_party_masstree
44 | run: |
45 | ./build_tools/bootstrap.sh
46 |
47 | - id: Build_third_party_mimalloc
48 | name: Build_third_party_mimalloc
49 | run: |
50 | ./build_tools/bootstrap_mimalloc.sh
51 |
52 | - id: Build_third_party_googletest
53 | name: Build_third_party_googletest
54 | run: |
55 | ./build_tools/bootstrap_googletest.sh
56 |
57 | - id: Build_si
58 | name: Build_si
59 | run: |
60 | cd si
61 | mkdir -p build
62 | cd build
63 | cmake -DCMAKE_BUILD_TYPE=Debug ..
64 | make -j
65 |
--------------------------------------------------------------------------------
/.github/workflows/silo_build.yml:
--------------------------------------------------------------------------------
1 | name: silo_build
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/silo_build.yml'
7 | - 'common/**'
8 | - 'silo/**'
9 | - 'third_party/**'
10 | pull_request:
11 | paths:
12 | - '.github/workflows/silo_build.yml'
13 | - 'common/**'
14 | - 'silo/**'
15 |
16 | jobs:
17 | Build:
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 10
20 |
21 | steps:
22 | - id: Begin
23 | name: Begin
24 | run: |
25 | echo "Begin ${GITHUB_WORKFLOW}/${GITHUB_JOB}"
26 |
27 | - id: Checkout
28 | name: Checkout
29 | uses: actions/checkout@v2
30 |
31 | - id: Install_apt
32 | name: Install_apt
33 | run: |
34 | sudo apt update -y
35 | sudo apt-get install -y $(cat build_tools/ubuntu.deps)
36 |
37 | - id: Submodule_init_recursive
38 | name: Submodule_init_recursive
39 | run: |
40 | git submodule update --init --recursive
41 |
42 | - id: Build_third_party_masstree
43 | name: Build_third_party_masstree
44 | run: |
45 | ./build_tools/bootstrap.sh
46 |
47 | - id: Build_third_party_mimalloc
48 | name: Build_third_party_mimalloc
49 | run: |
50 | ./build_tools/bootstrap_mimalloc.sh
51 |
52 | - id: Build_third_party_googletest
53 | name: Build_third_party_googletest
54 | run: |
55 | ./build_tools/bootstrap_googletest.sh
56 |
57 | - id: Build_silo
58 | name: Build_silo
59 | run: |
60 | cd silo
61 | mkdir -p build
62 | cd build
63 | cmake -DCMAKE_BUILD_TYPE=Debug ..
64 | make -j
65 |
--------------------------------------------------------------------------------
/.github/workflows/ss2pl_build.yml:
--------------------------------------------------------------------------------
1 | name: ss2pl_build
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/ss2pl_build.yml'
7 | - 'common/**'
8 | - 'ss2pl/**'
9 | - 'third_party/**'
10 | pull_request:
11 | paths:
12 | - '.github/workflows/ss2pl_build.yml'
13 | - 'common/**'
14 | - 'ss2pl/**'
15 |
16 | jobs:
17 | Build:
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 10
20 |
21 | steps:
22 | - id: Begin
23 | name: Begin
24 | run: |
25 | echo "Begin ${GITHUB_WORKFLOW}/${GITHUB_JOB}"
26 |
27 | - id: Checkout
28 | name: Checkout
29 | uses: actions/checkout@v2
30 |
31 | - id: Install_apt
32 | name: Install_apt
33 | run: |
34 | sudo apt update -y
35 | sudo apt-get install -y $(cat build_tools/ubuntu.deps)
36 |
37 | - id: Submodule_init_recursive
38 | name: Submodule_init_recursive
39 | run: |
40 | git submodule update --init --recursive
41 |
42 | - id: Build_third_party_masstree
43 | name: Build_third_party_masstree
44 | run: |
45 | ./build_tools/bootstrap.sh
46 |
47 | - id: Build_third_party_mimalloc
48 | name: Build_third_party_mimalloc
49 | run: |
50 | ./build_tools/bootstrap_mimalloc.sh
51 |
52 | - id: Build_third_party_googletest
53 | name: Build_third_party_googletest
54 | run: |
55 | ./build_tools/bootstrap_googletest.sh
56 |
57 | - id: Build_ss2pl
58 | name: Build_ss2pl
59 | run: |
60 | cd ss2pl
61 | mkdir -p build
62 | cd build
63 | cmake -DCMAKE_BUILD_TYPE=Debug ..
64 | make -j
65 |
66 | - id: Test_ss2pl
67 | name: Test_ss2pl
68 | run: |
69 | cd ss2pl/build
70 | ctest --verbose --timeout 20 -j 100
--------------------------------------------------------------------------------
/.github/workflows/tictoc_build.yml:
--------------------------------------------------------------------------------
1 | name: tictoc_build
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/tictoc_build.yml'
7 | - 'common/**'
8 | - 'tictoc/**'
9 | - 'third_party/**'
10 | pull_request:
11 | paths:
12 | - '.github/workflows/tictoc_build.yml'
13 | - 'common/**'
14 | - 'tictoc/**'
15 |
16 | jobs:
17 | Build:
18 | runs-on: ubuntu-latest
19 | timeout-minutes: 10
20 |
21 | steps:
22 | - id: Begin
23 | name: Begin
24 | run: |
25 | echo "Begin ${GITHUB_WORKFLOW}/${GITHUB_JOB}"
26 |
27 | - id: Checkout
28 | name: Checkout
29 | uses: actions/checkout@v2
30 |
31 | - id: Install_apt
32 | name: Install_apt
33 | run: |
34 | sudo apt update -y
35 | sudo apt-get install -y $(cat build_tools/ubuntu.deps)
36 |
37 | - id: Submodule_init_recursive
38 | name: Submodule_init_recursive
39 | run: |
40 | git submodule update --init --recursive
41 |
42 | - id: Build_third_party_masstree
43 | name: Build_third_party_masstree
44 | run: |
45 | ./build_tools/bootstrap.sh
46 |
47 | - id: Build_third_party_mimalloc
48 | name: Build_third_party_mimalloc
49 | run: |
50 | ./build_tools/bootstrap_mimalloc.sh
51 |
52 | - id: Build_third_party_googletest
53 | name: Build_third_party_googletest
54 | run: |
55 | ./build_tools/bootstrap_googletest.sh
56 |
57 | - id: Build_tictoc
58 | name: Build_tictoc
59 | run: |
60 | cd tictoc
61 | mkdir -p build
62 | cd build
63 | cmake -DCMAKE_BUILD_TYPE=Debug ..
64 | make -j
65 |
--------------------------------------------------------------------------------
/.github/workflows/tpcc_silo_build_and_ctest.yml:
--------------------------------------------------------------------------------
1 | name: tpcc_silo_build_and_ctest
2 |
3 | on:
4 | push:
5 | paths:
6 | - '.github/workflows/tpcc_silo_build_and_ctest.yml'
7 | - 'common/**'
8 | - 'index/masstree_beta/masstree_beta_wrapper.cpp'
9 | - 'tpcc_silo/**'
10 | - 'third_party/**'
11 | pull_request:
12 | paths:
13 | - '.github/workflows/tpcc_silo_build_and_ctest.yml'
14 | - 'common/**'
15 | - 'index/masstree_beta/masstree_beta_wrapper.cpp'
16 | - 'tpcc_silo/**'
17 |
18 | jobs:
19 | Build:
20 | runs-on: ubuntu-latest
21 | timeout-minutes: 10
22 |
23 | steps:
24 | - id: Begin
25 | name: Begin
26 | run: |
27 | echo "Begin ${GITHUB_WORKFLOW}/${GITHUB_JOB}"
28 |
29 | - id: Checkout
30 | name: Checkout
31 | uses: actions/checkout@v2
32 |
33 | - id: Install_apt
34 | name: Install_apt
35 | run: |
36 | sudo apt update -y
37 | sudo apt-get install -y $(cat build_tools/ubuntu.deps)
38 |
39 | - id: Submodule_init_recursive
40 | name: Submodule_init_recursive
41 | run: |
42 | git submodule update --init --recursive
43 |
44 | - id: Build_third_party_masstree
45 | name: Build_third_party_masstree
46 | run: |
47 | ./build_tools/bootstrap.sh
48 |
49 | - id: Build_third_party_mimalloc
50 | name: Build_third_party_mimalloc
51 | run: |
52 | ./build_tools/bootstrap_mimalloc.sh
53 |
54 | - id: Build_third_party_googletest
55 | name: Build_third_party_googletest
56 | run: |
57 | ./build_tools/bootstrap_googletest.sh
58 |
59 | - id: Build_tpcc_silo
60 | name: Build_tpcc_silo
61 | run: |
62 | cd tpcc_silo
63 | mkdir -p build
64 | cd build
65 | cmake -DCMAKE_BUILD_TYPE=Debug ..
66 | make -j
67 |
68 | - id: Ctest_tpcc_silo
69 | name: Ctest_tpcc_silo
70 | continue-on-error: false
71 | env:
72 | GTEST_OUTPUT: xml
73 | ASAN_OPTIONS: detect_stack_use_after_return=true
74 | run: |
75 | cd tpcc_silo
76 | cd build
77 | ctest --verbose --timeout 100 -j 100
78 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.dat
2 | *.eps
3 | *.data
4 | *.old
5 | *.s
6 |
7 |
8 | # Created by https://www.gitignore.io/api/vim,c++,macos
9 |
10 | ### C++ ###
11 | # Prerequisites
12 | *.d
13 |
14 | # Compiled Object files
15 | *.slo
16 | *.lo
17 | *.o
18 | *.obj
19 |
20 | # Precompiled Headers
21 | *.gch
22 | *.pch
23 |
24 | # Compiled Dynamic libraries
25 | *.so
26 | *.dylib
27 | *.dll
28 |
29 | # Fortran module files
30 | *.mod
31 | *.smod
32 |
33 | # Compiled Static libraries
34 | *.lai
35 | *.la
36 | *.a
37 | *.lib
38 |
39 | # Executables
40 | *.exe
41 | *.out
42 | *.app
43 |
44 | ### macOS ###
45 | *.DS_Store
46 | .AppleDouble
47 | .LSOverride
48 |
49 | # Icon must end with two \r
50 | Icon
51 |
52 | # Thumbnails
53 | ._*
54 |
55 | # Files that might appear in the root of a volume
56 | .DocumentRevisions-V100
57 | .fseventsd
58 | .Spotlight-V100
59 | .TemporaryItems
60 | .Trashes
61 | .VolumeIcon.icns
62 | .com.apple.timemachine.donotpresent
63 |
64 | # Directories potentially created on remote AFP share
65 | .AppleDB
66 | .AppleDesktop
67 | Network Trash Folder
68 | Temporary Items
69 | .apdisk
70 |
71 | ### Vim ###
72 | # swap
73 | [._]*.s[a-v][a-z]
74 | [._]*.sw[a-p]
75 | [._]s[a-v][a-z]
76 | [._]sw[a-p]
77 | # session
78 | Session.vim
79 | # temporary
80 | .netrwhist
81 | *~
82 | # auto-generated tag files
83 | tags
84 |
85 | # End of https://www.gitignore.io/api/vim,c++,macos
86 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "third_party/masstree"]
2 | path = third_party/masstree
3 | url = https://github.com/thawk105/masstree-beta.git
4 | [submodule "third_party/googletest"]
5 | path = third_party/googletest
6 | url = https://github.com/google/googletest.git
7 | [submodule "third_party/mimalloc"]
8 | path = third_party/mimalloc
9 | url = https://github.com/microsoft/mimalloc.git
10 | [submodule "third_party/spdlog"]
11 | path = third_party/spdlog
12 | url = https://github.com/gabime/spdlog.git
13 |
--------------------------------------------------------------------------------
/build_tools/bootstrap.sh:
--------------------------------------------------------------------------------
1 | # prepare for masstree
2 | cd third_party/masstree
3 | ./bootstrap.sh
4 | ./configure --disable-assertions
5 | make clean
6 | make -j CXXFLAGS='-g -W -Wall -O3 -fPIC'
7 | ar cr libkohler_masstree_json.a json.o string.o straccum.o str.o msgpack.o clp.o kvrandom.o compiler.o memdebug.o kvthread.o misc.o
8 | ranlib libkohler_masstree_json.a
9 |
10 |
--------------------------------------------------------------------------------
/build_tools/bootstrap_apt.sh:
--------------------------------------------------------------------------------
1 | sudo apt update -y
2 | sudo apt install -y libgflags-dev cmake cmake-curses-gui libboost-filesystem-dev
3 |
--------------------------------------------------------------------------------
/build_tools/bootstrap_googletest.sh:
--------------------------------------------------------------------------------
1 | cd third_party/googletest
2 | mkdir -p build
3 | cd build
4 | cmake ..
5 | make -j
6 |
--------------------------------------------------------------------------------
/build_tools/bootstrap_mimalloc.sh:
--------------------------------------------------------------------------------
1 | # prepare for mimalloc
2 | cd third_party/mimalloc
3 | mkdir -p out/release
4 | cd out/release
5 | cmake -DCMAKE_BUILD_TYPE=Release ../..
6 | make clean all -j
7 |
8 | cd ../
9 | mkdir debug
10 | cd debug
11 | cmake -DCMAKE_BUILD_TYPE=Debug ../..
12 | make clean all -j
13 |
14 | cd ../
15 | mkdir secure
16 | cd secure
17 | cmake -DMI_SECURE=ON ../..
18 | make clean all -j
19 |
20 | # prepare for tbb
21 | cd ../../../tbb
22 | make clean all -j
23 |
24 | cd ../../
25 |
--------------------------------------------------------------------------------
/build_tools/bootstrap_tbb.sh:
--------------------------------------------------------------------------------
1 | # prepare for tbb
2 | cd third_party/tbb
3 | make -j
4 | cd ../../
5 |
--------------------------------------------------------------------------------
/build_tools/ubuntu.deps:
--------------------------------------------------------------------------------
1 | cmake cmake-curses-gui
2 | libboost-filesystem-dev
3 | libgflags-dev
4 | libgoogle-glog-dev
5 |
--------------------------------------------------------------------------------
/cc_format/Makefile:
--------------------------------------------------------------------------------
1 | PROG1 = sv_format.exe
2 | SV_FORMAT_SRCS1 := sv_format.cc transaction.cc util.cc result.cc
3 |
4 | REL := ../common/
5 | include $(REL)Makefile
6 | SV_FORMAT_ALLSRC = $(SV_FORMAT_SRCS1) $(SRCS2) $(wildcard include/*.hh)
7 |
8 | # start of initialization of some parameters.
9 | ADD_ANALYSIS=1
10 | BACK_OFF=0
11 | KEY_SIZE=8
12 | MASSTREE_USE=1
13 | NO_WAIT_LOCKING_IN_VALIDATION=0
14 | NO_WAIT_OF_TICTOC=1
15 | PARTITION_TABLE=0
16 | PROCEDURE_SORT=0
17 | SLEEP_READ_PHASE=0 # of tics
18 | VAL_SIZE=4
19 | WAL=0
20 | # end of initialization
21 |
22 | CC = g++
23 | CFLAGS = -c -pipe -g -O3 -std=c++17 -march=native \
24 | -Wall -Wextra -Wdangling-else -Wchkp -Winvalid-memory-model \
25 | -D$(shell uname) \
26 | -D$(shell hostname) \
27 | -DKEY_SIZE=$(KEY_SIZE) \
28 | -DVAL_SIZE=$(VAL_SIZE) \
29 | -DADD_ANALYSIS=$(ADD_ANALYSIS) \
30 | -DBACK_OFF=$(BACK_OFF) \
31 | -DMASSTREE_USE=$(MASSTREE_USE) \
32 | -DNO_WAIT_LOCKING_IN_VALIDATION=$(NO_WAIT_LOCKING_IN_VALIDATION) \
33 | -DNO_WAIT_OF_TICTOC=$(NO_WAIT_OF_TICTOC) \
34 | -DPARTITION_TABLE=$(PARTITION_TABLE) \
35 | -DPROCEDURE_SORT=$(PROCEDURE_SORT) \
36 | -DSLEEP_READ_PHASE=$(SLEEP_READ_PHASE) \
37 | -DWAL=$(WAL) \
38 |
39 | INCLUDE = -I/usr/include \
40 | -I../third_party/ \
41 |
42 | LDLIBS = -lpthread -lboost_filesystem -lboost_system -lgflags -lglog
43 |
44 | OBJS1 = $(SV_FORMAT_SRCS1:.cc=.o)
45 |
46 | all: $(PROG1)
47 |
48 | include ../include/MakefileForMasstreeUse
49 | $(PROG1) : $(OBJS1) $(MASSOBJ)
50 | $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(INCLUDE)
51 |
52 | .cc.o:
53 | $(CC) $(CFLAGS) -c $< -o $@
54 |
55 | format:
56 | clang-format -i -verbose -style=Google $(SV_FORMAT_ALLSRC)
57 |
58 | clean:
59 | rm -f *~ *.o *.exe *.stackdump
60 | rm -f ../common/*~ ../common/*.o ../common/*.exe ../common/*.stackdump
61 | rm -rf .deps
62 |
--------------------------------------------------------------------------------
/cc_format/README.md:
--------------------------------------------------------------------------------
1 | # Single version concurrency control format
2 | - This is the format for adding single-version concurrency control.
3 |
4 | ## Where to edit
5 | ### Source files
6 | - result.cc
7 | - L12-14 : Declare the variables with appropriate names.
8 | - sv_format.cc
9 | Set an appropriate file name.
10 | - L48-66 : Edit it appropriately when you enable log persistence.
11 | - L106-133 : Define a single transaction workflow.
12 | - util.cc
13 | - L105-117 : Set initial value of record member appropriately.
14 | - leaderWork function : Define the job of a leader thread.
15 | - Makefile
16 | - Edit the file name "sv_format / SV_FORMAT" appropriately.
17 | - L9-37 : Define your preprocessor definition properly to determine the configuration.
18 | - Please remove the libraries and options that cannot be used in the experimental environment.
19 | - transaction.cc
20 | - Define the tbegin/validationPhase/abort/writePhase/read/write function properly.
21 | Delete unnecessary functions and add necessary functions to the transaction workflow.
22 | ### Header files
23 | - include/common.hh
24 | - Define the global variables and workload configuration variables that are necessary for Concurrency Control.
25 | - include/log.hh
26 | - Define the members of LogRecord class as appropriate. Please modify accordingly.
27 | - include/result.hh
28 | - Change the name of the variable appropriately.
29 | - include/silo_op_element.hh
30 | - Change the file name appropriately.
31 | - Change the members of ReadElement/WriteElement appropriately. And make corrections accordingly.
32 | - include/transaction.hh
33 | - Modify the members of TransactionStatus class appropriately as necessary.
34 | - TxnExecutor class is information that should be held by the worker thread. Please add any information necessary for concurrency control to the class members.
35 | - include/tuple.hh
36 | - Declare the metadata to be stored in the record header in the Tuple class.
37 | - attention : To improve the performance, no keys are stored. When a one-dimensional array is used as a DB table, the index position is the key. If you use masstree, the key-value is stored in the leaf node of masstree and the value is a pointer to the record, so there is no need to store the key.
38 | - include/util.hh
39 | - Edit it appropriately in conjunction with util.cc.
40 |
--------------------------------------------------------------------------------
/cc_format/include/atomic_tool.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "common.hh"
4 |
5 | #include "../../include/inline.hh"
6 |
7 | INLINE uint64_t atomicLoadGE();
8 |
9 | INLINE void atomicAddGE() {
10 | uint64_t expected, desired;
11 |
12 | expected = atomicLoadGE();
13 | for (;;) {
14 | desired = expected + 1;
15 | if (__atomic_compare_exchange_n(&(GlobalEpoch.obj_), &expected, desired,
16 | false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE))
17 | break;
18 | }
19 | }
20 |
21 | INLINE uint64_t atomicLoadGE() {
22 | uint64_t_64byte result =
23 | __atomic_load_n(&(GlobalEpoch.obj_), __ATOMIC_ACQUIRE);
24 | return result.obj_;
25 | }
26 |
27 | INLINE void atomicStoreThLocalEpoch(unsigned int thid, uint64_t newval) {
28 | __atomic_store_n(&(ThLocalEpoch[thid].obj_), newval, __ATOMIC_RELEASE);
29 | }
30 |
--------------------------------------------------------------------------------
/cc_format/include/common.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "tuple.hh"
8 |
9 | #include "../../include/cache_line_size.hh"
10 | #include "../../include/int64byte.hh"
11 | #include "../../include/masstree_wrapper.hh"
12 |
13 | #include "gflags/gflags.h"
14 | #include "glog/logging.h"
15 |
16 | #ifdef GLOBAL_VALUE_DEFINE
17 | #define GLOBAL
18 | alignas(CACHE_LINE_SIZE) GLOBAL uint64_t_64byte GlobalEpoch(1);
19 | #if MASSTREE_USE
20 | alignas(CACHE_LINE_SIZE) GLOBAL MasstreeWrapper MT;
21 | #endif
22 | #else
23 | #define GLOBAL extern
24 | alignas(CACHE_LINE_SIZE) GLOBAL uint64_t_64byte GlobalEpoch;
25 | #if MASSTREE_USE
26 | alignas(CACHE_LINE_SIZE) GLOBAL MasstreeWrapper MT;
27 | #endif
28 | #endif
29 |
30 | #ifdef GLOBAL_VALUE_DEFINE
31 | DEFINE_uint64(clocks_per_us, 2100,
32 | "CPU_MHz. Use this info for measuring time.");
33 | DEFINE_uint64(epoch_time, 40, "Epoch interval[msec].");
34 | DEFINE_uint64(extime, 3, "Execution time[sec].");
35 | DEFINE_uint64(max_ope, 10,
36 | "Total number of operations per single transaction.");
37 | DEFINE_bool(rmw, false,
38 | "True means read modify write, false means blind write.");
39 | DEFINE_uint64(rratio, 50, "read ratio of single transaction.");
40 | DEFINE_uint64(thread_num, 10, "Total number of worker threads.");
41 | DEFINE_uint64(tuple_num, 1000000, "Total number of records.");
42 | DEFINE_bool(ycsb, true,
43 | "True uses zipf_skew, false uses faster random generator.");
44 | DEFINE_double(zipf_skew, 0, "zipf skew. 0 ~ 0.999...");
45 | #else
46 | DECLARE_uint64(clocks_per_us);
47 | DECLARE_uint64(epoch_time);
48 | DECLARE_uint64(extime);
49 | DECLARE_uint64(max_ope);
50 | DECLARE_bool(rmw);
51 | DECLARE_uint64(rratio);
52 | DECLARE_uint64(thread_num);
53 | DECLARE_uint64(tuple_num);
54 | DECLARE_bool(ycsb);
55 | DECLARE_double(zipf_skew);
56 | #endif
57 |
58 | alignas(CACHE_LINE_SIZE) GLOBAL uint64_t_64byte *ThLocalEpoch;
59 | alignas(CACHE_LINE_SIZE) GLOBAL uint64_t_64byte *CTIDW;
60 |
61 | alignas(CACHE_LINE_SIZE) GLOBAL Tuple *Table;
62 |
--------------------------------------------------------------------------------
/cc_format/include/log.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | class LogHeader {
9 | public:
10 | int chkSum_ = 0;
11 | unsigned int logRecNum_ = 0;
12 | const std::size_t len_val_ = VAL_SIZE;
13 |
14 | void init() {
15 | chkSum_ = 0;
16 | logRecNum_ = 0;
17 | }
18 |
19 | void convertChkSumIntoComplementOnTwo() {
20 | chkSum_ ^= 0xffffffff;
21 | ++chkSum_;
22 | }
23 | };
24 |
25 | class LogRecord {
26 | public:
27 | uint64_t tid_;
28 | unsigned int key_;
29 | char val_[VAL_SIZE];
30 |
31 | LogRecord() : tid_(0), key_(0) {}
32 |
33 | LogRecord(uint64_t tid, unsigned int key, char *val) : tid_(tid), key_(key) {
34 | memcpy(this->val_, val, VAL_SIZE);
35 | }
36 |
37 | int computeChkSum() {
38 | // compute checksum
39 | int chkSum = 0;
40 | int *itr = (int *)this;
41 | for (unsigned int i = 0; i < sizeof(LogRecord) / sizeof(int); ++i) {
42 | chkSum += (*itr);
43 | ++itr;
44 | }
45 |
46 | return chkSum;
47 | }
48 | };
49 |
50 | class LogPackage {
51 | public:
52 | LogHeader header_;
53 | std::unique_ptr log_records_;
54 | };
55 |
--------------------------------------------------------------------------------
/cc_format/include/result.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/result.hh"
6 |
7 | extern std::vector SiloResult;
8 |
9 | extern void initResult();
10 |
--------------------------------------------------------------------------------
/cc_format/include/silo_op_element.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../../include/op_element.hh"
4 |
5 | template
6 | class ReadElement : public OpElement {
7 | public:
8 | using OpElement::OpElement;
9 |
10 | Tidword tidword_;
11 | char val_[VAL_SIZE];
12 |
13 | ReadElement(uint64_t key, T* rcdptr, char* val, Tidword tidword)
14 | : OpElement::OpElement(key, rcdptr) {
15 | tidword_.obj_ = tidword.obj_;
16 | memcpy(this->val_, val, VAL_SIZE);
17 | }
18 |
19 | bool operator<(const ReadElement& right) const {
20 | return this->key_ < right.key_;
21 | }
22 | };
23 |
24 | template
25 | class WriteElement : public OpElement {
26 | public:
27 | using OpElement::OpElement;
28 |
29 | WriteElement(uint64_t key, T* rcdptr)
30 | : OpElement::OpElement(key, rcdptr) {}
31 |
32 | bool operator<(const WriteElement& right) const {
33 | return this->key_ < right.key_;
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/cc_format/include/tuple.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | #include "../../include/cache_line_size.hh"
10 |
11 | class Tuple {
12 | public:
13 | char val_[VAL_SIZE];
14 | };
15 |
--------------------------------------------------------------------------------
/cc_format/include/util.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | extern void chkArg();
4 |
5 | extern bool chkEpochLoaded();
6 |
7 | extern void displayDB();
8 |
9 | extern void displayParameter();
10 |
11 | extern void genLogFile(std::string &logpath, const int thid);
12 |
13 | extern void leaderWork(uint64_t &epoch_timer_start, uint64_t &epoch_timer_stop);
14 |
15 | extern void makeDB();
16 |
17 | extern void partTableInit([[maybe_unused]] size_t thid, uint64_t start,
18 | uint64_t end);
19 |
20 | extern void ShowOptParameters();
21 |
--------------------------------------------------------------------------------
/cc_format/result.cc:
--------------------------------------------------------------------------------
1 | #include "include/result.hh"
2 | #include "include/common.hh"
3 |
4 | #include "../include/cache_line_size.hh"
5 | #include "../include/result.hh"
6 |
7 | using namespace std;
8 |
9 | /**
10 | * Please declare it with an appropriate name.
11 | */
12 | alignas(CACHE_LINE_SIZE) std::vector SiloResult;
13 |
14 | void initResult() { SiloResult.resize(FLAGS_thread_num); }
15 |
--------------------------------------------------------------------------------
/cicada/include/cicada_op_element.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "version.hh"
4 |
5 | template
6 | class ReadElement : public OpElement {
7 | public:
8 | using OpElement::OpElement;
9 |
10 | Version *later_ver_, *ver_;
11 |
12 | ReadElement(uint64_t key, T *rcdptr, Version *later_ver, Version *ver)
13 | : OpElement::OpElement(key, rcdptr) {
14 | later_ver_ = later_ver;
15 | ver_ = ver;
16 | }
17 |
18 | bool operator<(const ReadElement &right) const {
19 | return this->key_ < right.key_;
20 | }
21 | };
22 |
23 | template
24 | class WriteElement : public OpElement {
25 | public:
26 | using OpElement::OpElement;
27 |
28 | Version *later_ver_, *new_ver_;
29 | bool rmw_;
30 | bool finish_version_install_;
31 |
32 | WriteElement(uint64_t key, T *rcdptr, Version *later_ver, Version *new_ver,
33 | bool rmw)
34 | : OpElement::OpElement(key, rcdptr) {
35 | later_ver_ = later_ver;
36 | new_ver_ = new_ver;
37 | rmw_ = rmw;
38 | finish_version_install_ = false;
39 | }
40 |
41 | bool operator<(const WriteElement &right) const {
42 | return this->key_ < right.key_;
43 | }
44 | };
45 |
46 | template
47 | class GCElement : public OpElement {
48 | public:
49 | using OpElement::OpElement;
50 |
51 | Version *ver_;
52 | uint64_t wts_;
53 |
54 | GCElement() : ver_(nullptr), wts_(0) { this->key_ = 0; }
55 |
56 | GCElement(uint64_t key, T *rcdptr, Version *ver, uint64_t wts)
57 | : OpElement::OpElement(key, rcdptr) {
58 | this->ver_ = ver;
59 | this->wts_ = wts;
60 | }
61 | };
62 |
--------------------------------------------------------------------------------
/cicada/include/lock.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | class RWLock {
9 | public:
10 | std::atomic counter;
11 | // counter == -1, write locked;
12 | // counter == 0, not locked;
13 | // counter > 0, there are $counter readers who acquires read-lock.
14 |
15 | RWLock() { counter.store(0, std::memory_order_release); }
16 |
17 | // Read lock
18 | void r_lock() {
19 | int expected, desired;
20 | for (;;) {
21 | expected = counter.load(std::memory_order_acquire);
22 | RETRY_R_LOCK:
23 | if (expected != -1)
24 | desired = expected + 1;
25 | else {
26 | continue;
27 | }
28 | if (counter.compare_exchange_strong(
29 | expected, desired, memory_order_acq_rel, memory_order_acquire))
30 | break;
31 | else
32 | goto RETRY_R_LOCK;
33 | }
34 | }
35 |
36 | void r_unlock() { counter--; }
37 |
38 | // Write lock
39 | void w_lock() {
40 | int expected;
41 | for (;;) {
42 | expected = counter.load(memory_order_acquire);
43 | RETRY_W_LOCK:
44 | if (expected != 0) continue;
45 | if (counter.compare_exchange_strong(expected, -1, memory_order_acq_rel,
46 | memory_order_acquire))
47 | break;
48 | else
49 | goto RETRY_W_LOCK;
50 | }
51 | }
52 |
53 | void w_unlock() { counter++; }
54 |
55 | // Upgrae, read -> write
56 | void upgrade() {
57 | int one = 1;
58 | while (!counter.compare_exchange_strong(one, -1, memory_order_acq_rel,
59 | memory_order_acquire)) {
60 | }
61 | }
62 | };
63 |
--------------------------------------------------------------------------------
/cicada/include/result.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/result.hh"
6 |
7 | extern std::vector CicadaResult;
8 |
9 | extern void initResult();
10 |
--------------------------------------------------------------------------------
/cicada/include/time_stamp.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../../include/cache_line_size.hh"
4 | #include "../../include/tsc.hh"
5 |
6 | class TimeStamp {
7 | public:
8 | alignas(CACHE_LINE_SIZE) uint64_t ts_ = 0;
9 | uint64_t localClock_ = 0;
10 | uint64_t clockBoost_ = 0;
11 | uint8_t thid_;
12 |
13 | TimeStamp() {}
14 |
15 | inline uint64_t get_ts() { return ts_; }
16 |
17 | inline void set_ts(uint64_t &ts) { this->ts_ = ts; }
18 |
19 | inline void set_clockBoost(unsigned int CLOCK_PER_US) {
20 | // set 0 or some value equivalent to 1 us.
21 | clockBoost_ = CLOCK_PER_US;
22 | }
23 |
24 | inline void generateTimeStampFirst(uint8_t tid) {
25 | localClock_ = rdtscp();
26 | ts_ = (localClock_ << (sizeof(tid) * 8)) | tid;
27 | thid_ = tid;
28 | }
29 |
30 | inline void generateTimeStamp(uint8_t tid) {
31 | uint64_t tmp = rdtscp();
32 | uint64_t elapsedTime = tmp - localClock_;
33 | if (tmp < localClock_) elapsedTime = 0;
34 |
35 | // current local clock + elapsed time + clockBoost
36 | localClock_ += elapsedTime;
37 | localClock_ += clockBoost_;
38 |
39 | ts_ = (localClock_ << (sizeof(tid) * 8)) | tid;
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/cicada/include/tuple.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "../../include/cache_line_size.hh"
7 |
8 | #include "version.hh"
9 |
10 | using namespace std;
11 |
12 | class Tuple {
13 | public:
14 | alignas(CACHE_LINE_SIZE)
15 | #if INLINE_VERSION_OPT
16 | Version inline_ver_;
17 | #endif
18 | atomic latest_;
19 | atomic min_wts_;
20 | atomic continuing_commit_;
21 | atomic gc_lock_;
22 |
23 | Tuple() : latest_(nullptr), gc_lock_(0) {}
24 |
25 | Version *ldAcqLatest() { return latest_.load(std::memory_order_acquire); }
26 |
27 | bool getGCRight(uint8_t thid) {
28 | uint8_t expected, desired(thid);
29 | expected = this->gc_lock_.load(std::memory_order_acquire);
30 | for (;;) {
31 | if (expected != 0) return false;
32 | if (this->gc_lock_.compare_exchange_strong(expected, desired,
33 | std::memory_order_acq_rel,
34 | std::memory_order_acquire))
35 | return true;
36 | }
37 | }
38 |
39 | void returnGCRight() { this->gc_lock_.store(0, std::memory_order_release); }
40 |
41 | #if INLINE_VERSION_OPT
42 | // inline
43 | bool getInlineVersionRight() {
44 | VersionStatus expected, desired(VersionStatus::pending);
45 | expected = this->inline_ver_.status_.load(std::memory_order_acquire);
46 | for (;;) {
47 | if (expected != VersionStatus::unused) return false;
48 | if (this->inline_ver_.status_.compare_exchange_strong(
49 | expected, desired, std::memory_order_acq_rel,
50 | std::memory_order_acquire))
51 | return true;
52 | }
53 | }
54 |
55 | void returnInlineVersionRight() {
56 | this->inline_ver_.status_.store(VersionStatus::unused,
57 | std::memory_order_release);
58 | }
59 | #endif
60 | };
61 |
--------------------------------------------------------------------------------
/cicada/include/util.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/backoff.hh"
6 |
7 | extern void chkArg();
8 |
9 | extern void deleteDB();
10 |
11 | [[maybe_unused]] extern void displayDB();
12 |
13 | [[maybe_unused]] extern void displayMinRts();
14 |
15 | [[maybe_unused]] extern void displayMinWts();
16 |
17 | extern void displayParameter();
18 |
19 | [[maybe_unused]] extern void displaySLogSet();
20 |
21 | [[maybe_unused]] extern void displayThreadWtsArray();
22 |
23 | [[maybe_unused]] extern void displayThreadRtsArray();
24 |
25 | extern void leaderWork([[maybe_unused]] Backoff &backoff);
26 |
27 | extern void makeDB(uint64_t *initial_wts);
28 |
29 | extern void partTableDelete([[maybe_unused]] size_t thid, uint64_t start,
30 | uint64_t end);
31 |
32 | extern void partTableInit([[maybe_unused]] size_t thid, uint64_t initts,
33 | uint64_t start, uint64_t end);
34 |
35 | extern void ShowOptParameters();
36 |
--------------------------------------------------------------------------------
/cicada/result.cc:
--------------------------------------------------------------------------------
1 | #include "include/result.hh"
2 | #include "include/common.hh"
3 |
4 | #include "../include/cache_line_size.hh"
5 | #include "../include/result.hh"
6 |
7 | using namespace std;
8 |
9 | alignas(CACHE_LINE_SIZE) std::vector CicadaResult;
10 |
11 | void initResult() { CicadaResult.resize(FLAGS_thread_num); }
12 |
--------------------------------------------------------------------------------
/cicada/script/ycsbA-xgcidbsize-cache.sh:
--------------------------------------------------------------------------------
1 | #ycsbA-xgcidbsize.sh(cicada)
2 | maxope=10
3 | thread=24
4 | rratio=50
5 | skew=0
6 | ycsb=ON
7 | wal=OFF
8 | group_commit=OFF
9 | cpu_mhz=2400
10 | io_time_ns=5
11 | group_commit_timeout_us=2
12 | lock_release=E
13 | extime=1
14 | epoch=1
15 |
16 | result=result_cicada_ycsbA_tuple100-10m_gci1us-100ms_cache-miss.dat
17 | rm $result
18 | echo "#tuple num, gci, throughput, min, max" >> $result
19 | for ((tuple=100; tuple<=10000000; tuple*=10))
20 | do
21 | for ((gci=1; gci<=100000; gci*=10))
22 | do
23 | sum=0
24 | echo "./cicada.exe $tuple $maxope $thread $rratio $skew $ycsb $wal $group_commit $cpu_mhz $io_time_ns $group_commit_timeout_us $lock_release $gci $extime"
25 | echo "$tuple $epoch"
26 |
27 | max=0
28 | min=0
29 | for ((i = 1; i <= epoch; ++i))
30 | do
31 | perf stat -e cache-misses,cache-references -o cicada-cache-ana.txt ./cicada.exe $tuple $maxope $thread $rratio $skew $ycsb $wal $group_commit $cpu_mhz $io_time_ns $group_commit_timeout_us $lock_release $gci $extime
32 | tmp=`grep cache-misses ./cicada-cache-ana.txt | awk '{print $4}'`
33 | sum=`echo "$sum + $tmp" | bc -l`
34 | echo "sum: $sum, tmp: $tmp"
35 |
36 | if test $i -eq 1 ; then
37 | max=$tmp
38 | min=$tmp
39 | fi
40 |
41 | flag=`echo "$tmp > $max" | bc -l`
42 | if test $flag -eq 1 ; then
43 | max=$tmp
44 | fi
45 | flag=`echo "$tmp < $min" | bc -l`
46 | if test $flag -eq 1 ; then
47 | min=$tmp
48 | fi
49 | done
50 | avg=`echo "$sum / $epoch" | bc -l`
51 | echo "sum: $sum, epoch: $epoch"
52 | echo "avg $avg"
53 | echo "max: $max"
54 | echo "min: $min"
55 | echo "$tuple $gci $avg $min $max" >> $result
56 | done
57 | echo "" >> $result
58 | done
59 |
--------------------------------------------------------------------------------
/cicada/script/ycsbA-xrs-cache.sh:
--------------------------------------------------------------------------------
1 | #ycsbA-xrs-cache.sh(cicada)
2 | maxope=10
3 | thread=24
4 | rratio=50
5 | skew=0
6 | ycsb=ON
7 | wal=OFF
8 | group_commit=OFF
9 | cpu_mhz=2400
10 | io_time_ns=5
11 | group_commit_timeout_us=2
12 | lock_release=E
13 | extime=1
14 | epoch=1
15 |
16 | result=result_cicada_ycsbA_tuple100-10m_cachemiss.dat
17 | rm $result
18 | echo "#tuple num, cache-misses, min, max" >> $result
19 | echo "#./cicada.exe tuple $maxope $thread $rratio $skew $ycsb $wal $group_commit $cpu_mhz $io_time_ns $group_commit_timeout_us $lock_release $extime" >> $result
20 |
21 | for ((tuple=100; tuple<=10000000; tuple*=10))
22 | do
23 | sum=0
24 | echo "./cicada.exe $tuple $maxope $thread $rratio $skew $ycsb $wal $group_commit $cpu_mhz $io_time_ns $group_commit_timeout_us $lock_release $extime"
25 | echo "$tuple $epoch"
26 |
27 | max=0
28 | min=0
29 | for ((i = 1; i <= epoch; ++i))
30 | do
31 | perf stat -e cache-misses,cache-references -o cicada-cache-ana.txt ./cicada.exe $tuple $maxope $thread $rratio $skew $ycsb $wal $group_commit $cpu_mhz $io_time_ns $group_commit_timeout_us $lock_release $extime
32 | tmp=`grep cache-misses ./cicada-cache-ana.txt | awk '{print $4}'`
33 | sum=`echo "$sum + $tmp" | bc -l`
34 | echo "sum: $sum, tmp: $tmp"
35 |
36 | if test $i -eq 1 ; then
37 | max=$tmp
38 | min=$tmp
39 | fi
40 |
41 | flag=`echo "$tmp > $max" | bc -l`
42 | if test $flag -eq 1 ; then
43 | max=$tmp
44 | fi
45 | flag=`echo "$tmp < $min" | bc -l`
46 | if test $flag -eq 1 ; then
47 | min=$tmp
48 | fi
49 | done
50 | avg=`echo "$sum / $epoch" | bc -l`
51 | echo "sum: $sum, epoch: $epoch"
52 | echo "avg $avg"
53 | echo "max: $max"
54 | echo "min: $min"
55 | echo "$tuple $avg $min $max" >> $result
56 | done
57 |
58 |
--------------------------------------------------------------------------------
/cicada/testzip.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include "include/debug.hpp"
7 | #include "include/random.hpp"
8 | #include "include/tsc.hpp"
9 | #include "include/zipf.hpp"
10 |
11 | using std::cout, std::endl;
12 |
13 | int
14 | main() {
15 | pid_t pid = syscall(SYS_gettid);
16 | cpu_set_t cpu_set;
17 |
18 | CPU_ZERO(&cpu_set);
19 | CPU_SET(0, &cpu_set);
20 |
21 | if (sched_setaffinity(pid, sizeof(cpu_set_t), &cpu_set) != 0)
22 | ERR;
23 |
24 | Xoroshiro128Plus rnd;
25 | rnd.init();
26 | uint64_t start, stop, tmp;
27 |
28 | FastZipf zipf(&rnd, 0, 10);
29 |
30 | // warm up
31 | for (int i = 0; i < 100; ++i)
32 | start = rnd.next();
33 |
34 | start = rdtscp();
35 | for (int i = 0; i < 1000000; ++i)
36 | rnd.next();
37 | stop = rdtscp();
38 |
39 | cout << "xoroshiro : " << (stop - start) / 1000000 << endl;
40 |
41 | start = rdtscp();
42 | zipf();
43 | stop = rdtscp();
44 |
45 | cout << "zipf() : " << stop - start << endl;
46 |
47 | //for (uint i = 0; i < 10; ++i)
48 | // cout << zipf() << endl;
49 |
50 | int ary[10] = {};
51 | for (uint i = 0; i < 10000; ++i)
52 | ++ary[zipf()];
53 |
54 | for (uint i = 0; i < 10; ++i)
55 | cout << "ary[" << i << "] = " << ary[i] << endl;
56 |
57 | return 0;
58 | }
59 |
--------------------------------------------------------------------------------
/cmake/CompileOptions.cmake:
--------------------------------------------------------------------------------
1 | set(CMAKE_CXX_STANDARD 17)
2 | set(CMAKE_CXX_EXTENSIONS OFF)
3 | set(CMAKE_CXX_STANDARD_REQUIRED ON)
4 |
5 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer")
6 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-omit-frame-pointer")
7 |
8 | set(sanitizers "address")
9 | if (ENABLE_UB_SANITIZER)
10 | # NOTE: UB check requires instrumented libstdc++
11 | set(sanitizers "${sanitizers},undefined")
12 | endif ()
13 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
14 | # do nothing for gcc
15 | elseif (CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|AppleClang)$")
16 | set(sanitizers "${sanitizers},nullability")
17 | else ()
18 | message(FATAL_ERROR "unsupported compiler ${CMAKE_CXX_COMPILER_ID}")
19 | endif ()
20 |
21 | if (ENABLE_SANITIZER)
22 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=${sanitizers}")
23 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-sanitize=alignment")
24 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-sanitize-recover=${sanitizers}")
25 | endif ()
26 | if (ENABLE_COVERAGE)
27 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} --coverage")
28 | endif ()
29 |
30 | function(set_compile_options target_name)
31 | target_compile_options(${target_name}
32 | PRIVATE -Wall -Wextra -Werror)
33 | endfunction(set_compile_options)
34 |
--------------------------------------------------------------------------------
/cmake/Findgflags.cmake:
--------------------------------------------------------------------------------
1 | if(TARGET gflags::gflags)
2 | return()
3 | endif()
4 |
5 | find_library(gflags_LIBRARY_FILE NAMES gflags)
6 | find_path(gflags_INCLUDE_DIR NAMES gflags/gflags.h)
7 |
8 | include(FindPackageHandleStandardArgs)
9 | find_package_handle_standard_args(gflags DEFAULT_MSG
10 | gflags_LIBRARY_FILE
11 | gflags_INCLUDE_DIR)
12 |
13 | if(gflags_LIBRARY_FILE AND gflags_INCLUDE_DIR)
14 | set(gflags_FOUND ON)
15 | add_library(gflags::gflags SHARED IMPORTED)
16 | set_target_properties(gflags::gflags PROPERTIES
17 | IMPORTED_LOCATION "${gflags_LIBRARY_FILE}"
18 | INTERFACE_INCLUDE_DIRECTORIES "${gflags_INCLUDE_DIR}")
19 | else()
20 | set(gflags_FOUND OFF)
21 | endif()
22 |
23 | unset(gflags_LIBRARY_FILE CACHE)
24 | unset(gflags_INCLUDE_DIR CACHE)
25 |
--------------------------------------------------------------------------------
/cmake/Findglog.cmake:
--------------------------------------------------------------------------------
1 | if(TARGET glog::glog)
2 | return()
3 | endif()
4 |
5 | find_library(glog_LIBRARY_FILE NAMES glog)
6 | find_path(glog_INCLUDE_DIR NAMES glog/logging.h)
7 |
8 | include(FindPackageHandleStandardArgs)
9 | find_package_handle_standard_args(glog DEFAULT_MSG
10 | glog_LIBRARY_FILE
11 | glog_INCLUDE_DIR)
12 |
13 | if(glog_LIBRARY_FILE AND glog_INCLUDE_DIR)
14 | set(glog_FOUND ON)
15 | add_library(glog::glog SHARED IMPORTED)
16 | set_target_properties(glog::glog PROPERTIES
17 | IMPORTED_LOCATION "${glog_LIBRARY_FILE}"
18 | INTERFACE_INCLUDE_DIRECTORIES "${glog_INCLUDE_DIR}")
19 | else()
20 | set(glog_FOUND OFF)
21 | endif()
22 |
23 | unset(glog_LIBRARY_FILE CACHE)
24 | unset(glog_INCLUDE_DIR CACHE)
25 |
--------------------------------------------------------------------------------
/common/Makefile:
--------------------------------------------------------------------------------
1 |
2 | SV_FORMAT_SRCS1+=\
3 | $(REL)result.cc\
4 | $(REL)util.cc\
5 |
6 | ######
7 | INST_SRCS1+=\
8 | $(REL)util.cc
9 |
10 | INST_SRCS2+=\
11 | $(REL)util.cc
12 |
13 | INST_SRCS3+=\
14 | $(REL)util.cc
15 |
16 | INST_SRCS4+=\
17 | $(REL)util.cc
18 | ######
19 |
--------------------------------------------------------------------------------
/common/util.cc:
--------------------------------------------------------------------------------
1 |
2 | #include "./../include/atomic_wrapper.hh"
3 | #include "./../include/util.hh"
4 |
5 | [[maybe_unused]] bool chkSpan(struct timeval &start, struct timeval &stop, long threshold) {
6 | long diff = 0;
7 | diff += (stop.tv_sec - start.tv_sec) * 1000 * 1000 +
8 | (stop.tv_usec - start.tv_usec);
9 | if (diff > threshold) {
10 | return true;
11 | }
12 | return false;
13 | }
14 |
15 | size_t decideParallelBuildNumber(size_t tuple_num) {
16 | // if table size is very small, it builds by single thread.
17 | if (tuple_num < 1000) return 1;
18 |
19 | // else
20 | for (size_t i = std::thread::hardware_concurrency(); i > 0; --i) {
21 | if (tuple_num % i == 0) {
22 | return i;
23 | }
24 | if (i == 1) ERR;
25 | }
26 |
27 | return 0;
28 | }
29 |
30 | void displayProcedureVector(std::vector &pro) {
31 | printf("--------------------\n");
32 | size_t index = 0;
33 | for (auto &&elem : pro) {
34 | printf(
35 | "-----\n"
36 | "op_num\t: %zu\n"
37 | "key\t: %zu\n"
38 | "r/w\t: %d\n",
39 | index, elem.key_, (int) (elem.ope_));
40 | ++index;
41 | }
42 | printf("--------------------\n");
43 | }
44 |
45 | void displayRusageRUMaxrss() {
46 | struct rusage r{};
47 | if (getrusage(RUSAGE_SELF, &r) != 0) ERR;
48 | printf("maxrss:\t%ld kB\n", r.ru_maxrss);
49 | }
50 |
51 | void readyAndWaitForReadyOfAllThread(std::atomic &running,
52 | const size_t thnm) {
53 | running++;
54 | while (running.load(std::memory_order_acquire) != thnm) _mm_pause();
55 | }
56 |
57 | void waitForReadyOfAllThread(std::atomic &running, const size_t thnm) {
58 | while (running.load(std::memory_order_acquire) != thnm) _mm_pause();
59 | }
60 |
61 | bool isReady(const std::vector &readys) {
62 | for (const char &b : readys) {
63 | if (!loadAcquire(b)) return false;
64 | }
65 | return true;
66 | }
67 |
68 | void waitForReady(const std::vector &readys) {
69 | while (!isReady(readys)) {
70 | _mm_pause();
71 | }
72 | }
73 |
74 | void sleepMs(size_t ms) {
75 | std::this_thread::sleep_for(std::chrono::milliseconds(ms));
76 | }
77 |
--------------------------------------------------------------------------------
/ermia/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | project(ccbench_ermia
4 | VERSION 0.0.1
5 | DESCRIPTION "ermia of ccbench"
6 | LANGUAGES CXX)
7 |
8 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
9 |
10 | option(ENABLE_SANITIZER "enable sanitizer on debug build" ON)
11 | option(ENABLE_UB_SANITIZER "enable undefined behavior sanitizer on debug build" OFF)
12 | option(ENABLE_COVERAGE "enable coverage on debug build" OFF)
13 |
14 | find_package(Doxygen)
15 | find_package(Threads REQUIRED)
16 | find_package(gflags REQUIRED)
17 | find_package(glog REQUIRED)
18 | find_package(Boost
19 | COMPONENTS filesystem)
20 |
21 | include(GNUInstallDirs)
22 | include(CMakePackageConfigHelpers)
23 | include(CompileOptions)
24 |
25 | file(GLOB ERMIA_SOURCES
26 | "../common/result.cc"
27 | "../common/util.cc"
28 | "ermia.cc"
29 | "garbage_collection.cc"
30 | "result.cc"
31 | "transaction.cc"
32 | "util.cc"
33 | )
34 |
35 | add_executable(ermia.exe ${ERMIA_SOURCES})
36 |
37 | target_link_libraries(ermia.exe
38 | Boost::filesystem
39 | gflags::gflags
40 | ${PROJECT_SOURCE_DIR}/../third_party/mimalloc/out/release/libmimalloc.a
41 | ${PROJECT_SOURCE_DIR}/../third_party/masstree/libkohler_masstree_json.a
42 | Threads::Threads
43 | )
44 |
45 | if (DEFINED ADD_ANALYSIS)
46 | add_definitions(-DADD_ANALYSIS=${ADD_ANALYSIS})
47 | else ()
48 | add_definitions(-DADD_ANALYSIS=0)
49 | endif ()
50 |
51 | if (DEFINED BACK_OFF)
52 | add_definitions(-DBACK_OFF=${BACK_OFF})
53 | else ()
54 | add_definitions(-DBACK_OFF=0)
55 | endif ()
56 |
57 | if (DEFINED KEY_SIZE)
58 | add_definitions(-DKEY_SIZE=${KEY_SIZE})
59 | else ()
60 | add_definitions(-DKEY_SIZE=8)
61 | endif ()
62 |
63 | if (DEFINED KEY_SORT)
64 | add_definitions(-DKEY_SORT=${KEY_SORT})
65 | else ()
66 | add_definitions(-DKEY_SORT=0)
67 | endif ()
68 |
69 | if (DEFINED MASSTREE_USE)
70 | add_definitions(-DMASSTREE_USE=${MASSTREE_USE})
71 | else ()
72 | add_definitions(-DMASSTREE_USE=1)
73 | endif ()
74 |
75 | if (DEFINED VAL_SIZE)
76 | add_definitions(-DVAL_SIZE=${VAL_SIZE})
77 | else ()
78 | add_definitions(-DVAL_SIZE=4)
79 | endif ()
80 |
--------------------------------------------------------------------------------
/ermia/README.md:
--------------------------------------------------------------------------------
1 | # ERMIA
2 | It was proposed at SIGMOD'2016 by Kangnyeon Kim.
3 | SSN is serialization certifier which has to be executed serial.
4 | Latch-free SSN was proposed at VLDB'2017 by Tianzheng Wang.
5 |
6 | ## How to use
7 | - Build masstree
8 | ```
9 | $ cd ../
10 | $ ./bootstrap.sh
11 | ```
12 | This makes ../third_party/masstree/libkohler_masstree_json.a used by building ermia.
13 | - Build mimalloc
14 | ```
15 | $ cd ../
16 | $ ./bootstrap_mimalloc.sh
17 | ```
18 | This makes ../third_party/mimalloc/out/release/libmimalloc.a used by building ermia.
19 | - Build
20 | ```
21 | $ mkdir build
22 | $ cd build
23 | $ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
24 | $ ninja
25 | ```
26 | - Confirm usage
27 | ```
28 | $ ./ermia.exe -help
29 | ```
30 | - Execution example
31 | ```
32 | $ numactl --interleave=all ./ermia.exe -tuple_num=1000 -max_ope=10 -thread_num=224 -rratio=100 -rmw=0 -zipf_skew=0 -ycsb=1 -clocks_per_us=2100 -gc_inter_us=10 -pre_reserve_version=10000 -pre_reserve_tmt_element=100 -extime=3
33 | ```
34 |
35 | ## How to customize options in CMakeLists.txt
36 | - `ADD_ANALYSIS` : If this is 1, it is deeper analysis than setting 0.
37 | default : `0`
38 | - `BACK_OFF` : If this is 1, it use Cicada's backoff.
39 | default : `0`
40 | - `KEY_SORT` : If this is 1, its transaction accesses records in ascending key order.
41 | default : `0`
42 | - `MASSTREE_USE` : If this is 1, it use masstree as data structure. If not, it use simple array αs data structure.
43 | default : `1`
44 | - `VAL_SIZE` : Value of key-value size. In other words, payload size.
45 | default : `4`
46 |
47 | ## Custom build examples
48 | ```
49 | $ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DKEY_SIZE=1000 -DVAL_SIZE=1000 ..
50 | ```
51 | - Note: If you re-run cmake, don't forget to remove cmake cache.
52 | ```
53 | $ rm CMakeCache.txt
54 | ```
55 | The cmake cache definition data is used in preference to the command line definition data.
56 |
57 | ## Optimizations
58 | - Backoff.
59 | - Early aborts.
60 | - Latch-free SSN.
61 | - Leveraging existing infrastructure.
62 | - Rapid garbage collection.
63 | - Reduce cache line contention about transaction mapping table.
64 | - Reuse version.
65 |
--------------------------------------------------------------------------------
/ermia/include/common.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "lock.hh"
7 | #include "transaction_table.hh"
8 | #include "tuple.hh"
9 |
10 | #include "../../include/cache_line_size.hh"
11 | #include "../../include/int64byte.hh"
12 | #include "../../include/masstree_wrapper.hh"
13 |
14 | #include "gflags/gflags.h"
15 | #include "glog/logging.h"
16 |
17 | #ifdef GLOBAL_VALUE_DEFINE
18 | #define GLOBAL
19 | GLOBAL std::atomic Lsn(0);
20 | #if MASSTREE_USE
21 | alignas(CACHE_LINE_SIZE) GLOBAL MasstreeWrapper MT;
22 | #endif
23 | #else
24 | #define GLOBAL extern
25 | GLOBAL std::atomic Lsn;
26 | #if MASSTREE_USE
27 | alignas(CACHE_LINE_SIZE) GLOBAL MasstreeWrapper MT;
28 | #endif
29 | #endif
30 |
31 | #ifdef GLOBAL_VALUE_DEFINE
32 | DEFINE_uint64(clocks_per_us, 2100, "CPU_MHz. Use this info for measuring time.");
33 | DEFINE_uint64(extime, 3, "Execution time[sec].");
34 | DEFINE_uint64(gc_inter_us, 10, "GC interval[us].");
35 | DEFINE_uint64(max_ope, 10,
36 | "Total number of operations per single transaction.");
37 | DEFINE_uint64(pre_reserve_tmt_element, 100, "Pre-allocating memory for the transaction mapping table elements.");
38 | DEFINE_uint64(pre_reserve_version, 10000, "Pre-allocating memory for the version.");
39 | DEFINE_bool(rmw, false,
40 | "True means read modify write, false means blind write.");
41 | DEFINE_uint64(rratio, 50, "read ratio of single transaction.");
42 | DEFINE_uint64(thread_num, 10, "Total number of worker threads.");
43 | DEFINE_uint64(tuple_num, 1000000, "Total number of records.");
44 | DEFINE_bool(ycsb, true,
45 | "True uses zipf_skew, false uses faster random generator.");
46 | DEFINE_double(zipf_skew, 0, "zipf skew. 0 ~ 0.999...");
47 | #else
48 | DECLARE_uint64(clocks_per_us);
49 | DECLARE_uint64(extime);
50 | DECLARE_uint64(gc_inter_us);
51 | DECLARE_uint64(max_ope);
52 | DECLARE_uint64(pre_reserve_tmt_element);
53 | DECLARE_uint64(pre_reserve_version);
54 | DECLARE_bool(rmw);
55 | DECLARE_uint64(rratio);
56 | DECLARE_uint64(thread_num);
57 | DECLARE_uint64(tuple_num);
58 | DECLARE_bool(ycsb);
59 | DECLARE_double(zipf_skew);
60 | #endif
61 |
62 |
63 | alignas(CACHE_LINE_SIZE) GLOBAL Tuple *Table;
64 | alignas(CACHE_LINE_SIZE) GLOBAL
65 | TransactionTable **TMT; // Transaction Mapping Table
66 |
67 | GLOBAL std::mutex SsnLock;
68 |
--------------------------------------------------------------------------------
/ermia/include/ermia_op_element.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../../include/op_element.hh"
4 |
5 | #include "version.hh"
6 |
7 | template
8 | class SetElement : public OpElement {
9 | public:
10 | using OpElement::OpElement;
11 |
12 | Version *ver_;
13 |
14 | SetElement(uint64_t key, T *rcdptr, Version *ver)
15 | : OpElement::OpElement(key, rcdptr) {
16 | this->ver_ = ver;
17 | }
18 |
19 | bool operator<(const SetElement &right) const {
20 | return this->key_ < right.key_;
21 | }
22 | };
23 |
24 | template
25 | class GCElement : public OpElement {
26 | public:
27 | using OpElement::OpElement;
28 |
29 | Version *ver_;
30 | uint32_t cstamp_;
31 |
32 | GCElement(uint64_t key, T *rcdptr, Version *ver, uint32_t cstamp)
33 | : OpElement::OpElement(key, rcdptr) {
34 | this->ver_ = ver;
35 | this->cstamp_ = cstamp;
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/ermia/include/garbage_collection.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "../../include/inline.hh"
7 | #include "../../include/op_element.hh"
8 |
9 | #include "ermia_op_element.hh"
10 | #include "tuple.hh"
11 | #include "version.hh"
12 |
13 | // forward declaration
14 | class TransactionTable;
15 |
16 | class GarbageCollection {
17 | private:
18 | uint32_t fmin_, fmax_; // first range of txid in TMT.
19 | uint32_t smin_, smax_; // second range of txid in TMT.
20 | static std::atomic
21 | GC_threshold_; // share for all object (meaning all thread).
22 |
23 | public:
24 | std::deque gcq_for_TMT_;
25 | std::deque reuse_TMT_element_from_gc_;
26 | std::deque > gcq_for_version_;
27 | std::deque reuse_version_from_gc_;
28 | uint8_t thid_;
29 |
30 | GarbageCollection() {}
31 |
32 | GarbageCollection(uint8_t thid) : thid_(thid) {}
33 |
34 | void set_thid_(uint8_t thid) { thid_ = thid; }
35 |
36 | // for all thread
37 | INLINE uint32_t getGcThreshold() {
38 | return GC_threshold_.load(std::memory_order_acquire);
39 | }
40 | // -----
41 |
42 | // for leader thread
43 | bool chkSecondRange();
44 |
45 | void decideFirstRange();
46 |
47 | INLINE void decideGcThreshold() {
48 | GC_threshold_.store(fmin_, std::memory_order_release);
49 | }
50 |
51 | INLINE void mvSecondRangeToFirstRange() {
52 | fmin_ = smin_;
53 | fmax_ = smax_;
54 | }
55 | // -----
56 |
57 | // for worker thread
58 | void gcVersion(Result *eres_);
59 |
60 | void gcTMTelement(Result *eres_);
61 | // -----
62 | };
63 |
64 | #ifdef GLOBAL_VALUE_DEFINE
65 | // declare in ermia.cc
66 | std::atomic GarbageCollection::GC_threshold_(0);
67 | #endif
68 |
--------------------------------------------------------------------------------
/ermia/include/lock.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | using namespace std;
7 |
8 | class RWLock {
9 | public:
10 | std::atomic counter;
11 | // counter == -1, write locked;
12 | // counter == 0, not locked;
13 | // counter > 0, there are $counter readers who acquires read-lock.
14 |
15 | RWLock() { counter.store(0, std::memory_order_release); }
16 |
17 | // Read lock
18 | void r_lock() {
19 | int expected, desired;
20 | for (;;) {
21 | expected = counter.load(std::memory_order_acquire);
22 | RETRY_R_LOCK:
23 | if (expected != -1)
24 | desired = expected + 1;
25 | else {
26 | continue;
27 | }
28 | if (counter.compare_exchange_strong(
29 | expected, desired, memory_order_acq_rel, memory_order_acquire))
30 | break;
31 | else
32 | goto RETRY_R_LOCK;
33 | }
34 | }
35 |
36 | void r_unlock() { counter--; }
37 |
38 | // Write lock
39 | void w_lock() {
40 | int expected;
41 | for (;;) {
42 | expected = counter.load(memory_order_acquire);
43 | RETRY_W_LOCK:
44 | if (expected != 0) continue;
45 | if (counter.compare_exchange_strong(expected, -1, memory_order_acq_rel,
46 | memory_order_acquire))
47 | break;
48 | else
49 | goto RETRY_W_LOCK;
50 | }
51 | }
52 |
53 | void w_unlock() { counter++; }
54 |
55 | // Upgrae, read -> write
56 | void upgrade() {
57 | int one = 1;
58 | while (!counter.compare_exchange_strong(one, -1, memory_order_acq_rel,
59 | memory_order_acquire)) {
60 | }
61 | }
62 | };
63 |
--------------------------------------------------------------------------------
/ermia/include/result.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/result.hh"
6 |
7 | extern std::vector ErmiaResult;
8 |
9 | extern void initResult();
10 |
--------------------------------------------------------------------------------
/ermia/include/transaction_status.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | enum class TransactionStatus : uint8_t {
6 | inFlight,
7 | committing,
8 | committed,
9 | aborted,
10 | };
11 |
--------------------------------------------------------------------------------
/ermia/include/transaction_table.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "transaction_status.hh"
7 |
8 | class TransactionTable {
9 | public:
10 | alignas(CACHE_LINE_SIZE) std::atomic txid_;
11 | std::atomic cstamp_;
12 | std::atomic sstamp_;
13 | std::atomic lastcstamp_;
14 | std::atomic status_;
15 |
16 | TransactionTable() {}
17 |
18 | TransactionTable(uint32_t txid, uint32_t cstamp, uint32_t sstamp,
19 | uint32_t lastcstamp, TransactionStatus status) {
20 | this->txid_.store(txid, memory_order_relaxed);
21 | this->cstamp_.store(cstamp, memory_order_relaxed);
22 | this->sstamp_.store(sstamp, memory_order_relaxed);
23 | this->lastcstamp_.store(lastcstamp, memory_order_relaxed);
24 | this->status_.store(status, memory_order_relaxed);
25 | }
26 |
27 | void set(uint32_t txid, uint32_t cstamp, uint32_t sstamp, uint32_t lastcstamp,
28 | TransactionStatus status) {
29 | this->txid_.store(txid, memory_order_relaxed);
30 | this->cstamp_.store(cstamp, memory_order_relaxed);
31 | this->sstamp_.store(sstamp, memory_order_relaxed);
32 | this->lastcstamp_.store(lastcstamp, memory_order_relaxed);
33 | this->status_.store(status, memory_order_relaxed);
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/ermia/include/tuple.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "../../include/cache_line_size.hh"
7 | #include "version.hh"
8 |
9 | class Tuple {
10 | public:
11 | alignas(CACHE_LINE_SIZE) std::atomic latest_;
12 | std::atomic min_cstamp_;
13 | std::atomic gc_lock_;
14 |
15 | Tuple() {
16 | latest_.store(nullptr);
17 | gc_lock_.store(0, std::memory_order_release);
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/ermia/include/util.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "garbage_collection.hh"
4 |
5 | extern void chkArg();
6 |
7 | extern void displayDB();
8 |
9 | extern void displayParameter();
10 |
11 | extern void leaderWork(GarbageCollection &gcob);
12 |
13 | extern void makeDB();
14 |
15 | extern void naiveGarbageCollection(const bool &quit);
16 |
17 | extern void partTableInit([[maybe_unused]] size_t thid, uint64_t start,
18 | uint64_t end);
19 |
20 | extern void ShowOptParameters();
21 |
--------------------------------------------------------------------------------
/ermia/result.cc:
--------------------------------------------------------------------------------
1 | #include "include/result.hh"
2 | #include "include/common.hh"
3 |
4 | #include "../include/cache_line_size.hh"
5 | #include "../include/result.hh"
6 |
7 | using namespace std;
8 |
9 | alignas(CACHE_LINE_SIZE) std::vector ErmiaResult;
10 |
11 | void initResult() { ErmiaResult.resize(FLAGS_thread_num); }
12 |
--------------------------------------------------------------------------------
/ermia/script/test_cache_ana.sh:
--------------------------------------------------------------------------------
1 | #test_cache_ana.sh(ermia)
2 | tuple=1000000
3 | maxope=10
4 | thread=24
5 | cpu_mhz=2400
6 | extime=3
7 | epoch=5
8 |
9 | rratio=0
10 | result=result_ermia_r0-10_cache-references.dat
11 | result2=result_ermia_r0-10_cache-misses.dat
12 | rm $result
13 | rm $result2
14 | echo "#rratio, cache-references, min, max" >> $result
15 | echo "#rratio, cache-misses, min, max" >> $result2
16 | echo "#./ermia.exe $tuple $maxope $thread $rratio $cpu_mhz $extime" >> $result
17 | echo "#./ermia.exe $tuple $maxope $thread $rratio $cpu_mhz $extime" >> $result2
18 |
19 | for ((rratio=0; rratio <= 10; ++rratio))
20 | do
21 | echo "./ermia.exe $tuple $maxope $thread $rratio $cpu_mhz $extime"
22 | sum=0
23 | max=0
24 | min=0
25 | sum2=0
26 | max2=0
27 | min2=0
28 | for ((i = 1; i <= epoch; ++i))
29 | do
30 | perf stat -e cache-references,cache-misses -o ermia_cache_ana.txt ./ermia.exe $tuple $maxope $thread $rratio $cpu_mhz $extime
31 | tmp=`grep cache-references ./ermia_cache_ana.txt | awk '{print $1}' | tr -d ,`
32 | tmp2=`grep cache-misses ./ermia_cache_ana.txt | awk '{print $1}' | tr -d ,`
33 | sum=`echo "$sum + $tmp" | bc -l`
34 | sum2=`echo "$sum2 + $tmp2" | bc -l`
35 | echo "sum: $sum, tmp: $tmp"
36 | echo "sum2: $sum2, tmp2: $tmp2"
37 |
38 | if test $i -eq 1 ; then
39 | max=$tmp
40 | min=$tmp
41 | max2=$tmp2
42 | min2=$tmp2
43 | fi
44 |
45 | flag=`echo "$tmp > $max" | bc -l`
46 | if test $flag -eq 1 ; then
47 | max=$tmp
48 | fi
49 |
50 | flag=`echo "$tmp < $min" | bc -l`
51 | if test $flag -eq 1 ; then
52 | min=$tmp
53 | fi
54 | flag=`echo "$tmp2 > $max2" | bc -l`
55 | if test $flag -eq 1 ; then
56 | max2=$tmp2
57 | fi
58 |
59 | flag=`echo "$tmp2 < $min2" | bc -l`
60 | if test $flag -eq 1 ; then
61 | min2=$tmp2
62 | fi
63 | done
64 |
65 | avg=`echo "$sum / $epoch" | bc -l`
66 | avg2=`echo "$sum2 / $epoch" | bc -l`
67 | echo "sum: $sum, epoch: $epoch"
68 | echo "sum2: $sum2, epoch: $epoch"
69 | echo "avg $avg"
70 | echo "avg2 $avg2"
71 | echo "max: $max"
72 | echo "max2: $max2"
73 | echo "min: $min"
74 | echo "min2: $min2"
75 | echo "$rratio $avg $min $max" >> $result
76 | echo "$rratio $avg2 $min2 $max2" >> $result2
77 | done
78 |
--------------------------------------------------------------------------------
/ermia/script/ycsbA-xgcidbsize-cache.sh:
--------------------------------------------------------------------------------
1 | #ycsbA-xgcidbsize.sh(ermia)
2 | maxope=10
3 | thread=24
4 | rratio=50
5 | skew=0
6 | ycsb=ON
7 | cpu_mhz=2400
8 | extime=3
9 | epoch=5
10 |
11 | result=result_ermia_ycsbA_tuple100-10m_gci1us-100ms_cache-miss.dat
12 | rm $result
13 | echo "#tuple num, gci, throughput, min, max" >> $result
14 | for ((tuple=100; tuple<=10000000; tuple*=10))
15 | do
16 | for ((gci=1; gci<=100000; gci*=10))
17 | do
18 | sum=0
19 | echo "./ermia.exe $tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $gci $extime"
20 | echo "$tuple $epoch"
21 |
22 | max=0
23 | min=0
24 | for ((i = 1; i <= epoch; ++i))
25 | do
26 | perf stat -e cache-misses,cache-references -o ermia-cache-ana.txt ./ermia.exe $tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $gci $extime
27 | tmp=`grep cache-misses ./ermia-cache-ana.txt | awk '{print $4}'`
28 | sum=`echo "$sum + $tmp" | bc -l`
29 | echo "sum: $sum, tmp: $tmp"
30 |
31 | if test $i -eq 1 ; then
32 | max=$tmp
33 | min=$tmp
34 | fi
35 |
36 | flag=`echo "$tmp > $max" | bc -l`
37 | if test $flag -eq 1 ; then
38 | max=$tmp
39 | fi
40 | flag=`echo "$tmp < $min" | bc -l`
41 | if test $flag -eq 1 ; then
42 | min=$tmp
43 | fi
44 | done
45 |
46 | avg=`echo "$sum / $epoch" | bc -l`
47 | echo "sum: $sum, epoch: $epoch"
48 | echo "avg $avg"
49 | echo "max: $max"
50 | echo "min: $min"
51 | echo "$tuple $gci $avg $min $max" >> $result
52 | done
53 | echo "" >> $result
54 | done
55 |
--------------------------------------------------------------------------------
/ermia/script/ycsbA-xgcidbsize.sh:
--------------------------------------------------------------------------------
1 | #ycsbA-xgcidbsize.sh(ermia)
2 | maxope=10
3 | thread=24
4 | rratio=50
5 | skew=0
6 | ycsb=ON
7 | cpu_mhz=2400
8 | extime=3
9 | epoch=5
10 |
11 | result=result_ermia_ycsbA_tuple100-10m_gci1us-100ms_ar.dat
12 | rm $result
13 | echo "#tuple num, gci, throughput, min, max" >> $result
14 | for ((tuple=100; tuple<=10000000; tuple*=10))
15 | do
16 | for ((gci=1; gci<=100000; gci*=10))
17 | do
18 | sum=0
19 | echo "./ermia.exe $tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $gci $extime"
20 | echo "$tuple $epoch"
21 |
22 | max=0
23 | min=0
24 | for ((i = 1; i <= epoch; ++i))
25 | do
26 | tmp=`./ermia.exe $tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $gci $extime`
27 | sum=`echo "$sum + $tmp" | bc -l`
28 | echo "sum: $sum, tmp: $tmp"
29 |
30 | if test $i -eq 1 ; then
31 | max=$tmp
32 | min=$tmp
33 | fi
34 |
35 | flag=`echo "$tmp > $max" | bc -l`
36 | if test $flag -eq 1 ; then
37 | max=$tmp
38 | fi
39 | flag=`echo "$tmp < $min" | bc -l`
40 | if test $flag -eq 1 ; then
41 | min=$tmp
42 | fi
43 | done
44 | avg=`echo "$sum / $epoch" | bc -l`
45 | echo "sum: $sum, epoch: $epoch"
46 | echo "avg $avg"
47 | echo "max: $max"
48 | echo "min: $min"
49 | echo "$tuple $gci $avg $min $max" >> $result
50 | done
51 | echo "" >> $result
52 | done
53 |
--------------------------------------------------------------------------------
/ermia/script/ycsbA-xrs-cache.sh:
--------------------------------------------------------------------------------
1 | #ycsbA-xrs-cache.sh(ermia)
2 | maxope=10
3 | thread=24
4 | rratio=50
5 | skew=0
6 | ycsb=ON
7 | cpu_mhz=2400
8 | extime=3
9 | epoch=5
10 |
11 | result=result_ermia_ycsbA_tuple100-10m_cachemiss.dat
12 | rm $result
13 | echo "#tuple num, cache-misses, min, max" >> $result
14 | echo "#./ermia.exe tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $extime" >> $result
15 |
16 | for ((tuple=100; tuple<=10000000; tuple*=10))
17 | do
18 | sum=0
19 | echo "./ermia.exe $tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $extime"
20 | echo "$tuple $epoch"
21 |
22 | max=0
23 | min=0
24 | for ((i = 1; i <= epoch; ++i))
25 | do
26 | perf stat -e cache-misses,cache-references -o ermia-cache-ana.txt ./ermia.exe $tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $extime
27 | tmp=`grep cache-misses ./ermia-cache-ana.txt | awk '{print $4}'`
28 | sum=`echo "$sum + $tmp" | bc -l`
29 | echo "sum: $sum, tmp: $tmp"
30 |
31 | if test $i -eq 1 ; then
32 | max=$tmp
33 | min=$tmp
34 | fi
35 |
36 | flag=`echo "$tmp > $max" | bc -l`
37 | if test $flag -eq 1 ; then
38 | max=$tmp
39 | fi
40 | flag=`echo "$tmp < $min" | bc -l`
41 | if test $flag -eq 1 ; then
42 | min=$tmp
43 | fi
44 | done
45 | avg=`echo "$sum / $epoch" | bc -l`
46 | echo "sum: $sum, epoch: $epoch"
47 | echo "avg $avg"
48 | echo "max: $max"
49 | echo "min: $min"
50 | echo "$tuple $avg $min $max" >> $result
51 | done
52 |
53 |
--------------------------------------------------------------------------------
/include/Makefile:
--------------------------------------------------------------------------------
1 | INCLUDE_ALLSRC = $(wildcard *.hh)
2 |
3 | format:
4 | clang-format -i -verbose -style=Google $(INCLUDE_ALLSRC)
5 |
--------------------------------------------------------------------------------
/include/atomic_wrapper.hh:
--------------------------------------------------------------------------------
1 | /**
2 | * This file was created with reference to the following URL.
3 | * Special thanks to Mr. Hoshino.
4 | * https://github.com/starpos/oltp-cc-bench/blob/master/include/atomic_wrapper.hpp
5 | */
6 |
7 | #pragma once
8 |
9 | template
10 | T load(T &ptr) {
11 | return __atomic_load_n(&ptr, __ATOMIC_RELAXED);
12 | }
13 |
14 | template
15 | T loadAcquire(T &ptr) {
16 | return __atomic_load_n(&ptr, __ATOMIC_ACQUIRE);
17 | }
18 |
19 | template
20 | void store(T &ptr, T2 val) {
21 | __atomic_store_n(&ptr, (T) val, __ATOMIC_RELAXED);
22 | }
23 |
24 | template
25 | void storeRelease(T &ptr, T2 val) {
26 | __atomic_store_n(&ptr, (T) val, __ATOMIC_RELEASE);
27 | }
28 |
29 | template
30 | bool compareExchange(T &m, T &before, T2 after) {
31 | return __atomic_compare_exchange_n(&m, &before, (T) after, false,
32 | __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
33 | }
34 |
--------------------------------------------------------------------------------
/include/cache_line_size.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #define CACHE_LINE_SIZE 64
6 |
--------------------------------------------------------------------------------
/include/check.hh:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 |
5 | #include
6 |
7 | static bool chkInt(const char *arg) {
8 | for (uint i = 0; i < strlen(arg); ++i) {
9 | if (!isdigit(arg[i])) {
10 | std::cout << std::string(arg) << " is not a number." << std::endl;
11 | exit(0);
12 | }
13 | }
14 |
15 | return true;
16 | }
17 |
--------------------------------------------------------------------------------
/include/compiler.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define likely(x) __builtin_expect(!!(x), 1)
4 | #define unlikely(x) __builtin_expect(!!(x), 0)
5 |
--------------------------------------------------------------------------------
/include/config.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define PAGE_SIZE 4096
4 |
--------------------------------------------------------------------------------
/include/cpu.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "debug.hh"
9 |
10 | #define CPUID(INFO, LEAF, SUBLEAF) \
11 | __cpuid_count(LEAF, SUBLEAF, INFO[0], INFO[1], INFO[2], INFO[3])
12 |
13 | #define GETCPU(CPU) \
14 | { \
15 | uint32_t CPUInfo[4]; \
16 | CPUID(CPUInfo, 1, 0); \
17 | /* CPUInfo[1] is EBX, bits 24-31 are APIC ID */ \
18 | if ((CPUInfo[3] & (1 << 9)) == 0) { \
19 | CPU = -1; /* no APIC on chip */ \
20 | } else { \
21 | CPU = (unsigned)CPUInfo[1] >> 24; \
22 | /*unsigned int cores = ((unsigned)CPUInfo[1] >> 16) & 0xff;*/ \
23 | /*if ((CPUInfo[3] & (1 << 28)) == 1) printf("HTT\n");*/ \
24 | /*printf("total core number : %d\n", cores);*/ \
25 | } \
26 | if (CPU < 0) CPU = 0; \
27 | }
28 |
29 | #ifdef Linux
30 | static void setThreadAffinity(const int myid) {
31 | pid_t pid = syscall(SYS_gettid);
32 | cpu_set_t cpu_set;
33 |
34 | CPU_ZERO(&cpu_set);
35 | CPU_SET(myid % sysconf(_SC_NPROCESSORS_CONF), &cpu_set);
36 |
37 | if (sched_setaffinity(pid, sizeof(cpu_set_t), &cpu_set) != 0) ERR;
38 |
39 | // printf("thread affinity (id==%d) [ok]\n", myid);
40 | return;
41 | }
42 | #endif // Linux
43 |
--------------------------------------------------------------------------------
/include/delay.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 |
7 | #include "tsc.hh"
8 |
9 | using namespace std;
10 |
11 | [[maybe_unused]] static void
12 | clock_delay(size_t clocks) {
13 | std::size_t start(rdtscp()), stop;
14 |
15 | for (;;) {
16 | stop = rdtscp();
17 | if (stop - start > clocks) {
18 | break;
19 | } else {
20 | _mm_pause();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/include/fence.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "inline.hh"
4 |
5 | INLINE void compilerFence() { asm volatile("":: : "memory"); }
6 |
--------------------------------------------------------------------------------
/include/inline.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define INLINE __attribute__((always_inline)) inline
4 |
--------------------------------------------------------------------------------
/include/int64byte.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "./cache_line_size.hh"
6 |
7 | class uint64_t_64byte {
8 | public:
9 | alignas(CACHE_LINE_SIZE) uint64_t obj_;
10 |
11 | uint64_t_64byte() : obj_(0) {}
12 |
13 | uint64_t_64byte(uint64_t initial) : obj_(initial) {}
14 | };
15 |
--------------------------------------------------------------------------------
/include/logger.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by thawk on 2020/11/10.
3 | //
4 |
5 | #pragma once
6 |
7 | #ifdef NDEBUG
8 | #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
9 | #else
10 | #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG // NOLINT
11 | #endif
12 |
13 | #include "spdlog/spdlog.h"
14 |
15 | namespace ccbench {
16 |
17 | static inline void setup_spdlog() {
18 |
19 | #ifdef NDEBUG
20 | spdlog::set_level(spdlog::level::info);
21 | #else
22 | spdlog::set_level(spdlog::level::debug);
23 | #endif
24 |
25 | }
26 |
27 | } // namespace ccbench
28 |
--------------------------------------------------------------------------------
/include/op_element.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "debug.hh"
4 |
5 | template
6 | class OpElement {
7 | public:
8 | uint64_t key_;
9 | T *rcdptr_;
10 |
11 | OpElement() : key_(0), rcdptr_(nullptr) {}
12 |
13 | OpElement(uint64_t key) : key_(key) {}
14 |
15 | OpElement(uint64_t key, T *rcdptr) : key_(key), rcdptr_(rcdptr) {}
16 | };
17 |
--------------------------------------------------------------------------------
/include/procedure.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | using std::cout;
6 | using std::endl;
7 |
8 | enum class Ope : uint8_t {
9 | READ,
10 | WRITE,
11 | READ_MODIFY_WRITE,
12 | };
13 |
14 | class Procedure {
15 | public:
16 | Ope ope_;
17 | uint64_t key_;
18 | bool ronly_ = false;
19 | bool wonly_ = false;
20 |
21 | Procedure() : ope_(Ope::READ), key_(0) {}
22 |
23 | Procedure(Ope ope, uint64_t key) : ope_(ope), key_(key) {}
24 |
25 | bool operator<(const Procedure &right) const {
26 | if (this->key_ == right.key_ && this->ope_ == Ope::WRITE &&
27 | right.ope_ == Ope::READ) {
28 | return true;
29 | } else if (this->key_ == right.key_ && this->ope_ == Ope::WRITE &&
30 | right.ope_ == Ope::WRITE) {
31 | return true;
32 | }
33 | /* キーが同値なら先に write ope を実行したい.read -> write よりも write ->
34 | * read.
35 | * キーが同値で自分が read でここまで来たら,下記の式によって絶対に false
36 | * となり,自分 (read) が昇順で後ろ回しになるので ok */
37 |
38 | return this->key_ < right.key_;
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/include/string.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "debug.hh"
4 | #include "fence.hh"
5 |
6 | using std::cout;
7 | using std::endl;
8 |
9 | [[maybe_unused]] static void genStringRepeatedNumber(char *string, size_t val_size,
10 | size_t thid) {
11 | size_t digit(1), thidnum(thid);
12 | for (;;) {
13 | thidnum /= 10;
14 | if (thidnum != 0)
15 | ++digit;
16 | else
17 | break;
18 | }
19 |
20 | // generate write value for this thread.
21 | sprintf(string, "%ld", thid);
22 | for (uint i = digit; i < val_size - 2; ++i) {
23 | string[i] = '0';
24 | }
25 | // printf("%s\n", string);
26 | }
27 |
--------------------------------------------------------------------------------
/include/tsc.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | [[maybe_unused]] static uint64_t
6 | rdtsc() {
7 | uint64_t rax;
8 | uint64_t rdx;
9 |
10 | asm volatile("rdtsc" : "=a"(rax), "=d"(rdx));
11 | // store higher bits to rdx, lower bits to rax.
12 | // シリアライズ命令でないため,全ての先行命令を待機せずに
13 | // カウンタ値を読み込む.同様に後続命令が読み取り命令を追い越すことを許容する.
14 |
15 | return (rdx << 32) | rax;
16 | }
17 |
18 | [[maybe_unused]] static uint64_t
19 | rdtsc_serial() {
20 | uint64_t rax;
21 | uint64_t rdx;
22 |
23 | asm volatile("cpuid":: : "rax", "rbx", "rcx", "rdx");
24 | asm volatile("rdtsc" : "=a"(rax), "=d"(rdx));
25 |
26 | return (rdx << 32) | rax;
27 | }
28 |
29 | [[maybe_unused]] static uint64_t
30 | rdtscp() {
31 | uint64_t rax;
32 | uint64_t rdx;
33 | uint32_t aux;
34 | asm volatile("rdtscp" : "=a"(rax), "=d"(rdx), "=c"(aux)::);
35 | // store EDX:EAX.
36 | // 全ての先行命令を待機してからカウンタ値を読み取る.ただし,後続命令は
37 | // 同読み取り操作を追い越す可能性がある.
38 |
39 | return (rdx << 32) | rax;
40 | }
41 |
--------------------------------------------------------------------------------
/include/zipf.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "inline.hh"
11 | #include "random.hh"
12 |
13 | using std::cout;
14 | using std::endl;
15 |
16 | // Fast zipf distribution by Jim Gray et al.
17 | class FastZipf {
18 | Xoroshiro128Plus *rnd_;
19 | const size_t nr_;
20 | const double alpha_, zetan_, eta_;
21 | const double threshold_;
22 |
23 | public:
24 | FastZipf(Xoroshiro128Plus *rnd, double theta, size_t nr)
25 | : rnd_(rnd),
26 | nr_(nr),
27 | alpha_(1.0 / (1.0 - theta)),
28 | zetan_(zeta(nr, theta)),
29 | eta_((1.0 - std::pow(2.0 / (double) nr, 1.0 - theta)) /
30 | (1.0 - zeta(2, theta) / zetan_)),
31 | threshold_(1.0 + std::pow(0.5, theta)) {
32 | assert(0.0 <= theta);
33 | assert(theta < 1.0); // 1.0 can not be specified.
34 | }
35 |
36 | // Use this constructor if zeta is pre-calculated.
37 | FastZipf(Xoroshiro128Plus *rnd, double theta, size_t nr, double zetan)
38 | : rnd_(rnd),
39 | nr_(nr),
40 | alpha_(1.0 / (1.0 - theta)),
41 | zetan_(zetan),
42 | eta_((1.0 - std::pow(2.0 / (double) nr, 1.0 - theta)) /
43 | (1.0 - zeta(2, theta) / zetan_)),
44 | threshold_(1.0 + std::pow(0.5, theta)) {
45 | assert(0.0 <= theta);
46 | assert(theta < 1.0); // 1.0 can not be specified.
47 | }
48 |
49 | INLINE size_t operator()() {
50 | double u = rnd_->next() / (double) UINT64_MAX;
51 | double uz = u * zetan_;
52 | if (uz < 1.0) return 0;
53 | if (uz < threshold_) return 1;
54 | return (size_t)((double) nr_ * std::pow(eta_ * u - eta_ + 1.0, alpha_));
55 | }
56 |
57 | uint64_t rand() { return rnd_->next(); }
58 |
59 | static double zeta(size_t nr, double theta) {
60 | double ans = 0.0;
61 | for (size_t i = 0; i < nr; ++i)
62 | ans += std::pow(1.0 / (double) (i + 1), theta);
63 | return ans;
64 | }
65 | };
66 |
--------------------------------------------------------------------------------
/instruction/Makefile:
--------------------------------------------------------------------------------
1 | PROG1 = fetch_add
2 | INST_SRCS1 = fetch_add.cc
3 |
4 | PROG2 = cache-test
5 | INST_SRCS2 = cache-test.cc
6 |
7 | PROG3 = membench
8 | INST_SRCS3 = membench.cc
9 |
10 | PROG4 = rdtscBench
11 | INST_SRCS4 = rdtscBench.cc
12 |
13 | PROG5 = xoroshiro
14 | INST_SRCS5 = xoroshiro.cc
15 |
16 | REL := ../common/
17 | include $(REL)Makefile
18 |
19 | CC = g++
20 | CFLAGS = -c -pipe -g -O3 -std=c++17 -march=native \
21 | -Wall -Wextra -Wchkp -Winvalid-memory-model -Wdangling-else \
22 | -D$(shell uname) \
23 | -D$(shell hostname) \
24 |
25 | ifeq ($(shell hostname), chris41.omni.hpcc.jp)
26 | LDFLAGS = -L/home/tanabe/package/tbb/build/linux_intel64_gcc_cc7.1.0_libc2.12_kernel2.6.32_release
27 | endif
28 | ifeq ($(shell hostname), dbs11)
29 | LDFLAGS = -L/home/tanabe/package/tbb/build/linux_intel64_gcc_cc7_libc2.27_kernel4.15.0_release
30 | endif
31 |
32 | LIBS = -lpthread -ltbbmalloc_proxy -ltbbmalloc
33 | ifneq ($(shell hostname), chris41.omni.hpcc.jp)
34 | ifneq ($(shell hostname), dbs11)
35 | LIBS = -lpthread
36 | endif
37 | endif
38 |
39 | OBJS1 = $(INST_SRCS1:.cc=.o)
40 | OBJS2 = $(INST_SRCS2:.cc=.o)
41 | OBJS3 = $(INST_SRCS3:.cc=.o)
42 | OBJS4 = $(INST_SRCS4:.cc=.o)
43 | OBJS5 = $(INST_SRCS5:.cc=.o)
44 |
45 | all: $(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5)
46 |
47 | $(PROG1) : $(OBJS1) ../common/util.o
48 | $(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
49 |
50 | $(PROG2) : $(OBJS2)
51 | $(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
52 |
53 | $(PROG3) : $(OBJS3)
54 | $(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
55 |
56 | $(PROG4) : $(OBJS4)
57 | $(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
58 |
59 | $(PROG5) : $(OBJS5)
60 | $(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
61 |
62 | .cc.o:
63 | $(CC) $(CFLAGS) -c $< -o $@
64 |
65 | format:
66 | clang-format -i -verbose -style=Google $(wildcard *.cc)
67 |
68 | clean:
69 | rm -f *~ *.o *.exe *.stackdump
70 | rm -f ../common/*~ ../common/*.o ../common/*.exe ../common/*.stackdump
71 |
--------------------------------------------------------------------------------
/instruction/README.md:
--------------------------------------------------------------------------------
1 | # Instruction Survey
2 |
3 | ## fetch\_add
4 | ## xoroshiro128+
5 | ## memory benchmark
6 | ## masstree unit test
7 |
--------------------------------------------------------------------------------
/instruction/include/common.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include "../../include/int64byte.hh"
8 |
9 | #ifdef GLOBAL_VALUE_DEFINE
10 | #define GLOBAL
11 | GLOBAL std::atomic Running(0);
12 | GLOBAL std::atomic Counter(0);
13 | GLOBAL std::atomic Finish(false);
14 |
15 | #else
16 | #define GLOBAL extern
17 | GLOBAL std::atomic Running;
18 | GLOBAL std::atomic Counter;
19 | GLOBAL std::atomic Finish;
20 |
21 | #endif
22 |
23 | //run-time args
24 | GLOBAL unsigned int THREAD_NUM;
25 | GLOBAL uint64_t CLOCK_PER_US;
26 | GLOBAL unsigned int EXTIME;
27 |
28 | GLOBAL uint64_t_64byte *CounterIncrements;
29 |
30 | GLOBAL uint64_t Bgn;
31 | GLOBAL uint64_t End;
32 |
33 |
--------------------------------------------------------------------------------
/instruction/masstree_simple_test/GNUmakefile:
--------------------------------------------------------------------------------
1 | AR = ar
2 | CC = gcc
3 | CXX = g++
4 | CPPFLAGS =
5 | CXXFLAGS = -g -W -Wall -O2 -pipe
6 | CXXFLAGS += -march=native
7 |
8 | DEPSDIR := .deps
9 | DEPCFLAGS = #-MD -MF $(DEPSDIR)/$*.d -MP
10 | ifeq ($(strip $(MEMMGR)), )
11 | MEMMGR =
12 | endif
13 | ifneq ($(strip $(KEYSWAP)), )
14 | CPPFLAGS += -DKEYSWAP
15 | endif
16 | ifneq ($(strip $(NOPREFETCH)), )
17 | CPPFLAGS += -DNOPREFETCH
18 | endif
19 | ifneq ($(strip $(NOSUPERPAGE)), )
20 | CPPFLAGS += -DNOSUPERPAGE
21 | endif
22 |
23 | LIBS = -lnuma -lpthread -lm
24 | ifeq (0, 0) # for easy switch
25 | ifeq ($(shell hostname), dbs11)
26 | LIBS += -ltbb -ltbbmalloc_proxy -ltbbmalloc
27 | endif
28 | endif
29 |
30 | DEFINE =
31 | ifeq ($(shell hostname), dbs11)
32 | DEFINE += -Ddbs11
33 | endif
34 |
35 | INCLUDE =
36 | ifeq ($(shell hostname), dbs11)
37 | INCLUDE += -I/home/tanabe/package/tbb/include/tbb
38 | endif
39 |
40 | LDFLAGS =
41 | ifeq ($(shell hostname), dbs11)
42 | LDFLAGS += -L/home/tanabe/package/tbb/build/linux_intel64_gcc_cc7_libc2.27_kernel4.15.0_release
43 | endif
44 |
45 | all: unit-mt unit-mt2
46 |
47 | %.o: %.c ../../masstree/config.h #$(DEPSDIR)/stamp
48 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEPCFLAGS) $(INCLUDE) $(DEFINE) -c -o $@ $<
49 |
50 | %.o: %.cc ../../masstree/config.h #$(DEPSDIR)/stamp
51 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(DEPCFLAGS) $(INCLUDE) $(DEFINE) -c -o $@ $<
52 |
53 | %.S: %.o
54 | objdump -S $< > $@
55 |
56 | ../../masstree/libjson.a: ../../masstree/json.o ../../masstree/string.o ../../masstree/straccum.o ../../masstree/str.o ../../masstree/msgpack.o \
57 | ../../masstree/clp.o ../../masstree/kvrandom.o ../../masstree/compiler.o ../../masstree/memdebug.o ../../masstree/kvthread.o
58 | @/bin/rm -f $@
59 | $(AR) cru $@ $^
60 |
61 | unit-mt: unit-mt.o ../../masstree/compiler.o ../../masstree/misc.o ../../masstree/libjson.a ../../common/util.o
62 | $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)
63 |
64 | unit-mt2: unit-mt2.o ../../masstree/compiler.o ../../masstree/misc.o ../../masstree/libjson.a ../../common/util.o
65 | $(CXX) $(CXXFLAGS) -o $@ $^ $(MEMMGR) $(LDFLAGS) $(LIBS)
66 |
67 | $(DEPSDIR)/stamp:
68 | mkdir -p $(DEPSDIR)
69 | touch $@
70 |
71 | clean:
72 | rm -f mtd mtclient mttest test_string test_atomics *.o libjson.a
73 | rm -rf .deps
74 | rm -f ../../common/*.o
75 |
76 | DEPFILES := $(wildcard $(DEPSDIR)/*.d)
77 | ifneq ($(DEPFILES),)
78 | include $(DEPFILES)
79 | endif
80 |
81 | .PHONY: clean all
82 |
--------------------------------------------------------------------------------
/instruction/masstree_simple_test/script/test.sh:
--------------------------------------------------------------------------------
1 |
2 | result=result_masstree_put.dat
3 | rm $result
4 | epoch=3
5 | thread=1
6 |
7 | sumTH=0
8 | avgTH=0
9 | tmpTH=0
10 | for ((i = 1; i <= epoch; ++i))
11 | do
12 | ../unit-mt $thread > out
13 | tmpTH=`cat out`
14 | sumTH=`echo "$sumTH + $tmpTH" | bc`
15 | done
16 |
17 | avgTH=`echo "$sumTH / $epoch" | bc`
18 | echo "$thread $avgTH" | tee -a $result
19 |
20 | for ((thread = 28; thread <= 224; thread+=28))
21 | do
22 |
23 | sumTH=0
24 | avgTH=0
25 | tmpTH=0
26 | for ((i = 1; i <= epoch; ++i))
27 | do
28 | ../unit-mt $thread > out
29 | tmpTH=`cat out`
30 | sumTH=`echo "$sumTH + $tmpTH" | bc`
31 | done
32 |
33 | avgTH=`echo "$sumTH / $epoch" | bc`
34 | echo "$thread $avgTH" | tee -a $result
35 |
36 | done
37 |
38 |
--------------------------------------------------------------------------------
/instruction/masstree_simple_test/script/xrs.sh:
--------------------------------------------------------------------------------
1 |
2 | result=result_masstree_put_xrs.dat
3 | rm $result
4 | epoch=3
5 | thread=224
6 | rs=1000
7 |
8 | sumTH=0
9 | avgTH=0
10 | tmpTH=0
11 | for ((i = 1; i <= epoch; ++i))
12 | do
13 | ../unit-mt $thread $rs > out
14 | tmpTH=`cat out`
15 | sumTH=`echo "$sumTH + $tmpTH" | bc`
16 | done
17 |
18 | avgTH=`echo "$sumTH / $epoch" | bc`
19 | echo "$rs $avgTH" | tee -a $result
20 |
21 | for ((rs = 10000; rs <= 1000000000; rs *= 10))
22 | do
23 |
24 | sumTH=0
25 | avgTH=0
26 | tmpTH=0
27 | for ((i = 1; i <= epoch; ++i))
28 | do
29 | ../unit-mt $thread $rs > out
30 | tmpTH=`cat out`
31 | sumTH=`echo "$sumTH + $tmpTH" | bc`
32 | done
33 |
34 | avgTH=`echo "$sumTH / $epoch" | bc`
35 | echo "$rs $avgTH" | tee -a $result
36 |
37 | done
38 |
39 |
--------------------------------------------------------------------------------
/instruction/pow_test.cc:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 |
6 | #include "../include/debug.hh"
7 |
8 | #define TRIAL 1000000
9 |
10 | using namespace std;
11 |
12 | int main(const int argc, const char *argv[]) try {
13 | cout << "#pow_arg, time" << endl;
14 | for (double j = 0; j <= 3; j += 0.1) {
15 | chrono::system_clock::time_point start, end;
16 | start = chrono::system_clock::now();
17 | for (size_t i = 0; i < TRIAL; ++i)
18 | pow(2, j);
19 | end = chrono::system_clock::now();
20 | double time = static_cast(chrono::duration_cast(end - start).count() / 1000.0);
21 | cout << j << " " << time << endl;
22 | }
23 | return 0;
24 | } catch (std::bad_alloc) {
25 | ERR;
26 | }
27 |
--------------------------------------------------------------------------------
/instruction/rdtscBench.cc:
--------------------------------------------------------------------------------
1 |
2 | #include
3 |
4 | #include "../include/tsc.hh"
5 |
6 | #define LOOP 1000000
7 |
8 | using std::cout;
9 | using std::endl;
10 |
11 | int main() {
12 | uint64_t start, stop;
13 | start = rdtscp();
14 | for (uint64_t i = 0; i < LOOP; ++i) rdtsc();
15 | stop = rdtscp();
16 |
17 | cout << "rdtscBench[clocks] :\t" << (stop - start) / LOOP << endl;
18 |
19 | start = rdtscp();
20 | for (unsigned int i = 0; i < LOOP; ++i) rdtscp();
21 | stop = rdtscp();
22 |
23 | cout << "rdtscpBench[clocks] :\t" << (stop - start) / LOOP << endl;
24 | }
25 |
--------------------------------------------------------------------------------
/instruction/script/fetch_add.sh:
--------------------------------------------------------------------------------
1 | #membench.sh
2 | thnr=1
3 | epoch=3;
4 |
5 | host=`hostname`
6 | chris41="chris41.omni.hpcc.jp"
7 | dbs11="dbs11"
8 |
9 | #basically
10 | inith=1
11 | enth=24
12 | inc=1
13 | if test $host = $dbs11 ; then
14 | inith=1
15 | enth=224
16 | inc=28
17 | fi
18 |
19 | result=fetch_add.dat
20 | rm $result
21 | echo "#thnr, throughput, cache-miss-rate" >> $result
22 |
23 | for ((thread=$inith; thread<=$enth; thread+=$inc))
24 | do
25 | if test $host = $dbs11 ; then
26 | if test $thread -eq 29 ; then
27 | thread=28
28 | fi
29 | fi
30 | sumtps=0
31 | sumcm=0
32 | for ((i = 1; i <= epoch; ++i))
33 | do
34 | echo "#thread: $thread, #epoch: $i"
35 | perf stat -e cache-misses,cache-references -o ana.txt numactl --interleave=all ../fetch_add $thread > out
36 | tmptps=`cat out`
37 | tmpcm=`grep cache-misses ./ana.txt | awk '{print $4}'`
38 | sumtps=`echo "$sumtps + $tmptps" | bc`
39 | sumcm=`echo "$sumcm + $tmpcm" | bc`
40 | done
41 |
42 | avgtps=`echo "$sumtps / $epoch" | bc`
43 | avgcm=`echo "$sumcm / $epoch" | bc`
44 |
45 | echo "avgtps: $avgtps, avgcm: $avgcm"
46 | echo "$thread $avgtps $avgcm" >> $result
47 | done
48 |
--------------------------------------------------------------------------------
/instruction/script/membench.sh:
--------------------------------------------------------------------------------
1 | #membench.sh
2 | thnr=1
3 | alc=1;
4 | epoch=3;
5 |
6 | host=`hostname`
7 | chris41="chris41.omni.hpcc.jp"
8 | dbs11="dbs11"
9 |
10 | #basically
11 | inith=4
12 | enth=24
13 | inc=4
14 | if test $host = $dbs11 ; then
15 | inith=28
16 | enth=224
17 | inc=28
18 | fi
19 |
20 | result=membench.dat
21 | rm $result
22 | echo "#array size was $alc GB." >> $result
23 | echo "#thnr, srbw, swbw, rrbw, rwbw" >> $result
24 |
25 | for ((thread=$inith; thread<=$enth; thread+=$inc))
26 | do
27 | sumSRBW=0
28 | sumSWBW=0
29 | sumRRBW=0
30 | sumRWBW=0
31 | for ((i = 1; i <= epoch; ++i))
32 | do
33 | numactl --localalloc ../membench.exe $thread $alc > out
34 | echo "thread $thread"
35 | cat out | grep -v Th\#
36 | echo ""
37 |
38 | tmpSRBW=`grep -v Th# out | grep sequentialRead | awk '{print $2}'`
39 | tmpSWBW=`grep -v Th# out | grep sequentialWrite | awk '{print $2}'`
40 | tmpRRBW=`grep -v Th# out | grep randomRead | awk '{print $2}'`
41 | tmpRWBW=`grep -v Th# out | grep randomWrite | awk '{print $2}'`
42 | echo "tmpSRBW $tmpSRBW"
43 | sumSRBW=`echo "$sumSRBW + $tmpSRBW" | bc`
44 | sumSWBW=`echo "$sumSWBW + $tmpSWBW" | bc`
45 | sumRRBW=`echo "$sumRRBW + $tmpRRBW" | bc`
46 | sumRWBW=`echo "$sumRWBW + $tmpRWBW" | bc`
47 | done
48 |
49 | avgSRBW=`echo "$sumSRBW / $epoch" | bc`
50 | avgSWBW=`echo "$sumSWBW / $epoch" | bc`
51 | avgRRBW=`echo "$sumRRBW / $epoch" | bc`
52 | avgRWBW=`echo "$sumRWBW / $epoch" | bc`
53 |
54 | echo "$thread $avgSRBW $avgSWBW $avgRRBW $avgRWBW" >> $result
55 | done
56 |
--------------------------------------------------------------------------------
/instruction/test_fetch_add.sh:
--------------------------------------------------------------------------------
1 | #test.sh(ermia)
2 | cpu_mhz=2400
3 | extime=3
4 | epoch=3
5 |
6 | result=fetch_add.dat
7 | rm $result
8 | echo "#worker threads, increments, min, max" >> $result
9 | for ((thread=2; thread<=24; thread+=2))
10 | do
11 | sum=0
12 | echo "./fetch_add.exe $thread $cpu_mhz $extime"
13 |
14 | max=0
15 | min=0
16 | for ((i=1; i <= epoch; ++i))
17 | do
18 | tmp=`./fetch_add.exe $thread $cpu_mhz $extime`
19 | sum=`echo "$sum + $tmp" | bc -l`
20 | echo "sum: $sum, tmp: $tmp"
21 |
22 | if test $i -eq 1 ; then
23 | max=$tmp
24 | min=$tmp
25 | fi
26 |
27 | flag=`echo "$tmp > $max" | bc -l`
28 | if test $flag -eq 1 ; then
29 | max=$tmp
30 | fi
31 | flag=`echo "$tmp < $min" | bc -l`
32 | if test $flag -eq 1 ; then
33 | min=$tmp
34 | fi
35 | done
36 | avg=`echo "$sum / $epoch" | bc`
37 | echo "sum: $sum, epoch: $epoch"
38 | echo "avg: $avg"
39 | echo "max: $max"
40 | echo "min: $min"
41 | echo "$thread $avg $min $max" >> $result
42 | done
43 |
--------------------------------------------------------------------------------
/instruction/test_xoroshiro.sh:
--------------------------------------------------------------------------------
1 | #test.sh(ermia)
2 | cpu_mhz=2400
3 | extime=3
4 | epoch=3
5 |
6 | result=xoroshiro.dat
7 | rm $result
8 | echo "#worker threads, increments, min, max" >> $result
9 | for ((thread=2; thread<=24; thread+=2))
10 | do
11 | sum=0
12 | echo "./xoroshiro.exe $thread $cpu_mhz $extime"
13 |
14 | max=0
15 | min=0
16 | for ((i=1; i <= epoch; ++i))
17 | do
18 | tmp=`./xoroshiro.exe $thread $cpu_mhz $extime`
19 | sum=`echo "$sum + $tmp" | bc -l`
20 | echo "sum: $sum, tmp: $tmp"
21 |
22 | if test $i -eq 1 ; then
23 | max=$tmp
24 | min=$tmp
25 | fi
26 |
27 | flag=`echo "$tmp > $max" | bc -l`
28 | if test $flag -eq 1 ; then
29 | max=$tmp
30 | fi
31 | flag=`echo "$tmp < $min" | bc -l`
32 | if test $flag -eq 1 ; then
33 | min=$tmp
34 | fi
35 | done
36 | avg=`echo "$sum / $epoch" | bc`
37 | echo "sum: $sum, epoch: $epoch"
38 | echo "avg: $avg"
39 | echo "max: $max"
40 | echo "min: $min"
41 | echo "$thread $avg $min $max" >> $result
42 | done
43 |
--------------------------------------------------------------------------------
/instruction/xoroshiro.cc:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 |
5 | #include "../include/random.hh"
6 | #include "../include/tsc.hh"
7 | #include "../include/util.hh"
8 |
9 | #define CLOCKS_PER_US 2100
10 | #define LOOP 1000000
11 | #define EX_TIME 3
12 |
13 | using std::cout;
14 | using std::endl;
15 |
16 | int main() {
17 | Xoroshiro128Plus rnd;
18 | rnd.init();
19 |
20 | uint64_t start, stop;
21 | start = rdtscp();
22 | for (uint32_t i = 0; i < UINT32_MAX; ++i) rnd.next();
23 | stop = rdtscp();
24 |
25 | cout << "xoroshiro128PlusBench[clocks] :\t"
26 | << (double) (stop - start) / (double) UINT32_MAX << endl;
27 |
28 | return 0;
29 | }
30 |
--------------------------------------------------------------------------------
/instruction/zipf_dist_test.cc:
--------------------------------------------------------------------------------
1 |
2 | #include
3 |
4 | #include "../include/debug.hh"
5 | #include "../include/util.hh"
6 | #include "../include/zipf.hh"
7 |
8 | size_t LENGTH;
9 | double SKEW;
10 | size_t TRIAL;
11 |
12 | int main(const int argc, const char *argv[]) try {
13 | if (argc == 1) {
14 | cout << "./a.out LENGTH SKEW TRIAL" << endl;
15 | exit(0);
16 | }
17 |
18 | LENGTH = atoi(argv[1]);
19 | SKEW = atof(argv[2]);
20 | TRIAL = atoi(argv[3]);
21 |
22 | uint64_t Ctr[LENGTH];
23 | // if (posix_memalign((void**)&Ctr, CACHE_LINE_SIZE, LENGTH * sizeof(uint64_t)));
24 | Xoroshiro128Plus rnd;
25 | FastZipf zipf(&rnd, SKEW, LENGTH);
26 |
27 | for (size_t i = 0; i < LENGTH; ++i)
28 | Ctr[i] = 0;
29 |
30 | for (size_t i = 0; i < TRIAL; ++i)
31 | ++Ctr[zipf() % LENGTH];
32 |
33 | cout << "#number : count" << endl;
34 | for (size_t i = 0; i < LENGTH; ++i) {
35 | cout << i << " " << (double) Ctr[i] / (double) TRIAL << endl;
36 | }
37 |
38 | return 0;
39 | } catch (std::bad_alloc) {
40 | ERR;
41 | }
42 |
--------------------------------------------------------------------------------
/mocc/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | project(ccbench_mocc
4 | VERSION 0.0.1
5 | DESCRIPTION "mocc of ccbench"
6 | LANGUAGES CXX)
7 |
8 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
9 |
10 | option(ENABLE_SANITIZER "enable sanitizer on debug build" ON)
11 | option(ENABLE_UB_SANITIZER "enable undefined behavior sanitizer on debug build" OFF)
12 | option(ENABLE_COVERAGE "enable coverage on debug build" OFF)
13 |
14 | find_package(Doxygen)
15 | find_package(Threads REQUIRED)
16 | find_package(gflags REQUIRED)
17 | find_package(glog REQUIRED)
18 | find_package(Boost
19 | COMPONENTS filesystem)
20 |
21 | include(GNUInstallDirs)
22 | include(CMakePackageConfigHelpers)
23 | include(CompileOptions)
24 |
25 | file(GLOB MOCC_SOURCES
26 | "../common/result.cc"
27 | "../common/util.cc"
28 | "lock.cc"
29 | "mocc.cc"
30 | "result.cc"
31 | "transaction.cc"
32 | "util.cc"
33 | )
34 |
35 | add_executable(mocc.exe ${MOCC_SOURCES})
36 |
37 | target_link_libraries(mocc.exe
38 | Boost::filesystem
39 | gflags::gflags
40 | ${PROJECT_SOURCE_DIR}/../third_party/mimalloc/out/release/libmimalloc.a
41 | ${PROJECT_SOURCE_DIR}/../third_party/masstree/libkohler_masstree_json.a
42 | Threads::Threads
43 | )
44 |
45 | if (DEFINED ADD_ANALYSIS)
46 | add_definitions(-DADD_ANALYSIS=${ADD_ANALYSIS})
47 | else ()
48 | add_definitions(-DADD_ANALYSIS=0)
49 | endif ()
50 |
51 | if (DEFINED BACK_OFF)
52 | add_definitions(-DBACK_OFF=${BACK_OFF})
53 | else ()
54 | add_definitions(-DBACK_OFF=0)
55 | endif ()
56 |
57 | if (DEFINED KEY_SIZE)
58 | add_definitions(-DKEY_SIZE=${KEY_SIZE})
59 | else ()
60 | add_definitions(-DKEY_SIZE=8)
61 | endif ()
62 |
63 | if (DEFINED KEY_SORT)
64 | add_definitions(-DKEY_SORT=${KEY_SORT})
65 | else ()
66 | add_definitions(-DKEY_SORT=0)
67 | endif ()
68 |
69 | if (DEFINED MASSTREE_USE)
70 | add_definitions(-DMASSTREE_USE=${MASSTREE_USE})
71 | else ()
72 | add_definitions(-DMASSTREE_USE=1)
73 | endif ()
74 |
75 | add_definitions(-DRWLOCK)
76 |
77 | if (DEFINED TEMPERATURE_RESET_OPT)
78 | add_definitions(-DTEMPERATURE_RESET_OPT=${TEMPERATURE_RESET_OPT})
79 | else ()
80 | add_definitions(-DTEMPERATURE_RESET_OPT=1)
81 | endif ()
82 |
83 | if (DEFINED VAL_SIZE)
84 | add_definitions(-DVAL_SIZE=${VAL_SIZE})
85 | else ()
86 | add_definitions(-DVAL_SIZE=4)
87 | endif ()
88 |
--------------------------------------------------------------------------------
/mocc/README.md:
--------------------------------------------------------------------------------
1 | # MOCC
2 | It was proposed at VLDB'2017 by Tianzheng Wang.
3 |
4 | ## How to use
5 | - Build masstree
6 | ```
7 | $ cd ../
8 | $ ./bootstrap.sh
9 | ```
10 | This makes ../third_party/masstree/libkohler_masstree_json.a used by building mocc.
11 | - Build mimalloc
12 | ```
13 | $ cd ../
14 | $ ./bootstrap_mimalloc.sh
15 | ```
16 | This makes ../third_party/mimalloc/out/release/libmimalloc.a used by building mocc.
17 | - Build
18 | ```
19 | $ mkdir build
20 | $ cd build
21 | $ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
22 | $ ninja
23 | ```
24 | - Confirm usage
25 | ```
26 | $ ./mocc.exe -help
27 | ```
28 | - Execution example
29 | ```
30 | $ numactl --interleave=all ./mocc.exe -clocks_per_us=2100 -epoch_time=40 -extime=3 -max_ope=10 -rmw=0 -rratio=100 -thread_num=224 -tuple_num=1000000 -ycsb=1 -zipf_skew=0 -per_xx_temp=4096
31 | ```
32 |
33 | ## How to customize options in CMakeLists.txt
34 | - `ADD_ANALYSIS` : If this is 1, it is deeper analysis than setting 0.
35 | default : `0`
36 | - `BACK_OFF` : If this is 1, it use Cicada's backoff.
37 | default : `0`
38 | - `KEY_SORT` : If this is 1, its transaction accesses records in ascending key order.
39 | default : `0`
40 | - `MASSTREE_USE` : If this is 1, it use masstree as data structure. If not, it use simple array αs data structure.
41 | default : `1`
42 | - `TEMPERATURE_RESET_OPT` : If this is 1, it uses new temprature control protocol which reduces contentions and improves throughput much.
43 | default : `1`
44 | - `VAL_SIZE` : Value of key-value size. In other words, payload size.
45 | default : `4`
46 |
47 | ## Custom build examples
48 | ```
49 | $ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DKEY_SIZE=1000 -DVAL_SIZE=1000 ..
50 | ```
51 | - Note: If you re-run cmake, don't forget to remove cmake cache.
52 | ```
53 | $ rm CMakeCache.txt
54 | ```
55 | The cmake cache definition data is used in preference to the command line definition data.
56 |
57 | ## Optimizations
58 | - Backoff.
59 | - Early aborts (by setting threshold of whether it executes try lock or wait lock).
60 | - New temprature protocol reduces contentions and improves throughput much.
61 |
62 | ## Missing features
63 | - MQL lock. It uses custom reader-writer lock instead of MQL lock because author's experimental environment has few NUMA architecture.
64 |
--------------------------------------------------------------------------------
/mocc/include/atomic_tool.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../../include/inline.hh"
4 |
5 | #include "common.hh"
6 |
7 | INLINE uint64_t_64byte loadAcquireGE() {
8 | return __atomic_load_n(&(GlobalEpoch.obj_), __ATOMIC_ACQUIRE);
9 | }
10 |
11 | INLINE void atomicAddGE() {
12 | uint64_t_64byte expected, desired;
13 |
14 | expected = loadAcquireGE();
15 | for (;;) {
16 | desired.obj_ = expected.obj_ + 1;
17 | if (__atomic_compare_exchange_n(&(GlobalEpoch.obj_), &(expected.obj_),
18 | desired.obj_, false, __ATOMIC_ACQ_REL,
19 | __ATOMIC_ACQUIRE))
20 | break;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/mocc/include/mocc_op_element.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/op_element.hh"
6 |
7 | using std::cout;
8 | using std::endl;
9 |
10 | template
11 | class ReadElement : public OpElement {
12 | public:
13 | using OpElement::OpElement;
14 |
15 | Tidword tidword_;
16 | char val_[VAL_SIZE];
17 | bool failed_verification_;
18 |
19 | ReadElement(Tidword tidword, uint64_t key, T *rcdptr, char *newVal)
20 | : OpElement::OpElement(key, rcdptr) {
21 | this->tidword_ = tidword;
22 | memcpy(val_, newVal, VAL_SIZE);
23 | this->failed_verification_ = false;
24 | }
25 |
26 | ReadElement(uint64_t key, T *rcdptr) : OpElement::OpElement(key, rcdptr) {
27 | failed_verification_ = true;
28 | }
29 |
30 | bool operator<(const ReadElement &right) const {
31 | return this->key_ < right.key_;
32 | }
33 | };
34 |
35 | template
36 | class WriteElement : public OpElement {
37 | public:
38 | using OpElement::OpElement;
39 |
40 | bool operator<(const WriteElement &right) const {
41 | return this->key_ < right.key_;
42 | }
43 | };
44 |
--------------------------------------------------------------------------------
/mocc/include/result.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/result.hh"
6 |
7 | extern std::vector MoccResult;
8 |
9 | extern void initResult();
10 |
--------------------------------------------------------------------------------
/mocc/include/transaction.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/procedure.hh"
6 | #include "../../include/result.hh"
7 | #include "../../include/string.hh"
8 | #include "../../include/util.hh"
9 | #include "common.hh"
10 | #include "lock.hh"
11 | #include "mocc_op_element.hh"
12 | #include "tuple.hh"
13 |
14 | using namespace std;
15 |
16 | enum class TransactionStatus : uint8_t {
17 | inFlight,
18 | committed,
19 | aborted,
20 | };
21 |
22 | class TxExecutor {
23 | public:
24 | vector > read_set_;
25 | vector > write_set_;
26 | vector pro_set_;
27 | #ifdef RWLOCK
28 | vector> RLL_;
29 | vector> CLL_;
30 | #endif // RWLOCK
31 | #ifdef MQLOCK
32 | vector> RLL_;
33 | vector> CLL_;
34 | #endif // MQLOCK
35 | TransactionStatus status_;
36 |
37 | int thid_;
38 | Tidword mrctid_;
39 | Tidword max_rset_;
40 | Tidword max_wset_;
41 | Xoroshiro128Plus *rnd_;
42 | Result *mres_;
43 |
44 | char write_val_[VAL_SIZE] = {};
45 | char return_val_[VAL_SIZE] = {};
46 |
47 | TxExecutor(int thid, Xoroshiro128Plus *rnd, Result *mres)
48 | : thid_(thid), mres_(mres) {
49 | read_set_.reserve(FLAGS_max_ope);
50 | write_set_.reserve(FLAGS_max_ope);
51 | pro_set_.reserve(FLAGS_max_ope);
52 | RLL_.reserve(FLAGS_max_ope);
53 | CLL_.reserve(FLAGS_max_ope);
54 |
55 | this->status_ = TransactionStatus::inFlight;
56 | this->rnd_ = rnd;
57 | max_rset_.obj_ = 0;
58 | max_wset_.obj_ = 0;
59 |
60 | genStringRepeatedNumber(write_val_, VAL_SIZE, thid);
61 | }
62 |
63 | ReadElement *searchReadSet(uint64_t key);
64 |
65 | WriteElement *searchWriteSet(uint64_t key);
66 |
67 | template
68 | T *searchRLL(uint64_t key);
69 |
70 | void removeFromCLL(uint64_t key);
71 |
72 | void begin();
73 |
74 | void read(uint64_t key);
75 |
76 | void write(uint64_t key);
77 |
78 | void read_write(uint64_t key);
79 |
80 | void lock(uint64_t key, Tuple *tuple, bool mode);
81 |
82 | void construct_RLL(); // invoked on abort;
83 | void unlockCLL();
84 |
85 | bool commit();
86 |
87 | void abort();
88 |
89 | void writePhase();
90 |
91 | void dispCLL();
92 |
93 | void dispRLL();
94 |
95 | void dispWS();
96 |
97 | Tuple *get_tuple(Tuple *table, uint64_t key) { return &table[key]; }
98 | };
99 |
--------------------------------------------------------------------------------
/mocc/include/tuple.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include // memcpy
4 | #include
5 | #include
6 |
7 | #include "lock.hh"
8 |
9 | #include "../../include/cache_line_size.hh"
10 |
11 | #define TEMP_THRESHOLD 5
12 | #define TEMP_MAX 20
13 | #define TEMP_RESET_US 100
14 |
15 | struct Tidword {
16 | union {
17 | uint64_t obj_;
18 | struct {
19 | uint64_t tid: 32;
20 | uint64_t epoch: 32;
21 | };
22 | };
23 |
24 | Tidword() { obj_ = 0; }
25 |
26 | bool operator==(const Tidword &right) const { return obj_ == right.obj_; }
27 |
28 | bool operator!=(const Tidword &right) const { return !operator==(right); }
29 |
30 | bool operator<(const Tidword &right) const { return this->obj_ < right.obj_; }
31 | };
32 |
33 | // 32bit temprature, 32bit epoch
34 | struct Epotemp {
35 | union {
36 | alignas(CACHE_LINE_SIZE) uint64_t obj_;
37 | struct {
38 | uint64_t temp: 32;
39 | uint64_t epoch: 32;
40 | };
41 | };
42 |
43 | Epotemp() : obj_(0) {}
44 |
45 | Epotemp(uint64_t temp2, uint64_t epoch2) : temp(temp2), epoch(epoch2) {}
46 |
47 | bool operator==(const Epotemp &right) const { return obj_ == right.obj_; }
48 |
49 | bool operator!=(const Epotemp &right) const { return !operator==(right); }
50 |
51 | bool eqEpoch(uint64_t epo) {
52 | if (epoch == epo)
53 | return true;
54 | else
55 | return false;
56 | }
57 | };
58 |
59 | class Tuple {
60 | public:
61 | alignas(CACHE_LINE_SIZE) Tidword tidword_;
62 | #ifdef RWLOCK
63 | RWLock rwlock_; // 4byte
64 | // size to here is 20 bytes
65 | #endif
66 | #ifdef MQLOCK
67 | MQLock mqlock_;
68 | #endif
69 |
70 | char val_[VAL_SIZE];
71 | };
72 |
--------------------------------------------------------------------------------
/mocc/include/util.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | extern void chkArg();
4 |
5 | extern bool chkEpochLoaded();
6 |
7 | extern void displayDB();
8 |
9 | extern void displayParameter();
10 |
11 | extern void displayLockedTuple();
12 |
13 | extern void leaderWork(uint64_t &epoch_timer_start, uint64_t &epoch_timer_stop,
14 | [[maybe_unused]] Result &res);
15 |
16 | extern void makeDB();
17 |
18 | extern void partTableInit([[maybe_unused]] size_t thid, uint64_t start,
19 | uint64_t end);
20 |
21 | extern void ShowOptParameters();
22 |
--------------------------------------------------------------------------------
/mocc/result.cc:
--------------------------------------------------------------------------------
1 | #include "include/result.hh"
2 | #include "include/common.hh"
3 |
4 | #include "../include/cache_line_size.hh"
5 | #include "../include/result.hh"
6 |
7 | using namespace std;
8 |
9 | alignas(CACHE_LINE_SIZE) std::vector MoccResult;
10 |
11 | void initResult() { MoccResult.resize(FLAGS_thread_num); }
12 |
--------------------------------------------------------------------------------
/mocc/script/ycsbA-xrs-cache.sh:
--------------------------------------------------------------------------------
1 | #ycsbA-xrs-cache.sh(mocc)
2 | maxope=10
3 | thread=24
4 | rratio=50
5 | skew=0
6 | ycsb=ON
7 | cpu_mhz=2400
8 | epochtime=40
9 | extime=3
10 | epoch=5
11 |
12 | result=result_mocc_ycsbA_tuple100-10m_cachemiss.dat
13 | rm $result
14 | echo "#tuple num, cache-misses, min, max" >> $result
15 | echo "#./mocc.exe tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $epochtime $extime" >> $result
16 |
17 | for ((tuple=100; tuple<=10000000; tuple*=10))
18 | do
19 | sum=0
20 | echo "./mocc.exe $tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $epochtime $extime"
21 | echo "$tuple $epoch"
22 |
23 | max=0
24 | min=0
25 | for ((i = 1; i <= epoch; ++i))
26 | do
27 | perf stat -e cache-misses,cache-references -o mocc-cache-ana.txt ./mocc.exe $tuple $maxope $thread $rratio $skew $ycsb $cpu_mhz $epochtime $extime
28 | tmp=`grep cache-misses ./mocc-cache-ana.txt | awk '{print $4}'`
29 | sum=`echo "$sum + $tmp" | bc -l`
30 | echo "sum: $sum, tmp: $tmp"
31 |
32 | if test $i -eq 1 ; then
33 | max=$tmp
34 | min=$tmp
35 | fi
36 |
37 | flag=`echo "$tmp > $max" | bc -l`
38 | if test $flag -eq 1 ; then
39 | max=$tmp
40 | fi
41 | flag=`echo "$tmp < $min" | bc -l`
42 | if test $flag -eq 1 ; then
43 | min=$tmp
44 | fi
45 | done
46 | avg=`echo "$sum / $epoch" | bc -l`
47 | echo "sum: $sum, epoch: $epoch"
48 | echo "avg $avg"
49 | echo "max: $max"
50 | echo "min: $min"
51 | echo "$tuple $avg $min $max" >> $result
52 | done
53 |
54 |
--------------------------------------------------------------------------------
/occ/Makefile:
--------------------------------------------------------------------------------
1 | PROG1 = occ.exe
2 | SV_FORMAT_SRCS1 := occ.cc transaction.cc util.cc result.cc
3 |
4 | REL := ../common/
5 | include $(REL)Makefile
6 | SV_FORMAT_ALLSRC = $(SV_FORMAT_SRCS1) $(SRCS2) $(wildcard include/*.hh)
7 |
8 | # start of initialization of some parameters.
9 | ADD_ANALYSIS=1
10 | BACK_OFF=0
11 | KEY_SIZE=8
12 | MASSTREE_USE=1
13 | PARTITION_TABLE=0
14 | PROCEDURE_SORT=0
15 | OCC_GC_THRESHOLD=10000 # How many write sets to keep
16 | VAL_SIZE=4
17 | WAL=0
18 | # end of initialization
19 |
20 | CC = g++
21 | CFLAGS = -c -pipe -g -O3 -std=c++17 -march=native \
22 | -Wall -Wextra -Wdangling-else -Wchkp -Winvalid-memory-model \
23 | -D$(shell uname) \
24 | -D$(shell hostname) \
25 | -DKEY_SIZE=$(KEY_SIZE) \
26 | -DVAL_SIZE=$(VAL_SIZE) \
27 | -DADD_ANALYSIS=$(ADD_ANALYSIS) \
28 | -DBACK_OFF=$(BACK_OFF) \
29 | -DMASSTREE_USE=$(MASSTREE_USE) \
30 | -DNO_WAIT_LOCKING_IN_VALIDATION=$(NO_WAIT_LOCKING_IN_VALIDATION) \
31 | -DNO_WAIT_OF_TICTOC=$(NO_WAIT_OF_TICTOC) \
32 | -DPARTITION_TABLE=$(PARTITION_TABLE) \
33 | -DPROCEDURE_SORT=$(PROCEDURE_SORT) \
34 | -DOCC_GC_THRESHOLD=$(OCC_GC_THRESHOLD) \
35 | -DWAL=$(WAL) \
36 |
37 | INCLUDE = -I/usr/include \
38 | -I../third_party/ \
39 |
40 | LDLIBS = -lpthread -lboost_filesystem -lboost_system -lgflags -lglog
41 |
42 | OBJS1 = $(SV_FORMAT_SRCS1:.cc=.o)
43 |
44 | all: $(PROG1)
45 |
46 | include ../include/MakefileForMasstreeUse
47 | $(PROG1) : $(OBJS1) $(MASSOBJ)
48 | $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) $(INCLUDE)
49 |
50 | .cc.o:
51 | $(CC) $(CFLAGS) -c $< -o $@
52 |
53 | format:
54 | clang-format -i -verbose -style=Google $(SV_FORMAT_ALLSRC)
55 |
56 | clean:
57 | rm -f *~ *.o *.exe *.stackdump
58 | rm -f ../common/*~ ../common/*.o ../common/*.exe ../common/*.stackdump
59 | rm -rf .deps
60 |
--------------------------------------------------------------------------------
/occ/README.md:
--------------------------------------------------------------------------------
1 | # OCC
2 | The original proposal is as follows.
3 |
4 | ```
5 | H. T. Kung and John T. Robinson. 1981.
6 | On optimistic methods for concurrency control.
7 | ACM Trans. Database Syst. 6, 2 (June 1981), 213-226.
8 | DOI=http://dx.doi.org/10.1145/319566.319567
9 | ```
10 |
11 | ## How to use
12 | - Build
13 | ```
14 | $ make
15 | ```
16 | - Confirm usage
17 | ```
18 | $ ./occ.exe -help
19 | ```
20 | - Execution example
21 | ```
22 | $ numactl --interleave=all ./occ.exe -tuple_num=1000 -max_ope=10 -thread_num=224 -rratio=100 -rmw=0 -zipf_skew=0 -ycsb=1 -clocks_per_us=2100 -extime=3
23 | ```
24 |
25 | ## How to select build options in Makefile
26 | - `OCC_GC_THRESHOLD` : Number of committed write sets to be kept before performing garbage collection.
27 | - `ADD_ANALYSIS` : If this is 1, it is deeper analysis than setting 0 (currently no analysis point for OCC).
28 | - `BACK_OFF` : If this is 1, it use backoff.
29 | - `MASSTREE_USE` : If this is 1, it use masstree as data structure. If not, it use simple array αs data structure.
30 | - `PARTITION_TABLE` : If this is 1, it devide the table into the number of worker threads not to occur read/write conflicts.
31 | - `VAL_SIZE` : Value of key-value size. In other words, payload size.
32 |
33 | ## Optimizations
34 | - Backoff.
35 |
--------------------------------------------------------------------------------
/occ/include/atomic_tool.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "common.hh"
4 |
5 | #include "../../include/inline.hh"
6 |
7 | INLINE uint64_t atomicLoadGE();
8 |
9 | INLINE void atomicAddGE() {
10 | uint64_t expected, desired;
11 |
12 | expected = atomicLoadGE();
13 | for (;;) {
14 | desired = expected + 1;
15 | if (__atomic_compare_exchange_n(&(GlobalEpoch.obj_), &expected, desired,
16 | false, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE))
17 | break;
18 | }
19 | }
20 |
21 | INLINE uint64_t atomicLoadGE() {
22 | uint64_t_64byte result =
23 | __atomic_load_n(&(GlobalEpoch.obj_), __ATOMIC_ACQUIRE);
24 | return result.obj_;
25 | }
26 |
27 | INLINE void atomicStoreThLocalEpoch(unsigned int thid, uint64_t newval) {
28 | __atomic_store_n(&(ThLocalEpoch[thid].obj_), newval, __ATOMIC_RELEASE);
29 | }
30 |
--------------------------------------------------------------------------------
/occ/include/common.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "tuple.hh"
8 |
9 | #include "../../include/cache_line_size.hh"
10 | #include "../../include/int64byte.hh"
11 | #include "../../include/masstree_wrapper.hh"
12 |
13 | #include "gflags/gflags.h"
14 | #include "glog/logging.h"
15 |
16 | #ifdef GLOBAL_VALUE_DEFINE
17 | #define GLOBAL
18 | alignas(CACHE_LINE_SIZE) GLOBAL uint64_t_64byte GlobalEpoch(1);
19 | #if MASSTREE_USE
20 | alignas(CACHE_LINE_SIZE) GLOBAL MasstreeWrapper MT;
21 | #endif
22 | #else
23 | #define GLOBAL extern
24 | alignas(CACHE_LINE_SIZE) GLOBAL uint64_t_64byte GlobalEpoch;
25 | #if MASSTREE_USE
26 | alignas(CACHE_LINE_SIZE) GLOBAL MasstreeWrapper MT;
27 | #endif
28 | #endif
29 |
30 | #ifdef GLOBAL_VALUE_DEFINE
31 | DEFINE_uint64(clocks_per_us, 2100,
32 | "CPU_MHz. Use this info for measuring time.");
33 | DEFINE_uint64(epoch_time, 40, "Epoch interval[msec].");
34 | DEFINE_uint64(extime, 3, "Execution time[sec].");
35 | DEFINE_uint64(max_ope, 10,
36 | "Total number of operations per single transaction.");
37 | DEFINE_bool(rmw, false,
38 | "True means read modify write, false means blind write.");
39 | DEFINE_uint64(rratio, 50, "read ratio of single transaction.");
40 | DEFINE_uint64(thread_num, 10, "Total number of worker threads.");
41 | DEFINE_uint64(tuple_num, 1000000, "Total number of records.");
42 | DEFINE_bool(ycsb, true,
43 | "True uses zipf_skew, false uses faster random generator.");
44 | DEFINE_double(zipf_skew, 0, "zipf skew. 0 ~ 0.999...");
45 | #else
46 | DECLARE_uint64(clocks_per_us);
47 | DECLARE_uint64(epoch_time);
48 | DECLARE_uint64(extime);
49 | DECLARE_uint64(max_ope);
50 | DECLARE_bool(rmw);
51 | DECLARE_uint64(rratio);
52 | DECLARE_uint64(thread_num);
53 | DECLARE_uint64(tuple_num);
54 | DECLARE_bool(ycsb);
55 | DECLARE_double(zipf_skew);
56 | #endif
57 |
58 | alignas(CACHE_LINE_SIZE) GLOBAL uint64_t_64byte *ThLocalEpoch;
59 | alignas(CACHE_LINE_SIZE) GLOBAL uint64_t_64byte *CTIDW;
60 |
61 | alignas(CACHE_LINE_SIZE) GLOBAL Tuple *Table;
62 |
--------------------------------------------------------------------------------
/occ/include/log.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | class LogHeader {
9 | public:
10 | int chkSum_ = 0;
11 | unsigned int logRecNum_ = 0;
12 | const std::size_t len_val_ = VAL_SIZE;
13 |
14 | void init() {
15 | chkSum_ = 0;
16 | logRecNum_ = 0;
17 | }
18 |
19 | void convertChkSumIntoComplementOnTwo() {
20 | chkSum_ ^= 0xffffffff;
21 | ++chkSum_;
22 | }
23 | };
24 |
25 | class LogRecord {
26 | public:
27 | uint64_t tid_;
28 | unsigned int key_;
29 | char val_[VAL_SIZE];
30 |
31 | LogRecord() : tid_(0), key_(0) {}
32 |
33 | LogRecord(uint64_t tid, unsigned int key, char *val) : tid_(tid), key_(key) {
34 | memcpy(this->val_, val, VAL_SIZE);
35 | }
36 |
37 | int computeChkSum() {
38 | // compute checksum
39 | int chkSum = 0;
40 | int *itr = (int *)this;
41 | for (unsigned int i = 0; i < sizeof(LogRecord) / sizeof(int); ++i) {
42 | chkSum += (*itr);
43 | ++itr;
44 | }
45 |
46 | return chkSum;
47 | }
48 | };
49 |
50 | class LogPackage {
51 | public:
52 | LogHeader header_;
53 | std::unique_ptr log_records_;
54 | };
55 |
--------------------------------------------------------------------------------
/occ/include/occ_op_element.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../../include/op_element.hh"
4 |
5 | template
6 | class ReadElement : public OpElement {
7 | public:
8 | using OpElement::OpElement;
9 |
10 | char val_[VAL_SIZE];
11 |
12 | ReadElement(uint64_t key, T* rcdptr, char* val)
13 | : OpElement::OpElement(key, rcdptr) {
14 | memcpy(this->val_, val, VAL_SIZE);
15 | }
16 |
17 | bool operator<(const ReadElement& right) const {
18 | return this->key_ < right.key_;
19 | }
20 | };
21 |
22 | template
23 | class WriteElement : public OpElement {
24 | public:
25 | using OpElement::OpElement;
26 |
27 | WriteElement(uint64_t key, T* rcdptr)
28 | : OpElement::OpElement(key, rcdptr) {}
29 |
30 | bool operator<(const WriteElement& right) const {
31 | return this->key_ < right.key_;
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/occ/include/result.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/result.hh"
6 |
7 | extern std::vector OccResult;
8 |
9 | extern void initResult();
10 |
--------------------------------------------------------------------------------
/occ/include/tuple.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | #include "../../include/cache_line_size.hh"
10 |
11 | class Tuple {
12 | public:
13 | char val_[VAL_SIZE];
14 | };
15 |
--------------------------------------------------------------------------------
/occ/include/util.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | extern void chkArg();
4 |
5 | extern bool chkEpochLoaded();
6 |
7 | extern void displayDB();
8 |
9 | extern void displayParameter();
10 |
11 | extern void genLogFile(std::string &logpath, const int thid);
12 |
13 | extern void leaderWork();
14 |
15 | extern void makeDB();
16 |
17 | extern void partTableInit([[maybe_unused]] size_t thid, uint64_t start,
18 | uint64_t end);
19 |
20 | extern void ShowOptParameters();
21 |
--------------------------------------------------------------------------------
/occ/result.cc:
--------------------------------------------------------------------------------
1 | #include "include/result.hh"
2 | #include "include/common.hh"
3 |
4 | #include "../include/cache_line_size.hh"
5 | #include "../include/result.hh"
6 |
7 | using namespace std;
8 |
9 | /**
10 | * Please declare it with an appropriate name.
11 | */
12 | alignas(CACHE_LINE_SIZE) std::vector OccResult;
13 |
14 | void initResult() { OccResult.resize(FLAGS_thread_num); }
15 |
--------------------------------------------------------------------------------
/si/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | project(ccbench_si
4 | VERSION 0.0.1
5 | DESCRIPTION "si of ccbench"
6 | LANGUAGES CXX)
7 |
8 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake")
9 |
10 | option(ENABLE_SANITIZER "enable sanitizer on debug build" ON)
11 | option(ENABLE_UB_SANITIZER "enable undefined behavior sanitizer on debug build" OFF)
12 | option(ENABLE_COVERAGE "enable coverage on debug build" OFF)
13 |
14 | find_package(Doxygen)
15 | find_package(Threads REQUIRED)
16 | find_package(gflags REQUIRED)
17 | find_package(glog REQUIRED)
18 | find_package(Boost
19 | COMPONENTS filesystem)
20 |
21 | include(GNUInstallDirs)
22 | include(CMakePackageConfigHelpers)
23 | include(CompileOptions)
24 |
25 | file(GLOB SI_SOURCES
26 | "../common/result.cc"
27 | "../common/util.cc"
28 | "si.cc"
29 | "garbage_collection.cc"
30 | "result.cc"
31 | "transaction.cc"
32 | "util.cc"
33 | )
34 |
35 | add_executable(si.exe ${SI_SOURCES})
36 |
37 | target_link_libraries(si.exe
38 | Boost::filesystem
39 | gflags::gflags
40 | ${PROJECT_SOURCE_DIR}/../third_party/mimalloc/out/release/libmimalloc.a
41 | ${PROJECT_SOURCE_DIR}/../third_party/masstree/libkohler_masstree_json.a
42 | Threads::Threads
43 | )
44 |
45 | if (DEFINED ADD_ANALYSIS)
46 | add_definitions(-DADD_ANALYSIS=${ADD_ANALYSIS})
47 | else ()
48 | add_definitions(-DADD_ANALYSIS=0)
49 | endif ()
50 |
51 | if (DEFINED BACK_OFF)
52 | add_definitions(-DBACK_OFF=${BACK_OFF})
53 | else ()
54 | add_definitions(-DBACK_OFF=0)
55 | endif ()
56 |
57 | add_definitions(-DCCTR_ON)
58 |
59 | if (DEFINED KEY_SIZE)
60 | add_definitions(-DKEY_SIZE=${KEY_SIZE})
61 | else ()
62 | add_definitions(-DKEY_SIZE=8)
63 | endif ()
64 |
65 | if (DEFINED MASSTREE_USE)
66 | add_definitions(-DMASSTREE_USE=${MASSTREE_USE})
67 | else ()
68 | add_definitions(-DMASSTREE_USE=1)
69 | endif ()
70 |
71 | if (DEFINED VAL_SIZE)
72 | add_definitions(-DVAL_SIZE=${VAL_SIZE})
73 | else ()
74 | add_definitions(-DVAL_SIZE=4)
75 | endif ()
76 |
--------------------------------------------------------------------------------
/si/include/common.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "../../include/cache_line_size.hh"
7 | #include "../../include/int64byte.hh"
8 | #include "../../include/masstree_wrapper.hh"
9 | #include "transaction_table.hh"
10 | #include "tuple.hh"
11 |
12 | #include "gflags/gflags.h"
13 | #include "glog/logging.h"
14 |
15 | #ifdef GLOBAL_VALUE_DEFINE
16 | #define GLOBAL
17 | alignas(CACHE_LINE_SIZE) GLOBAL std::atomic CCtr(0);
18 | #if MASSTREE_USE
19 | alignas(CACHE_LINE_SIZE) GLOBAL MasstreeWrapper MT;
20 | #endif
21 | #else
22 | #define GLOBAL extern
23 | alignas(CACHE_LINE_SIZE) GLOBAL std::atomic CCtr;
24 | #if MASSTREE_USE
25 | alignas(CACHE_LINE_SIZE) GLOBAL MasstreeWrapper MT;
26 | #endif
27 | #endif
28 |
29 | #ifdef GLOBAL_VALUE_DEFINE
30 | DEFINE_uint64(clocks_per_us, 2100,
31 | "CPU_MHz. Use this info for measuring time.");
32 | DEFINE_uint64(extime, 3, "Execution time[sec].");
33 | DEFINE_uint64(gc_inter_us, 10, "GC interval[us].");
34 | DEFINE_uint64(max_ope, 10,
35 | "Total number of operations per single transaction.");
36 | DEFINE_uint64(
37 | pre_reserve_tmt_element, 100,
38 | "Pre-allocating memory for the transaction mapping table elements.");
39 | DEFINE_uint64(pre_reserve_version, 10000,
40 | "Pre-allocating memory for the version.");
41 | DEFINE_bool(rmw, false,
42 | "True means read modify write, false means blind write.");
43 | DEFINE_uint64(rratio, 50, "read ratio of single transaction.");
44 | DEFINE_uint64(thread_num, 10, "Total number of worker threads.");
45 | DEFINE_uint64(tuple_num, 1000000, "Total number of records.");
46 | DEFINE_bool(ycsb, true,
47 | "True uses zipf_skew, false uses faster random generator.");
48 | DEFINE_double(zipf_skew, 0, "zipf skew. 0 ~ 0.999...");
49 | #else
50 | DECLARE_uint64(clocks_per_us);
51 | DECLARE_uint64(extime);
52 | DECLARE_uint64(gc_inter_us);
53 | DECLARE_uint64(max_ope);
54 | DECLARE_uint64(pre_reserve_tmt_element);
55 | DECLARE_uint64(pre_reserve_version);
56 | DECLARE_bool(rmw);
57 | DECLARE_uint64(rratio);
58 | DECLARE_uint64(thread_num);
59 | DECLARE_uint64(tuple_num);
60 | DECLARE_bool(ycsb);
61 | DECLARE_double(zipf_skew);
62 | #endif
63 |
64 | #include "transaction.hh"
65 |
66 | alignas(CACHE_LINE_SIZE) GLOBAL Tuple *Table;
67 | alignas(CACHE_LINE_SIZE) GLOBAL
68 | TransactionTable **TMT; // Transaction Mapping Table
69 |
--------------------------------------------------------------------------------
/si/include/garbage_collection.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "../../include/inline.hh"
7 | #include "../../include/result.hh"
8 | #include "si_op_element.hh"
9 | #include "tuple.hh"
10 | #include "version.hh"
11 |
12 | // forward declaration
13 | class TransactionTable;
14 |
15 | class GarbageCollection {
16 | private:
17 | uint32_t fmin_, fmax_; // first range of txid in TMT.
18 | uint32_t smin_, smax_; // second range of txid in TMT.
19 |
20 | static std::atomic
21 | GC_threshold_; // share for all object (meaning all thread).
22 |
23 | public:
24 | // deque を使うのは,どこまでサイズが肥大するか不明瞭であるから.
25 | // vector のリサイズは要素の全コピーが発生するなどして重いから.
26 | #ifdef CCTR_ON
27 | std::deque gcq_for_TMT_;
28 | std::deque reuse_TMT_element_from_gc_;
29 | #endif // CCTR_ON
30 | std::deque > gcq_for_versions_;
31 | std::deque reuse_version_from_gc_;
32 | uint8_t thid_;
33 |
34 | GarbageCollection() {
35 | //#ifdef CCTR_ON
36 | // gcqForTMT.resize(1000);
37 | //#endif // CCTR_ON
38 | // gcqForVersion.resize(1000);
39 | }
40 |
41 | // for all thread
42 | INLINE uint32_t getGcThreshold() {
43 | return GC_threshold_.load(std::memory_order_acquire);
44 | }
45 | // -----
46 |
47 | // for leader thread
48 | bool chkSecondRange();
49 |
50 | void decideFirstRange();
51 |
52 | INLINE void decideGcThreshold() {
53 | GC_threshold_.store(fmin_, std::memory_order_release);
54 | }
55 |
56 | INLINE void mvSecondRangeToFirstRange() {
57 | fmin_ = smin_;
58 | fmax_ = smax_;
59 | }
60 | // -----
61 |
62 | // for worker thread
63 | void gcVersion(Result *sres_);
64 |
65 | #ifdef CCTR_ON
66 | void gcTMTElements(Result *sres_);
67 | #endif // CCTR_ON
68 | // -----
69 | };
70 |
71 | #ifdef GLOBAL_VALUE_DEFINE
72 | // declare in ermia.cc
73 | std::atomic GarbageCollection::GC_threshold_(0);
74 | #endif
75 |
--------------------------------------------------------------------------------
/si/include/result.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../../include/result.hh"
6 |
7 | extern std::vector SIResult;
8 |
9 | extern void initResult();
10 |
--------------------------------------------------------------------------------
/si/include/si_op_element.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../../include/op_element.hh"
4 |
5 | #include "transaction_table.hh"
6 | #include "version.hh"
7 |
8 | template
9 | class SetElement : public OpElement {
10 | public:
11 | using OpElement::OpElement;
12 |
13 | Version *ver_;
14 |
15 | SetElement(uint64_t key, T *rcdptr, Version *ver)
16 | : OpElement::OpElement(key, rcdptr) {
17 | this->ver_ = ver;
18 | }
19 |
20 | bool operator<(const SetElement &right) const {
21 | return this->key_ < right.key;
22 | }
23 | };
24 |
25 | template
26 | class GCElement : public OpElement {
27 | public:
28 | using OpElement::OpElement;
29 |
30 | Version *ver_;
31 | uint32_t cstamp_;
32 |
33 | GCElement() : OpElement::OpElement() {
34 | this->ver_ = nullptr;
35 | cstamp_ = 0;
36 | }
37 |
38 | GCElement(uint64_t key, T *rcdptr, Version *ver, uint32_t cstamp)
39 | : OpElement::OpElement(key, rcdptr) {
40 | this->ver_ = ver;
41 | this->cstamp_ = cstamp;
42 | }
43 | };
44 |
45 | class GCTMTElement {
46 | public:
47 | TransactionTable *tmt_;
48 |
49 | GCTMTElement() : tmt_(nullptr) {}
50 |
51 | GCTMTElement(TransactionTable *tmt) : tmt_(tmt) {}
52 | };
53 |
--------------------------------------------------------------------------------
/si/include/transaction.hh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include