diff options
| author | leochanj <jbakita@cs.unc.edu> | 2020-10-23 00:13:06 -0400 |
|---|---|---|
| committer | leochanj <jbakita@cs.unc.edu> | 2020-10-23 00:13:06 -0400 |
| commit | d427b910baffcc330b0b24d87c9b3216f306d0fb (patch) | |
| tree | ef312bc5757860a03673316be421c1624a5bb6b7 /run_bench.sh | |
| parent | b839934c04b214c9bdab399628ee2b94a65bcd10 (diff) | |
| parent | a7c3210215bd1181ae93b23c313941dfb44519fb (diff) | |
merged
Diffstat (limited to 'run_bench.sh')
| -rwxr-xr-x | run_bench.sh | 384 |
1 files changed, 313 insertions, 71 deletions
diff --git a/run_bench.sh b/run_bench.sh index c5b67b6..ddc6bcc 100755 --- a/run_bench.sh +++ b/run_bench.sh | |||
| @@ -1,30 +1,162 @@ | |||
| 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) | ||
| 2 | 12 | ||
| 3 | core=$1 | 13 | if grep -q "#define LITMUS 1" ../extra.h ./extra.h 2> /dev/null; then |
| 4 | maxJobs=$2 | 14 | LITMUS=1 |
| 5 | userRunID=$3 | 15 | fi |
| 6 | tacleNames=tacleNames.txt | 16 | |
| 17 | if [ $# -lt 5 ]; then | ||
| 18 | echo "Usage $0 -m MODE -p CPU -l LOOPS -b FILE [-B] [-I] RUN_ID" | ||
| 19 | echo " -m base|dis|pair Which benchmarking mode to use" | ||
| 20 | echo " -p CPU Which CPU to run each benchmark on" | ||
| 21 | echo " -l LOOPS How many loops of each benchmark to do" | ||
| 22 | echo " -b FILE List of benchmarks to execute. Optional tab-" | ||
| 23 | echo " delimited 2nd column specifies an input" | ||
| 24 | echo " generation command (fed to bench via stdin)" | ||
| 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)" | ||
| 28 | echo "Mode base requires no additional options." | ||
| 29 | echo "Mode dis does not support the 2nd col. of -b and needs:" | ||
| 30 | echo " -W FILE List of working set sizes to pass gen_input.py" | ||
| 31 | echo " -T FILE Input template to pass to gen_input.py" | ||
| 32 | echo " -C FILE List of cache configurations to test" | ||
| 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" | ||
| 37 | fi | ||
| 38 | |||
| 39 | # Name options similarly to rtspin | ||
| 40 | while getopts “m:p:l:b:BI:W:T:C:P:A” opt; do | ||
| 41 | case $opt in | ||
| 42 | # Required | ||
| 43 | m) mode=$OPTARG ;; | ||
| 44 | p) core=$OPTARG ;; | ||
| 45 | l) maxJobs=$OPTARG ;; | ||
| 46 | b) benchNames=$OPTARG ;; | ||
| 47 | # Optional | ||
| 48 | B) contend=1 ;; | ||
| 49 | I) iso_mode=$OPTARG ;; | ||
| 50 | # DIS | ||
| 51 | W) wss_settings=$OPTARG ;; | ||
| 52 | T) template_input=$OPTARG ;; | ||
| 53 | C) cache_settings=$OPTARG ;; | ||
| 54 | # Pair | ||
| 55 | P) core_two=$OPTARG ;; | ||
| 56 | A) async=1 ;; | ||
| 57 | esac | ||
| 58 | done | ||
| 59 | # Reset to read operands | ||
| 60 | shift $((OPTIND -1)) | ||
| 61 | userRunID=$1 | ||
| 62 | |||
| 63 | # Required argument checking | ||
| 64 | if [[ "$mode" != "base" && "$mode" != "dis" && $mode != pair ]]; then | ||
| 65 | echo "Invalid argument: MODE must be either 'base' or 'dis'" | ||
| 66 | exit | ||
| 67 | fi | ||
| 68 | if [[ ! -v core ]] || [[ ! -v maxJobs ]] || [[ ! -v benchNames ]]; then | ||
| 69 | echo "Missing argument: -p, -l, and -b are required" | ||
| 70 | exit | ||
| 71 | fi | ||
| 72 | if [[ ! -f "$benchNames" ]]; then | ||
| 73 | echo "Invalid argument: $benchNames des not exist" | ||
| 74 | exit | ||
| 75 | fi | ||
| 76 | if [[ ! -v userRunID ]]; then | ||
| 77 | echo "Missing argument: RUN_ID is required" | ||
| 78 | exit | ||
| 79 | fi | ||
| 80 | |||
| 81 | # DIS argument checking | ||
| 82 | if [[ "$mode" == "dis" ]] && [[ ! -v wss_settings || ! -v template_input || -z $cache_settings ]]; then | ||
| 83 | echo "Missing argument: DIS needs -W FILE -T FILE and -C FILE" | ||
| 84 | exit | ||
| 85 | fi | ||
| 86 | if [[ "$mode" == "dis" ]] && [[ ! -f "$wss_settings" ]]; then | ||
| 87 | echo "Invalid argument: $wss_settings does not exist" | ||
| 88 | exit | ||
| 89 | fi | ||
| 90 | if [[ "$mode" == "dis" ]] && [[ ! -f "$template_input" ]]; then | ||
| 91 | echo "Invalid argument: $template_input does not exist" | ||
| 92 | exit | ||
| 93 | fi | ||
| 94 | if [[ "$mode" == "dis" ]] && [[ ! -f "$cache_settings" ]]; then | ||
| 95 | echo "Invalid argument: $cache_settings does not exist" | ||
| 96 | exit | ||
| 97 | fi | ||
| 7 | 98 | ||
| 8 | if [ $# -lt 3 ]; then | 99 | # Pair argument checking |
| 9 | echo "Usage $0 <core ID> <number of iterations> <run ID> [TACLe names file] [--contend]" | 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" | ||
| 10 | exit | 106 | exit |
| 11 | fi | 107 | fi |
| 12 | 108 | ||
| 13 | if [ $# -gt 3 ]; then | 109 | # Additional checks |
| 14 | echo "Using alternate list of TACLe benchmarks from $4" | 110 | if [[ $userRunID == "" ]]; then |
| 15 | tacleNames=$4 | 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 | ||
| 16 | fi | 121 | fi |
| 17 | 122 | ||
| 18 | if [ "$EUID" -ne 0 ] | 123 | # Check permissions and update state |
| 19 | then | 124 | if [[ "$EUID" != 0 ]]; then |
| 20 | 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!" |
| 21 | exit | 126 | exit |
| 22 | fi | 127 | fi |
| 23 | 128 | ||
| 24 | echo "Making sure that binaries are up to date..." | 129 | echo "Loading benchmark names and input..." |
| 130 | |||
| 131 | # Read the names of each benchmark and load input. | ||
| 132 | # This might look a bit scary, but all it does is | ||
| 133 | # separate the two fields (1 or more tabs in-between), | ||
| 134 | # save the benchmark name, and execute the input | ||
| 135 | # command (storing its output in-memory for later). | ||
| 136 | j=0 | ||
| 137 | IFS=$'\r\n' | ||
| 25 | while read i; do | 138 | while read i; do |
| 26 | make bin/$i | 139 | bench[$j]=$(echo $i | tr -s "\t" | cut -f1) |
| 27 | done < $tacleNames | 140 | input[$j]=$(eval $(echo $i | tr -s "\t" | cut -s -f2)) |
| 141 | j=$(( $j + 1 )) | ||
| 142 | done < $benchNames | ||
| 143 | echo "Making sure that binaries are up to date..." | ||
| 144 | |||
| 145 | for b in ${bench[@]}; do | ||
| 146 | # Build "bin/bench" if bin directory | ||
| 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 | ||
| 152 | make $b | ||
| 153 | fi | ||
| 154 | # If bench is still not in bin or curr dir, fail | ||
| 155 | if [[ ! -f "./$b" && ! -f "./bin/$b" ]]; then | ||
| 156 | echo "Unable to find benchmark $b" | ||
| 157 | exit | ||
| 158 | fi | ||
| 159 | done | ||
| 28 | echo "Done. Disabling real-time throttling..." | 160 | echo "Done. Disabling real-time throttling..." |
| 29 | 161 | ||
| 30 | # Turn off rt throttling | 162 | # Turn off rt throttling |
| @@ -43,12 +175,34 @@ do | |||
| 43 | i=$(( $i + 1 )) | 175 | i=$(( $i + 1 )) |
| 44 | done | 176 | done |
| 45 | 177 | ||
| 46 | # Read the names of each benchmark | 178 | echo "Done. Creating cleanup handler..." |
| 47 | j=0 | 179 | function cleanup { |
| 48 | while read i; do | 180 | # End contending tasks |
| 49 | tacleProg[$j]=$i | 181 | if [[ -v contend ]]; then |
| 50 | j=$(( $j + 1 )) | 182 | killall thrasher |
| 51 | done < $tacleNames | 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 | ||
