1#!/bin/sh 2# 3# This script generates statistics (build size, speed) for successive 4# revisions of the code. It checks out git commits one an a time, compiles 5# various ports to determine their size, and runs pystone on the unix port. 6# Results are collected in the output file. 7# 8# Note: you will need to copy this file out of the tools directory before 9# executing because it does not exist in old revisions of the repository. 10 11# check that we are in the root directory of the repository 12if [ ! -d py -o ! -d ports/unix -o ! -d ports/stm32 ]; then 13 echo "script must be run from root of the repository" 14 exit 1 15fi 16 17# output file for the data; data is appended if file already exists 18output=codestats.dat 19 20# utility programs 21RM=/bin/rm 22AWK=awk 23MAKE="make -j2" 24 25# these are the binaries that are built; some have 2 or 3 depending on version 26bin_unix=ports/unix/micropython 27bin_stm32=ports/stm32/build-PYBV10/firmware.elf 28bin_barearm_1=ports/bare-arm/build/flash.elf 29bin_barearm_2=ports/bare-arm/build/firmware.elf 30bin_minimal=ports/minimal/build/firmware.elf 31bin_cc3200_1=ports/cc3200/build/LAUNCHXL/application.axf 32bin_cc3200_2=ports/cc3200/build/LAUNCHXL/release/application.axf 33bin_cc3200_3=ports/cc3200/build/WIPY/release/application.axf 34 35# start at zero size; if build fails reuse previous valid size 36size_unix="0" 37size_stm32="0" 38size_barearm="0" 39size_minimal="0" 40size_cc3200="0" 41 42# start at zero pystones 43pystones="0" 44 45# this code runs pystone and averages the results 46pystoneavg=/tmp/pystoneavg.py 47cat > $pystoneavg << EOF 48import pystone 49samples = [pystone.pystones(300000)[1] for i in range(5)] 50samples.sort() 51stones = sum(samples[1:-1]) / (len(samples) - 2) # exclude smallest and largest 52print("stones %g" % stones) 53EOF 54 55function get_size() { 56 if [ -r $2 ]; then 57 size $2 | tail -n1 | $AWK '{print $1}' 58 else 59 echo $1 60 fi 61} 62 63function get_size2() { 64 if [ -r $2 ]; then 65 size $2 | tail -n1 | $AWK '{print $1}' 66 elif [ -r $3 ]; then 67 size $3 | tail -n1 | $AWK '{print $1}' 68 else 69 echo $1 70 fi 71} 72 73function get_size3() { 74 if [ -r $2 ]; then 75 size $2 | tail -n1 | $AWK '{print $1}' 76 elif [ -r $3 ]; then 77 size $3 | tail -n1 | $AWK '{print $1}' 78 elif [ -r $4 ]; then 79 size $4 | tail -n1 | $AWK '{print $1}' 80 else 81 echo $1 82 fi 83} 84 85# get the last revision in the data file; or start at v1.0 if no file 86if [ -r $output ]; then 87 last_rev=$(tail -n1 $output | $AWK '{print $1}') 88else 89 echo "# hash size_unix size_stm32 size_barearm size_minimal size_cc3200 pystones" > $output 90 last_rev="v1.0" 91fi 92 93# get a list of hashes between last revision (exclusive) and master 94hashes=$(git log --format=format:"%H" --reverse ${last_rev}..master) 95#hashes=$(git log --format=format:"%H" --reverse ${last_rev}..master | $AWK '{if (NR % 10 == 0) print $0}') # do every 10th one 96 97for hash in $hashes; do 98 99 #### checkout the revision #### 100 101 git checkout $hash 102 if [ $? -ne 0 ]; then 103 echo "aborting" 104 exit 1 105 fi 106 107 #### apply patches to get it to build #### 108 109 if grep -q '#if defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000000) // POSIX' unix/modtime.c; then 110 echo apply patch 111 git apply - << EOF 112diff --git a/unix/modtime.c b/unix/modtime.c 113index 77d2945..dae0644 100644 114--- a/unix/modtime.c 115+++ b/unix/modtime.c 116@@ -55,10 +55,8 @@ void msec_sleep_tv(struct timeval *tv) { 117 #define MP_CLOCKS_PER_SEC CLOCKS_PER_SEC 118 #endif 119 120-#if defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000000) // POSIX 121-#define CLOCK_DIV 1000.0 122-#elif defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000) // WIN32 123-#define CLOCK_DIV 1.0 124+#if defined(MP_CLOCKS_PER_SEC) 125+#define CLOCK_DIV (MP_CLOCKS_PER_SEC / 1000.0F) 126 #else 127 #error Unsupported clock() implementation 128 #endif 129EOF 130 fi 131 132 #### unix #### 133 134 $RM $bin_unix 135 $MAKE -C ports/unix CFLAGS_EXTRA=-DNDEBUG 136 size_unix=$(get_size $size_unix $bin_unix) 137 138 # undo patch if it was applied 139 git checkout unix/modtime.c 140 141 #### stm32 #### 142 143 $RM $bin_stm32 144 $MAKE -C ports/stm32 board=PYBV10 145 size_stm32=$(get_size $size_stm32 $bin_stm32) 146 147 #### bare-arm #### 148 149 $RM $bin_barearm_1 $bin_barearm_2 150 $MAKE -C ports/bare-arm 151 size_barearm=$(get_size2 $size_barearm $bin_barearm_1 $bin_barearm_2) 152 153 #### minimal #### 154 155 if [ -r ports/minimal/Makefile ]; then 156 $RM $bin_minimal 157 $MAKE -C ports/minimal CROSS=1 158 size_minimal=$(get_size $size_minimal $bin_minimal) 159 fi 160 161 #### cc3200 #### 162 163 if [ -r ports/cc3200/Makefile ]; then 164 $RM $bin_cc3200_1 $bin_cc3200_2 $bin_cc3200_3 165 $MAKE -C ports/cc3200 BTARGET=application 166 size_cc3200=$(get_size3 $size_cc3200 $bin_cc3200_1 $bin_cc3200_2 $bin_cc3200_3) 167 fi 168 169 #### run pystone #### 170 171 if [ -x $bin_unix ]; then 172 new_pystones=$($bin_unix $pystoneavg) 173 # only update the variable if pystone executed successfully 174 if echo $new_pystones | grep -q "^stones"; then 175 pystones=$(echo $new_pystones | $AWK '{print $2}') 176 fi 177 fi 178 179 #### output data for this commit #### 180 181 echo "$hash $size_unix $size_stm32 $size_barearm $size_minimal $size_cc3200 $pystones" >> $output 182 183done 184 185# checkout master and cleanup 186git checkout master 187$RM $pystoneavg 188