diff options
| author | Joshua Bakita <jbakita@cs.unc.edu> | 2020-10-22 00:08:12 -0400 |
|---|---|---|
| committer | Joshua Bakita <jbakita@cs.unc.edu> | 2020-10-22 00:08:12 -0400 |
| commit | 3b0aa125061b362b23ecf66afe8319e3a268c874 (patch) | |
| tree | 9323b85d5a3a0d14e33a28caa9ffc3b8ce7225be /run_bench.sh | |
| parent | edb491490ccd0cae4bd28ca9c9a7e095a47c749b (diff) | |
Add pair benchmarking and isolation specification into run_bench.sh
This allows `run_bench.sh` to replace all previous general paired
benchmarking scripts. See `run_everything.sh` for an example of how
to use the new script.
This also fixes two critical bugs present in the old scripts:
1. The cpus_list was incorrectly set for resctrl when running
synchronous pair timing with L2+L3 isolation (i). Each write
to that file replaces the previous contents, and it was previously
written once for each core. This prevented the entire 1st core
from using any L3 cache.
2. The competing task list was indexed improperly in the asynchronous
pair timing script. This caused the competing task to always be
identical to the task being profiled.
These issues combine to imply that in the rejected RTSS'20 paper:
- All Level-C SMT timing data is suspect
- Level-A and -B SMT timing data with L2+L3 isolation (i) is
wildly optimistic
Diffstat (limited to 'run_bench.sh')
| -rwxr-xr-x | run_bench.sh | 261 |
1 files changed, 204 insertions, 57 deletions
diff --git a/run_bench.sh b/run_bench.sh index 4e09faa..250d843 100755 --- a/run_bench.sh +++ b/run_bench.sh | |||
| @@ -1,24 +1,43 @@ | |||
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | # Copyright 2020 Joshua Bakita | ||
| 3 | # A unified script for timing: | ||
| 4 | # - SMT pairs with synchronous launches (hard real-time methodolgy) | ||
| 5 | # - SMT pairs with asynchronous launches (soft real-time methodolgy) | ||
| 6 | # - Unpaired tasks | ||
| 7 | # - The cache alloc vs WSS setting exploration for DIS | ||
| 8 | # These can all be done with: | ||
| 9 | # - No cache management | ||
| 10 | # - L3 cache splitting | ||
| 11 | # - L2+L3 cache splitting (if OS supported) | ||
| 12 | |||
| 13 | if grep -q "#define LITMUS 1" ../extra.h ./extra.h 2> /dev/null; then | ||
| 14 | LITMUS=1 | ||
| 15 | fi | ||
| 2 | 16 | ||
| 3 | if [ $# -lt 5 ]; then | 17 | if [ $# -lt 5 ]; then |
| 4 | echo "Usage $0 -m MODE -p CPU -l LOOPS -b FILE [-c] RUN_ID" | 18 | echo "Usage $0 -m MODE -p CPU -l LOOPS -b FILE [-B] [-I] RUN_ID" |
| 5 | echo " -m base|dis Which benchmarking mode to use" | 19 | echo " -m base|dis|pair Which benchmarking mode to use" |
| 6 | echo " -p CPU Which CPU to run each benchmark on" | 20 | echo " -p CPU Which CPU to run each benchmark on" |
| 7 | echo " -l LOOPS How many loops of each benchmark to do" | 21 | echo " -l LOOPS How many loops of each benchmark to do" |
| 8 | echo " -b FILE List of benchmarks to execute. Optional tab-" | 22 | echo " -b FILE List of benchmarks to execute. Optional tab-" |
| 9 | echo " delimited 2nd column specifies an input" | 23 | echo " delimited 2nd column specifies an input" |
| 10 | echo " generation command (fed to bench via stdin)" | 24 | echo " generation command (fed to bench via stdin)" |
| 11 | echo " -B Enable background contenders on other CCXes" | 25 | echo " -B Enable background contenders on other CCXes" |
| 26 | echo " -I xi|i3|i Isolation mode: none (xi) (default), way-based" | ||
| 27 | echo " L3-only (i3), or color-based L2+L3 (i)" | ||
| 12 | echo "Mode base requires no additional options." | 28 | echo "Mode base requires no additional options." |
| 13 | echo "Mode dis does not support the 2nd col. of -b and needs:" | 29 | echo "Mode dis does not support the 2nd col. of -b and needs:" |
| 14 | echo " -W FILE List of working set sizes to pass gen_input.py" | 30 | echo " -W FILE List of working set sizes to pass gen_input.py" |
| 15 | echo " -T FILE Input template to pass to gen_input.py" | 31 | echo " -T FILE Input template to pass to gen_input.py" |
| 16 | echo " -C FILE List of cache configurations to test" | 32 | echo " -C FILE List of cache configurations to test" |
| 17 | exit | 33 | echo "Mode pair options:" |
| 34 | echo " -P CPU CPU to run the 2nd benchmark on" | ||
| 35 | echo " -A Async. (Don't synchronize the pair at job" | ||
| 36 | echo " boundries.) Typically used SMT in soft realtime" | ||
| 18 | fi | 37 | fi |
| 19 | 38 | ||
| 20 | # Name options similarly to rtspin | 39 | # Name options similarly to rtspin |
| 21 | while getopts “m:p:l:b:BW:T:C:” opt; do | 40 | while getopts “m:p:l:b:BI:W:T:C:P:A” opt; do |
| 22 | case $opt in | 41 | case $opt in |
| 23 | # Required | 42 | # Required |
| 24 | m) mode=$OPTARG ;; | 43 | m) mode=$OPTARG ;; |
| @@ -27,9 +46,14 @@ while getopts “m:p:l:b:BW:T:C:” opt; do | |||
| 27 | b) benchNames=$OPTARG ;; | 46 | b) benchNames=$OPTARG ;; |
| 28 | # Optional | 47 | # Optional |
| 29 | B) contend=1 ;; | 48 | B) contend=1 ;; |
| 49 | I) iso_mode=$OPTARG ;; | ||
| 50 | # DIS | ||
| 30 | W) wss_settings=$OPTARG ;; | 51 | W) wss_settings=$OPTARG ;; |
| 31 | T) template_input=$OPTARG ;; | 52 | T) template_input=$OPTARG ;; |
| 32 | C) cache_settings=$OPTARG ;; | 53 | C) cache_settings=$OPTARG ;; |
| 54 | # Pair | ||
| 55 | P) core_two=$OPTARG ;; | ||
| 56 | A) async=1 ;; | ||
| 33 | esac | 57 | esac |
| 34 | done | 58 | done |
| 35 | # Reset to read operands | 59 | # Reset to read operands |
| @@ -37,7 +61,7 @@ shift $((OPTIND -1)) | |||
| 37 | userRunID=$1 | 61 | userRunID=$1 |
| 38 | 62 | ||
| 39 | # Required argument checking | 63 | # Required argument checking |
| 40 | if [[ "$mode" != "base" ]] && [[ "$mode" != "dis" ]]; then | 64 | if [[ "$mode" != "base" && "$mode" != "dis" && $mode != pair ]]; then |
| 41 | echo "Invalid argument: MODE must be either 'base' or 'dis'" | 65 | echo "Invalid argument: MODE must be either 'base' or 'dis'" |
| 42 | exit | 66 | exit |
| 43 | fi | 67 | fi |
| @@ -72,14 +96,37 @@ if [[ "$mode" == "dis" ]] && [[ ! -f "$cache_settings" ]]; then | |||
| 72 | exit | 96 | exit |
| 73 | fi | 97 | fi |
| 74 | 98 | ||
| 99 | # Pair argument checking | ||
| 100 | if [[ "$mode" == "pair" && ! -v core_two ]]; then | ||
| 101 | echo "Missing argument: mode=pair reqires -P" | ||
| 102 | exit | ||
| 103 | fi | ||
| 104 | if [[ "$mode" != "pair" ]] && [[ -v async || -v core_two ]]; then | ||
| 105 | echo "Invalid argument: -A and -P require mode=pair" | ||
| 106 | exit | ||
| 107 | fi | ||
| 108 | |||
| 109 | # Additional checks | ||
| 110 | if [[ $userRunID == "" ]]; then | ||
| 111 | echo "Missing argument: a run ID is required" | ||
| 112 | exit | ||
| 113 | fi | ||
| 114 | if [[ -v contend && ! -f "/playpen/mc2/imx6q-thrasher/thrasher" ]]; then | ||
| 115 | echo "ERROR: cannot find thrasher binary for -B. Exiting..." | ||
| 116 | exit | ||
| 117 | fi | ||
| 118 | if [[ $iso_mode == "i" && ! $(uname -a | grep "mc2") ]]; then | ||
| 119 | echo "Isolation mode 'i' requires the MC^2 kernel. Exiting..." | ||
| 120 | exit | ||
| 121 | fi | ||
| 122 | |||
| 75 | # Check permissions and update state | 123 | # Check permissions and update state |
| 76 | if [ "$EUID" -ne 0 ] | 124 | if [[ "$EUID" != 0 ]]; then |
| 77 | then | ||
| 78 | echo "You need to be root to enable interrupt isolation and real-time execution!" | 125 | echo "You need to be root to enable interrupt isolation and real-time execution!" |
| 79 | exit | 126 | exit |
| 80 | fi | 127 | fi |
| 81 | 128 | ||
| 82 | echo "Done. Loading benchmark names and input..." | 129 | echo "Loading benchmark names and input..." |
| 83 | 130 | ||
| 84 | # Read the names of each benchmark and load input. | 131 | # Read the names of each benchmark and load input. |
| 85 | # This might look a bit scary, but all it does is | 132 | # This might look a bit scary, but all it does is |
| @@ -96,11 +143,16 @@ done < $benchNames | |||
| 96 | echo "Making sure that binaries are up to date..." | 143 | echo "Making sure that binaries are up to date..." |
| 97 | 144 | ||
| 98 | for b in ${bench[@]}; do | 145 | for b in ${bench[@]}; do |
| 99 | make bin/$b | 146 | # Build "bin/bench" if bin directory |
| 100 | if [[ $? ]]; then | 147 | if [[ -d bin ]]; then |
| 148 | make bin/$b | ||
| 149 | fi | ||
| 150 | # If that failed, try a different name | ||
| 151 | if [[ "$?" != 0 || ! -d bin ]]; then | ||
| 101 | make $b | 152 | make $b |
| 102 | fi | 153 | fi |
| 103 | if [[ ! -f $b && ! -f "./bin/$b" ]]; then | 154 | # If bench is still not in bin or curr dir, fail |
| 155 | if [[ ! -f "./$b" && ! -f "./bin/$b" ]]; then | ||
| 104 | echo "Unable to find benchmark $b" | 156 | echo "Unable to find benchmark $b" |
| 105 | exit | 157 | exit |
| 106 | fi | 158 | fi |
| @@ -123,26 +175,86 @@ do | |||
| 123 | i=$(( $i + 1 )) | 175 | i=$(( $i + 1 )) |
| 124 | done | 176 | done |
| 125 | 177 | ||
| 178 | echo "Done. Creating cleanup handler..." | ||
| 179 | function cleanup { | ||
| 180 | # End contending tasks | ||
| 181 | if [[ -v contend ]]; then | ||
| 182 | killall thrasher | ||
| 183 | fi | ||
| 184 | |||
| 185 | # Restore cache access to everyone | ||
| 186 | echo "L3:0=ffff;1=ffff;2=ffff;3=ffff" > /sys/fs/resctrl/schemata | ||
| 187 | if [[ -e /sys/fs/resctrl/benchmarks ]]; then | ||
| 188 | echo "" > /sys/fs/resctrl/benchmarks/cpus_list | ||
| 189 | fi | ||
| 190 | if [[ -e /sys/fs/resctrl/benchmarks2 ]]; then | ||
| 191 | echo "" > /sys/fs/resctrl/benchmarks2/cpus_list | ||
| 192 | fi | ||
| 193 | |||
| 194 | # Put smp_affinty back the way it was | ||
| 195 | i=0 | ||
| 196 | for IRQ in /proc/irq/* | ||
| 197 | do | ||
| 198 | if [ -d $IRQ ]; then | ||
| 199 | echo ${irqList[$i]} 2> /dev/null > $IRQ/smp_affinity_list | ||
| 200 | fi | ||
| 201 | i=$(( $i + 1 )) | ||
| 202 | done | ||
| 203 | } | ||
| 204 | # This sets the cleanup function to be called when we exit for any reason | ||
| 205 | trap cleanup EXIT | ||
| 206 | |||
| 126 | echo "Done. Checking for wbinvd module..." | 207 | echo "Done. Checking for wbinvd module..." |
| 127 | if [[ ! -f "/proc/wbinvd" ]]; then | 208 | if [[ ! -f "/proc/wbinvd" ]]; then |
| 128 | echo "ERROR: wbinvd module not loaded. Exiting..." | 209 | echo "ERROR: wbinvd module not loaded. Exiting..." |
| 129 | exit | 210 | exit |
| 130 | fi | 211 | fi |
| 131 | 212 | ||
| 132 | echo "Done. Setting core $core to 'performance'..." | 213 | echo "Done. Setting cores to 'performance'..." |
| 133 | echo "performance" > /sys/devices/system/cpu/cpu$core/cpufreq/scaling_governor | 214 | echo "performance" > /sys/devices/system/cpu/cpu$core/cpufreq/scaling_governor |
| 215 | if [[ -v core_two ]]; then | ||
| 216 | echo "performance" > /sys/devices/system/cpu/cpu$core_two/cpufreq/scaling_governor | ||
| 217 | fi | ||
| 134 | 218 | ||
| 135 | # Enable L3 isolation | 219 | # Enable L3 isolation |
| 136 | echo "Done. Enabling L3 isolation..." | 220 | echo "Done. Setting up L3 isolation..." |
| 137 | mount -t resctrl resctrl /sys/fs/resctrl | ||
