| 1 | #!/usr/bin/env bash
|
| 2 | #
|
| 3 | # Do a quick test of virtual memory.
|
| 4 | #
|
| 5 | # Note: This is probably very similar to max RSS of
|
| 6 | # testdata/osh-runtime/hello-world.sh, so it could be retired.
|
| 7 | #
|
| 8 | # Usage:
|
| 9 | # benchmarks/vm-baseline.sh <function name>
|
| 10 |
|
| 11 | set -o nounset
|
| 12 | set -o pipefail
|
| 13 | set -o errexit
|
| 14 |
|
| 15 | REPO_ROOT=$(cd "$(dirname $0)/.."; pwd)
|
| 16 |
|
| 17 | source test/common.sh # log
|
| 18 | source benchmarks/common.sh
|
| 19 | source build/dev-shell.sh # python2
|
| 20 | source test/tsv-lib.sh # tsv2html
|
| 21 |
|
| 22 | readonly BASE_DIR=_tmp/vm-baseline
|
| 23 |
|
| 24 | measure() {
|
| 25 | local provenance=$1
|
| 26 | local host_job_id=$2
|
| 27 | local base_dir=${3:-_tmp/vm-baseline}
|
| 28 |
|
| 29 | local out_dir="$base_dir/$host_job_id"
|
| 30 | mkdir -p $out_dir
|
| 31 |
|
| 32 | # TODO:
|
| 33 | # print-tasks should:
|
| 34 | # - use the whole shell path like _bin/osh
|
| 35 | # - the host name should be a column
|
| 36 | # - the join ID can be a file, and construct the task name from that
|
| 37 | # - Then maybe use tsv_columns_from_files.py like we do with cachegrind
|
| 38 |
|
| 39 | # - should not
|
| 40 | # - get shell name from the filename
|
| 41 | # - get host name from the filename
|
| 42 | # - should use TSV files
|
| 43 |
|
| 44 | # Fourth column is the shell.
|
| 45 | cat $provenance | filter-provenance "${SHELLS[@]}" "$OSH_CPP_REGEX" |
|
| 46 | while read _ _ _ sh_path shell_hash; do
|
| 47 |
|
| 48 | local sh_name
|
| 49 | sh_name=$(basename $sh_path)
|
| 50 |
|
| 51 | local out="$out_dir/${sh_name}-${shell_hash}.txt"
|
| 52 |
|
| 53 | # There is a race condition on the status but sleep helps.
|
| 54 | # Bug fix: ALIVE to prevent exec optimization in OSH and zsh.
|
| 55 | $sh_path -c 'sleep 0.001; cat /proc/$$/status; echo ALIVE' > $out
|
| 56 | done
|
| 57 |
|
| 58 | echo
|
| 59 | echo "$out_dir:"
|
| 60 | ls -l $out_dir
|
| 61 | }
|
| 62 |
|
| 63 | # Run a single file through stage 1 and report.
|
| 64 | demo() {
|
| 65 | local -a job_dirs=($BASE_DIR/lisa.2017-*)
|
| 66 | local dir1=$BASE_DIR/stage1
|
| 67 | local dir2=$BASE_DIR/stage2
|
| 68 |
|
| 69 | mkdir -p $dir1 $dir2
|
| 70 |
|
| 71 | benchmarks/virtual_memory.py baseline ${job_dirs[-1]} \
|
| 72 | > $dir1/vm-baseline.tsv
|
| 73 |
|
| 74 | benchmarks/report.R vm-baseline $dir1 $dir2
|
| 75 | }
|
| 76 |
|
| 77 | # Combine CSV files.
|
| 78 | stage1() {
|
| 79 | local raw_dir=${1:-$BASE_DIR/raw}
|
| 80 | local single_machine=${2:-}
|
| 81 |
|
| 82 | local out=$BASE_DIR/stage1
|
| 83 | mkdir -p $out
|
| 84 |
|
| 85 | local base_dir=
|
| 86 |
|
| 87 | local -a raw=()
|
| 88 |
|
| 89 | if test -n "$single_machine"; then
|
| 90 | base_dir=_tmp/vm-baseline
|
| 91 | local -a m1=( $base_dir/$single_machine.* )
|
| 92 | raw+=( ${m1[-1]} )
|
| 93 | else
|
| 94 | base_dir=../benchmark-data/vm-baseline
|
| 95 | # Globs are in lexicographical order, which works for our dates.
|
| 96 | local -a m1=( $base_dir/$MACHINE1.* )
|
| 97 | local -a m2=( $base_dir/$MACHINE2.* )
|
| 98 |
|
| 99 | raw+=( ${m1[-1]} ${m2[-1]} )
|
| 100 | fi
|
| 101 |
|
| 102 | benchmarks/virtual_memory.py baseline "${raw[@]}" \
|
| 103 | | tee $out/vm-baseline.tsv
|
| 104 | }
|
| 105 |
|
| 106 | print-report() {
|
| 107 | local in_dir=$1
|
| 108 |
|
| 109 | benchmark-html-head 'Virtual Memory Baseline'
|
| 110 |
|
| 111 | cat <<EOF
|
| 112 | <body class="width60">
|
| 113 | <p id="home-link">
|
| 114 | <a href="/">oils.pub</a>
|
| 115 | </p>
|
| 116 | EOF
|
| 117 |
|
| 118 | cmark << 'EOF'
|
| 119 | ## Virtual Memory Baseline
|
| 120 |
|
| 121 | Source code: [oils/benchmarks/vm-baseline.sh](https://github.com/oils-for-unix/oils/tree/master/benchmarks/vm-baseline.sh)
|
| 122 |
|
| 123 | ### Memory Used at Startup (MB)
|
| 124 |
|
| 125 | Memory usage is measured in MB (powers of 10), not MiB (powers of 2).
|
| 126 |
|
| 127 | EOF
|
| 128 | # highlight OSH lines
|
| 129 | tsv2html --css-class-pattern 'special ^osh' $in_dir/vm-baseline.tsv
|
| 130 |
|
| 131 | # R code doesn't generate this
|
| 132 | if false; then
|
| 133 | cmark <<< '### Shell and Host Details'
|
| 134 |
|
| 135 | tsv2html $in_dir/shells.tsv
|
| 136 | tsv2html $in_dir/hosts.tsv
|
| 137 | fi
|
| 138 |
|
| 139 | cat <<EOF
|
| 140 | </body>
|
| 141 | </html>
|
| 142 | EOF
|
| 143 | }
|
| 144 |
|
| 145 |
|
| 146 | #
|
| 147 | # Other
|
| 148 | #
|
| 149 |
|
| 150 | soil-run() {
|
| 151 | ### Run it on just this machine, and make a report
|
| 152 |
|
| 153 | rm -r -f $BASE_DIR
|
| 154 | mkdir -p $BASE_DIR
|
| 155 |
|
| 156 | local -a osh_bin=( $OSH_CPP_NINJA )
|
| 157 | ninja "${osh_bin[@]}"
|
| 158 |
|
| 159 | local single_machine='no-host'
|
| 160 |
|
| 161 | local job_id
|
| 162 | job_id=$(benchmarks/id.sh print-job-id)
|
| 163 |
|
| 164 | benchmarks/id.sh shell-provenance-2 \
|
| 165 | $single_machine $job_id _tmp \
|
| 166 | bash dash bin/osh "${osh_bin[@]}"
|
| 167 |
|
| 168 | # TODO: measure* should use print-tasks | run-tasks
|
| 169 | local provenance=_tmp/provenance.txt
|
| 170 | local host_job_id="$single_machine.$job_id"
|
| 171 |
|
| 172 | measure $provenance $host_job_id
|
| 173 |
|
| 174 | # Make it run on one machine
|
| 175 | stage1 '' $single_machine
|
| 176 |
|
| 177 | benchmarks/report.sh stage2 $BASE_DIR
|
| 178 | benchmarks/report.sh stage3 $BASE_DIR
|
| 179 | }
|
| 180 |
|
| 181 | "$@"
|