From 9fd0fbebe69b61bce9b3d83e752052802f76d70c Mon Sep 17 00:00:00 2001 From: Yangzheng Bai Date: Thu, 21 Jun 2018 18:46:46 -0500 Subject: [PATCH 1/4] Change -o core separator from comma to colon Because we use comma separated value file format for the output, it's better to use colon instead of comma to separate -o arguments. We also split lh_test_cfg.yaml into two config file: sweeptest and unittest, because these two tests normally don't run together. We also modified runall.sh to use test_lockhammer.py instead of plain bash script. --- ...lh_test_cfg.yaml => lh_sweeptest_cfg.yaml} | 56 +---------- .../lockhammer/scripts/lh_unittest_cfg.yaml | 93 +++++++++++++++++++ benchmarks/lockhammer/scripts/runall.sh | 25 +---- .../lockhammer/scripts/runall_obsolete.sh | 53 +++++++++++ .../lockhammer/scripts/test_lockhammer.py | 25 +++-- benchmarks/lockhammer/src/lockhammer.c | 7 +- 6 files changed, 170 insertions(+), 89 deletions(-) rename benchmarks/lockhammer/scripts/{lh_test_cfg.yaml => lh_sweeptest_cfg.yaml} (72%) create mode 100644 benchmarks/lockhammer/scripts/lh_unittest_cfg.yaml create mode 100755 benchmarks/lockhammer/scripts/runall_obsolete.sh diff --git a/benchmarks/lockhammer/scripts/lh_test_cfg.yaml b/benchmarks/lockhammer/scripts/lh_sweeptest_cfg.yaml similarity index 72% rename from benchmarks/lockhammer/scripts/lh_test_cfg.yaml rename to benchmarks/lockhammer/scripts/lh_sweeptest_cfg.yaml index c9cc62c..defa3af 100644 --- a/benchmarks/lockhammer/scripts/lh_test_cfg.yaml +++ b/benchmarks/lockhammer/scripts/lh_sweeptest_cfg.yaml @@ -37,6 +37,7 @@ globalcfg: execdir: ../build logfile: lockhammer.csv + ## Sweep Test Settings # # Common assumptions for sweeptest: @@ -50,7 +51,7 @@ globalcfg: # ## sweeptest: - enabled: False + enabled: True safemode: False cmd: - lh_cas_event_mutex @@ -89,56 +90,3 @@ sweeptest: c: 1000ns p: 5000ns o: lstopo - -## Unittest Settings -# -# Common assumptions for unittest: -# Only cover functional correctness, use as least time as possible -# Normal runtime should be around 1 minute -# t=0 means maximum core count -# -## -unittest: - enabled: True - safemode: True - testcase: - - cmd: - - lh_cas_event_mutex - - lh_cas_lockref - - lh_cas_rw_lock - - lh_empty - - lh_event_mutex - - lh_incdec_refcount - - lh_jvm_objectmonitor - - lh_osq_lock - - lh_queued_spinlock - - lh_swap_mutex - - lh_tbb_spin_rw_mutex - - lh_ticket_spinlock - cmd_aarch64: [lh_hybrid_spinlock, lh_hybrid_spinlock_fastdequeue] - cmd_x86_64: - t: [1, 0] - a: 100 - c: [0ns, 50ns] - p: [0ns, 50ns] - - - cmd: lh_osq_lock - t: [1, 0] - a: 100 - c: 50ns - p: 0ns - o: lstopo - extra: - u: 10 - s: 2 - - - cmd: lh_tbb_spin_rw_mutex - t: [1, 0] - a: 100 - c: 50ns - p: 0ns - i: 1 - o: '0,1,2,3' - extra: - r: 4 - m: 1 diff --git a/benchmarks/lockhammer/scripts/lh_unittest_cfg.yaml b/benchmarks/lockhammer/scripts/lh_unittest_cfg.yaml new file mode 100644 index 0000000..c4fcd85 --- /dev/null +++ b/benchmarks/lockhammer/scripts/lh_unittest_cfg.yaml @@ -0,0 +1,93 @@ +# Copyright (c) 2018, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, this +# list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. +# +# Neither the name of ARM Limited nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of this project. + + +## Global Settings +globalcfg: + execdir: ../build + logfile: lockhammer.csv + + +## Unittest Settings +# +# Common assumptions for unittest: +# Only cover functional correctness, use as least time as possible +# Normal runtime should be around 1 minute +# t=0 means maximum core count +# o=lstopo means using lstopo output as preferred thread pinning order +# +## +unittest: + enabled: True + safemode: True + testcase: + - cmd: + - lh_cas_event_mutex + - lh_cas_lockref + - lh_cas_rw_lock + - lh_empty + - lh_event_mutex + - lh_incdec_refcount + - lh_jvm_objectmonitor + - lh_osq_lock + - lh_queued_spinlock + - lh_swap_mutex + - lh_tbb_spin_rw_mutex + - lh_ticket_spinlock + cmd_aarch64: [lh_hybrid_spinlock, lh_hybrid_spinlock_fastdequeue] + cmd_x86_64: + t: [1, 0] + a: 100 + c: [0ns, 50ns] + p: [0ns, 50ns] + + - cmd: lh_osq_lock + t: [1, 0] + a: 100 + c: 50ns + p: 0ns + o: lstopo + extra: + u: 10 + s: 2 + + - cmd: lh_tbb_spin_rw_mutex + t: [1, 0] + a: 100 + c: 50ns + p: 0ns + i: 1 + o: '0:1:2:3' + extra: + r: 4 + m: 1 diff --git a/benchmarks/lockhammer/scripts/runall.sh b/benchmarks/lockhammer/scripts/runall.sh index 0ec8e27..7c9ab77 100755 --- a/benchmarks/lockhammer/scripts/runall.sh +++ b/benchmarks/lockhammer/scripts/runall.sh @@ -27,27 +27,4 @@ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -./sweep.sh incdec_refcount 0 0 > incdec_refcount_0_0_$HOSTNAME.csv -./sweep.sh cas_lockref 0 0 > cas_lockref_0_0_$HOSTNAME.csv -./sweep.sh cas_lockref 2000 1000 > cas_lockref_2000_1000_$HOSTNAME.csv -./sweep.sh ticket_spinlock 0 0 > ticket_spinlock_0_0_$HOSTNAME.csv -./sweep.sh ticket_spinlock 1000 5000 > ticket_spinlock_1000_5000_$HOSTNAME.csv -./sweep.sh queued_spinlock 0 0 > queued_spinlock_0_0_$HOSTNAME.csv -./sweep.sh queued_spinlock 1000 5000 > queued_spinlock_1000_5000_$HOSTNAME.csv -./sweep.sh event_mutex 0 0 > event_mutex_0_0_$HOSTNAME.csv -./sweep.sh event_mutex 1000 5000 > event_mutex_1000_5000_$HOSTNAME.csv -./sweep.sh cas_event_mutex 0 0 > cas_event_mutex_0_0_$HOSTNAME.csv -./sweep.sh cas_event_mutex 1000 5000 > cas_event_mutex_1000_5000_$HOSTNAME.csv -./sweep.sh cas_rw_lock 0 0 > cas_rw_lock_0_0_$HOSTNAME.csv -./sweep.sh cas_rw_lock 2000 1000 > cas_rw_lock_2000_1000_$HOSTNAME.csv -./sweep.sh hybrid_spinlock 0 0 > hybrid_spinlock_0_0_$HOSTNAME.csv -./sweep.sh hybrid_spinlock 1000 5000 > hybrid_spinlock_1000_5000_$HOSTNAME.csv -./sweep.sh hybrid_spinlock_fastdequeue 0 0 > hybrid_spinlock_fastdequeue_0_0_$HOSTNAME.csv -./sweep.sh hybrid_spinlock_fastdequeue 1000 5000 > hybrid_spinlock_fastdequeue_1000_5000_$HOSTNAME.csv -./sweep.sh empty 0 0 > empty_0_0_$HOSTNAME.csv -./sweep.sh jvm_objectmonitor 0 0 > jvm_objectmonitor_0_0_$HOSTNAME.csv -./sweep.sh jvm_objectmonitor 1000 5000 > jvm_objectmonitor_1000_5000_$HOSTNAME.csv -./sweep.sh swap_mutex 0 0 > swap_mutex_0_0_$HOSTNAME.csv -./sweep.sh swap_mutex 1000 5000 > swap_mutex_1000_5000_$HOSTNAME.csv -./sweep.sh spin_rw_mutex 0 0 > spin_rw_mutex_0_0_$HOSTNAME.csv -./sweep.sh spin_rw_mutex 1000 5000 > spin_rw_mutex_1000_5000_$HOSTNAME.csv +nohup sudo ./test_lockhammer.py lh_sweeptest_cfg.yaml & diff --git a/benchmarks/lockhammer/scripts/runall_obsolete.sh b/benchmarks/lockhammer/scripts/runall_obsolete.sh new file mode 100755 index 0000000..0ec8e27 --- /dev/null +++ b/benchmarks/lockhammer/scripts/runall_obsolete.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Copyright (c) 2017, The Linux Foundation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of The Linux Foundation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +./sweep.sh incdec_refcount 0 0 > incdec_refcount_0_0_$HOSTNAME.csv +./sweep.sh cas_lockref 0 0 > cas_lockref_0_0_$HOSTNAME.csv +./sweep.sh cas_lockref 2000 1000 > cas_lockref_2000_1000_$HOSTNAME.csv +./sweep.sh ticket_spinlock 0 0 > ticket_spinlock_0_0_$HOSTNAME.csv +./sweep.sh ticket_spinlock 1000 5000 > ticket_spinlock_1000_5000_$HOSTNAME.csv +./sweep.sh queued_spinlock 0 0 > queued_spinlock_0_0_$HOSTNAME.csv +./sweep.sh queued_spinlock 1000 5000 > queued_spinlock_1000_5000_$HOSTNAME.csv +./sweep.sh event_mutex 0 0 > event_mutex_0_0_$HOSTNAME.csv +./sweep.sh event_mutex 1000 5000 > event_mutex_1000_5000_$HOSTNAME.csv +./sweep.sh cas_event_mutex 0 0 > cas_event_mutex_0_0_$HOSTNAME.csv +./sweep.sh cas_event_mutex 1000 5000 > cas_event_mutex_1000_5000_$HOSTNAME.csv +./sweep.sh cas_rw_lock 0 0 > cas_rw_lock_0_0_$HOSTNAME.csv +./sweep.sh cas_rw_lock 2000 1000 > cas_rw_lock_2000_1000_$HOSTNAME.csv +./sweep.sh hybrid_spinlock 0 0 > hybrid_spinlock_0_0_$HOSTNAME.csv +./sweep.sh hybrid_spinlock 1000 5000 > hybrid_spinlock_1000_5000_$HOSTNAME.csv +./sweep.sh hybrid_spinlock_fastdequeue 0 0 > hybrid_spinlock_fastdequeue_0_0_$HOSTNAME.csv +./sweep.sh hybrid_spinlock_fastdequeue 1000 5000 > hybrid_spinlock_fastdequeue_1000_5000_$HOSTNAME.csv +./sweep.sh empty 0 0 > empty_0_0_$HOSTNAME.csv +./sweep.sh jvm_objectmonitor 0 0 > jvm_objectmonitor_0_0_$HOSTNAME.csv +./sweep.sh jvm_objectmonitor 1000 5000 > jvm_objectmonitor_1000_5000_$HOSTNAME.csv +./sweep.sh swap_mutex 0 0 > swap_mutex_0_0_$HOSTNAME.csv +./sweep.sh swap_mutex 1000 5000 > swap_mutex_1000_5000_$HOSTNAME.csv +./sweep.sh spin_rw_mutex 0 0 > spin_rw_mutex_0_0_$HOSTNAME.csv +./sweep.sh spin_rw_mutex 1000 5000 > spin_rw_mutex_1000_5000_$HOSTNAME.csv diff --git a/benchmarks/lockhammer/scripts/test_lockhammer.py b/benchmarks/lockhammer/scripts/test_lockhammer.py index cd66357..6de32bc 100755 --- a/benchmarks/lockhammer/scripts/test_lockhammer.py +++ b/benchmarks/lockhammer/scripts/test_lockhammer.py @@ -49,7 +49,7 @@ # config file should be in the same directory of this script -LH_CFG = "lh_test_cfg.yaml" +LH_CFG = "lh_unittest_cfg.yaml" # lockhammer.c has these parameters LH_ARGU_LIST = ['t', 'a', 'c', 'p', 'i', 'o'] @@ -144,9 +144,9 @@ def parse_lstopo(): for line in out.splitlines(): match = re.search("P#(\d+)", line.strip()) if match: - result += (match.group(1) + ',') + result += (match.group(1) + ':') finally: - if result[-1] == ',': + if result[-1] == ':': result = result[:-1] # sample output for single-socket EPYC 7601 server: @@ -272,7 +272,9 @@ def generate_unittest(className, lhCfg, testCfg): logFile = default_value(globalCfg, 'logfile', None) safeMode = default_value(unitCfg, 'safemode', True) - prepare_logfile(logFile) + if logFile: + logFile = socket.gethostname() + '_' + logFile + prepare_logfile(logFile) allCmd = [] if isinstance(testCfg['cmd'], list): @@ -326,7 +328,10 @@ def generate_sweeptest(className, lhCfg): lhCommand = default_value(sweepCfg, 'cmd', []) lhArgument = default_value(sweepCfg, 'argulist', [{}]) - prepare_logfile(logFile) + if logFile: + logFile = socket.gethostname() + '_' + logFile + prepare_logfile(logFile) + sweepList = calc_sweep_list(arguMax, skipSince, skipStep) append_arch_cmd(sweepCfg, lhCommand) @@ -357,10 +362,14 @@ def build_sweep_test(lhCfg): sys.exit(2) -# main function +# test_lockhammer.py [local_yaml_config_file_without_extension] if __name__ == "__main__": - lhConfig = read_config(os.path.join(os.path.dirname(os.path.abspath(__file__)), LH_CFG)) + if len(sys.argv) == 2: + lhConfigFullPath = os.path.join(os.path.dirname(os.path.abspath(__file__)), sys.argv[1]) + else: + lhConfigFullPath = os.path.join(os.path.dirname(os.path.abspath(__file__)), LH_CFG) + lhConfig = read_config(lhConfigFullPath) pprint.pprint(lhConfig) build_unit_test(lhConfig) build_sweep_test(lhConfig) - unittest.main(verbosity=2) + unittest.main(argv=['first-arg-is-ignored'], verbosity=2) diff --git a/benchmarks/lockhammer/src/lockhammer.c b/benchmarks/lockhammer/src/lockhammer.c index d6eeb31..4004f3e 100644 --- a/benchmarks/lockhammer/src/lockhammer.c +++ b/benchmarks/lockhammer/src/lockhammer.c @@ -175,10 +175,11 @@ int main(int argc, char** argv) case 'o': args.pinorder = calloc(num_cores, sizeof(int)); if (args.pinorder == NULL) { - fprintf(stderr, "ERROR: Cannot allocate enough memory for pinorder structure.\n"); + fprintf(stderr, "ERROR: cannot allocate enough memory for pinorder structure.\n"); return 1; } - csv = strtok(optarg, ","); + /* colon is better than comma because lockhammer output uses csv format */ + csv = strtok(optarg, ":"); for (int i = 0; i < num_cores && csv != NULL; ++i) { optval = strtol(csv, (char **) NULL, 10); @@ -187,7 +188,7 @@ int main(int argc, char** argv) } else { fprintf(stderr, "WARNING: core number %ld is out of range.\n", optval); } - csv = strtok(NULL, ","); + csv = strtok(NULL, ":"); } break; case 's': From 44dc370ce3a17c3c2a0e49b332b209fb0bff9e8c Mon Sep 17 00:00:00 2001 From: Yangzheng Bai Date: Thu, 21 Jun 2018 18:54:57 -0500 Subject: [PATCH 2/4] Minor change on comments --- benchmarks/lockhammer/scripts/test_lockhammer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/lockhammer/scripts/test_lockhammer.py b/benchmarks/lockhammer/scripts/test_lockhammer.py index 6de32bc..f57ec76 100755 --- a/benchmarks/lockhammer/scripts/test_lockhammer.py +++ b/benchmarks/lockhammer/scripts/test_lockhammer.py @@ -362,7 +362,7 @@ def build_sweep_test(lhCfg): sys.exit(2) -# test_lockhammer.py [local_yaml_config_file_without_extension] +# test_lockhammer.py [local_yaml_config_filename] if __name__ == "__main__": if len(sys.argv) == 2: lhConfigFullPath = os.path.join(os.path.dirname(os.path.abspath(__file__)), sys.argv[1]) From bd7c5badec720bd9b072e2b8be83dc8d70a688dc Mon Sep 17 00:00:00 2001 From: Yangzheng Bai Date: Fri, 22 Jun 2018 10:39:29 -0500 Subject: [PATCH 3/4] Minor changes for default help messages Let help be more readable... --- benchmarks/lockhammer/src/lockhammer.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/benchmarks/lockhammer/src/lockhammer.c b/benchmarks/lockhammer/src/lockhammer.c index 4004f3e..9f100c1 100644 --- a/benchmarks/lockhammer/src/lockhammer.c +++ b/benchmarks/lockhammer/src/lockhammer.c @@ -56,18 +56,17 @@ void* hmr(void *); void print_usage (char *invoc) { fprintf(stderr, - "Usage: %s\n\t[-t threads]\n\t[-a acquires per thread]\n\t" + "Usage: %s\n\t[-t <#> threads]\n\t[-a <#> acquires per thread]\n\t" "[-c <#>[ns | in] critical iterations measured in ns or (in)structions, " "if no suffix, assumes instructions]\n\t" "[-p <#>[ns | in] parallelizable iterations measured in ns or (in)structions, " "if no suffix, assumes (in)structions]\n\t" - "[-s safe-mode operation for running as non-root\n\t" - "[-i interleave value for thread pinning order, for example, 1 means " - "sequential increasing, 2 means pinning hyperthread of the same core first " - "before the next core.]\n\t" - "[-o arbitrary core pinning order separated by comma without space, command " - "lstopo can be used to deduce the correct order.]\n\t" - "[-- ]\n", invoc); + "[-s safe-mode operation for running as non-root by reducing priority]\n\t" + "[-i <#> interleave value for SMT pinning, e.g. 1: core pinning / no SMT, " + "2: 2-way SMT pinning, 4: 4-way SMT pinning, may not work for multisocket]\n\t" + "[-o <#:#:#:#> arbitrary pinning order separated by colon without space, " + "command lstopo can be used to deduce the correct order]\n\t" + "[-- ]\n", invoc); } int main(int argc, char** argv) From 7b76780a3f0c99a8b0107c4baba23a72179317a6 Mon Sep 17 00:00:00 2001 From: Yangzheng Bai Date: Wed, 1 Aug 2018 14:10:34 -0500 Subject: [PATCH 4/4] Support both comma and colon as -o delimiter Default output will still use comma as delimiter like csv file. test_lockhammer.py will generate colon as delimiter in default runall.sh --- benchmarks/lockhammer/src/lockhammer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/benchmarks/lockhammer/src/lockhammer.c b/benchmarks/lockhammer/src/lockhammer.c index 9f100c1..217cb2e 100644 --- a/benchmarks/lockhammer/src/lockhammer.c +++ b/benchmarks/lockhammer/src/lockhammer.c @@ -177,8 +177,8 @@ int main(int argc, char** argv) fprintf(stderr, "ERROR: cannot allocate enough memory for pinorder structure.\n"); return 1; } - /* colon is better than comma because lockhammer output uses csv format */ - csv = strtok(optarg, ":"); + /* support both comma and colon as delimiter */ + csv = strtok(optarg, ",:"); for (int i = 0; i < num_cores && csv != NULL; ++i) { optval = strtol(csv, (char **) NULL, 10); @@ -187,7 +187,7 @@ int main(int argc, char** argv) } else { fprintf(stderr, "WARNING: core number %ld is out of range.\n", optval); } - csv = strtok(NULL, ":"); + csv = strtok(NULL, ",:"); } break; case 's':