cairo-perf-diff 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #!/bin/sh
  2. set -e
  3. usage() {
  4. argv0=`basename $0`
  5. cat >&2 << END
  6. Usage:
  7. For comparing files created my cairo-perf:
  8. $argv0 old.perf new.perf
  9. For comparing (cached) performance of revisions:
  10. $argv0 [OPTIONS] <revision> [-- cairo-perf options]
  11. $argv0 [OPTIONS] <rev1> <rev2> [-- cairo-perf-options]
  12. If given a single revision, compares its results to that of its
  13. (first-parent) predecessor. Otherwise compares the two given revisions.
  14. The revisions can be any revision accepted by git. For example:
  15. $argv0 HEAD # Show impact of latest commit
  16. $argv0 1.2.0 1.2.4 # Compare performance of 1.2.0 to 1.2.4
  17. Options:
  18. -f, --force
  19. Forces cairo-perf-diff to re-run performance tests
  20. even if cached performance data is available.
  21. -h, --html
  22. With this option performance changes are summarized
  23. as HTML table.
  24. -t, --trace
  25. Compare performance using trace replays instead of
  26. microbenchmarks.
  27. Additional options can be passed the child cairo-perf process
  28. by separating them with a double hyphen (--). For example, to
  29. examine what the impact of the latest change is on the stroke
  30. test you might use:
  31. $argv0 HEAD -- stroke
  32. The performance results are cached in .perf next to the .git directory.
  33. Set CAIRO_AUTOGEN_OPTIONS to pass options to autogen for both
  34. builds.
  35. END
  36. exit 1
  37. }
  38. benchmark="cairo-perf-micro"
  39. # First, pull off any known options
  40. while true; do
  41. case $1 in
  42. -f|--force) force_cairo_perf="true";;
  43. -h|--html) html_output="$2"; shift ;;
  44. -t|--trace) benchmark="cairo-perf-trace";;
  45. *) break;;
  46. esac
  47. shift
  48. done
  49. # Then if anything is left that still looks like an option, (begins
  50. # with a dash), give usage to catch --help or any other -garbage
  51. if [ $# -eq 0 ] || [ "`echo "$1" | sed 's/^-//'`" != "$1" ]; then
  52. usage
  53. fi
  54. # Finally, pick up the actual revision arguments
  55. if [ $# -eq 1 ] || [ "$2" = "--" ]; then
  56. old="$1^"
  57. new="$1"
  58. shift 1
  59. else
  60. old="$1"
  61. new="$2"
  62. shift 2
  63. fi
  64. # And post-finally, pass anything after -- on to cairo-perf
  65. CAIRO_PERF_OPTIONS="-r -i 10"
  66. if [ $# -gt 0 ]; then
  67. if [ "$1" = "--" ]; then
  68. shift 1
  69. CAIRO_PERF_OPTIONS="$CAIRO_PERF_OPTIONS $@"
  70. else
  71. usage
  72. fi
  73. fi
  74. git_setup() {
  75. SUBDIRECTORY_OK='Yes'
  76. . "$(git --exec-path)/git-sh-setup"
  77. CAIRO_DIR=`dirname $GIT_DIR`
  78. if [ "$CAIRO_DIR" = "." ]; then
  79. CAIRO_DIR=`pwd`
  80. fi
  81. CAIRO_PERF_DIR=$CAIRO_DIR/.perf
  82. }
  83. rev2sha() {
  84. rev=$1
  85. git rev-parse --verify $rev || ( echo "Cannot resolve $rev as a git object" && exit 1 )
  86. }
  87. cpu_count() {
  88. test -f /proc/cpuinfo &&
  89. grep -c '^processor[[:blank:]]\+:' /proc/cpuinfo ||
  90. echo 1
  91. }
  92. # We cache performance output based on a two-part name capturing the
  93. # current performance test suite and the library being tested. We
  94. # capture these as the tree object of the perf directory in HEAD and
  95. # the tree object of the src directory of the revision being tested.
  96. #
  97. # This way, whenever the performance suite is updated, cached output
  98. # from old versions of the suite are automatically invalidated. Also,
  99. # if a commit just changes things outside of the src tree, (say it
  100. # changes the "test" test suite, or README or configure.in, or
  101. # whatever), cairo-perf-diff will be smart enough to still use cached
  102. # results from a run with an equivalent src tree.
  103. rev2perf() {
  104. rev=$1
  105. sha=`rev2sha $rev`
  106. src_tree_sha=`rev2sha $rev:src`
  107. perf_tree_sha=`rev2sha HEAD:perf`
  108. script_tree_sha=`rev2sha HEAD:util/cairo-script`
  109. echo "$CAIRO_PERF_DIR/${sha}-${perf_tree_sha}-${script_tree_sha}-${src_tree_sha}.perf"
  110. }
  111. rev2perf_glob() {
  112. rev=$1
  113. src_tree_sha=`rev2sha $rev:src`
  114. perf_tree_sha=`rev2sha HEAD:perf`
  115. script_tree_sha=`rev2sha HEAD:util/cairo-script`
  116. echo "$CAIRO_PERF_DIR/*-${perf_tree_sha}-${script_tree_sha}-${src_tree_sha}.perf"
  117. }
  118. build() {
  119. build_dir=$1
  120. sha=$2
  121. if [ ! -d $build_dir ]; then
  122. git clone -s $CAIRO_DIR $build_dir
  123. (cd $build_dir; git checkout -b tmp-cairo-perf-diff $sha)
  124. fi
  125. cd $build_dir
  126. git checkout tmp-cairo-perf-diff
  127. git reset --hard $sha
  128. if [ -z "$MAKEFLAGS" ]; then
  129. CPU_COUNT=`cpu_count`
  130. export MAKEFLAGS="-j`expr $CPU_COUNT + 1`"
  131. fi
  132. if [ ! -e Makefile ]; then
  133. ./autogen.sh $CAIRO_AUTOGEN_OPTIONS
  134. fi
  135. for file in $boilerplate_files; do
  136. rsync $CAIRO_DIR/$file boilerplate
  137. done
  138. for file in $perf_files; do
  139. rsync $CAIRO_DIR/$file perf
  140. done
  141. for file in $script_files; do
  142. rsync $CAIRO_DIR/$file util/cairo-script
  143. done
  144. make || (rm config.cache && make)
  145. (cd boilerplate && make libcairoboilerplate.la)
  146. cd perf
  147. make ${benchmark}
  148. }
  149. # Usage: run_cairo_perf_if_not_cached <rev> <suffix>
  150. # The <rev> argument must be a valid git ref-spec that can
  151. # be resolved to a commit. The suffix is just something
  152. # unique so that build directories can be separated for
  153. # multiple calls to this function.
  154. run_cairo_perf_if_not_cached() {
  155. rev=$1
  156. build_dir="build-$2"
  157. owd=`pwd`
  158. sha=`rev2sha $rev`
  159. perf=`rev2perf $rev`
  160. glob=`rev2perf_glob $rev`
  161. if [ -e $glob ] && [ "$force_cairo_perf" != "true" ]; then
  162. return 0
  163. fi
  164. if [ ! -d $CAIRO_PERF_DIR ]; then
  165. echo "Creating new perf cache in $CAIRO_PERF_DIR"
  166. mkdir $CAIRO_PERF_DIR
  167. fi
  168. cd $CAIRO_DIR
  169. boilerplate_files=`git ls-tree --name-only HEAD boilerplate/*`
  170. perf_files=`git ls-tree --name-only HEAD perf/*`
  171. script_files=`git ls-tree --name-only HEAD util/cairo-script/*`
  172. cd $CAIRO_PERF_DIR
  173. build $build_dir $sha || {
  174. rm -rf $build_dir
  175. build $build_dir $sha || exit 1
  176. }
  177. echo "Running \"cairo-perf $CAIRO_PERF_OPTIONS\" against $rev. Results will be cached in:"
  178. { ./$benchmark $CAIRO_PERF_OPTIONS || echo "*** Performance test crashed"; } >> $perf
  179. cd $owd
  180. }
  181. git_setup
  182. if [ -e ./cairo-perf-diff-files ]; then
  183. bindir="."
  184. else
  185. bindir=$CAIRO_DIR/perf
  186. # Build cairo-perf-diff-files if not available
  187. if [ ! -e $bindir/cairo-perf-diff-files ]; then
  188. echo "Building cairo-perf-diff-files"
  189. if [ "x$OS" = "xWindows_NT" ]; then
  190. make -f Makefile.win32 -C $bindir cairo-perf-diff-files CFG=debug
  191. else
  192. make -C $bindir cairo-perf-diff-files
  193. fi
  194. fi
  195. fi
  196. if [ ! -e $old ]; then
  197. run_cairo_perf_if_not_cached $old old
  198. old=`rev2perf $old`
  199. fi
  200. if [ ! -e $new ]; then
  201. run_cairo_perf_if_not_cached $new new
  202. new=`rev2perf $new`
  203. fi
  204. if [ -z "$html_output" ]; then
  205. $bindir/cairo-perf-diff-files $old $new
  206. else
  207. $bindir/cairo-perf-diff-files $old $new |
  208. $CAIRO_DIR/perf/make-html.py > $html_output
  209. fi