#!/bin/sh # # This script generates statistics (build size, speed) for successive # revisions of the code. It checks out git commits one an a time, compiles # various ports to determine their size, and runs pystone on the unix port. # Results are collected in the output file. # # Note: you will need to copy this file out of the tools directory before # executing because it does not exist in old revisions of the repository. # check that we are in the root directory of the repository if test ! -d py -o ! -d unix -o ! -d stmhal { echo "script must be run from root of the repository" exit 1 } # output file for the data; data is appended if file already exists setglobal output = 'codestats.dat' # utility programs setglobal RM = '/bin/rm' setglobal AWK = 'awk' setglobal MAKE = '"make -j2'" # these are the binaries that are built; some have 2 or 3 depending on version setglobal bin_unix = 'unix/micropython' setglobal bin_stmhal = 'stmhal/build-PYBV10/firmware.elf' setglobal bin_barearm_1 = 'bare-arm/build/flash.elf' setglobal bin_barearm_2 = 'bare-arm/build/firmware.elf' setglobal bin_minimal = 'minimal/build/firmware.elf' setglobal bin_cc3200_1 = 'cc3200/build/LAUNCHXL/application.axf' setglobal bin_cc3200_2 = 'cc3200/build/LAUNCHXL/release/application.axf' setglobal bin_cc3200_3 = 'cc3200/build/WIPY/release/application.axf' # start at zero size; if build fails reuse previous valid size setglobal size_unix = '"0'" setglobal size_stmhal = '"0'" setglobal size_barearm = '"0'" setglobal size_minimal = '"0'" setglobal size_cc3200 = '"0'" # start at zero pystones setglobal pystones = '"0'" # this code runs pystone and averages the results setglobal pystoneavg = '/tmp/pystoneavg.py' cat > $pystoneavg << """ import pystone samples = [pystone.pystones(300000)[1] for i in range(5)] samples.sort() stones = sum(samples[1:-1]) / (len(samples) - 2) # exclude smallest and largest print("stones %g" % stones) """ proc get_size { if test -r $2 { size $2 | tail -n1 | $AWK '{print $1}' } else { echo $1 } } proc get_size2 { if test -r $2 { size $2 | tail -n1 | $AWK '{print $1}' } elif test -r $3 { size $3 | tail -n1 | $AWK '{print $1}' } else { echo $1 } } proc get_size3 { if test -r $2 { size $2 | tail -n1 | $AWK '{print $1}' } elif test -r $3 { size $3 | tail -n1 | $AWK '{print $1}' } elif test -r $4 { size $4 | tail -n1 | $AWK '{print $1}' } else { echo $1 } } # get the last revision in the data file; or start at v1.0 if no file if test -r $output { setglobal last_rev = $[tail -n1 $output | $AWK '{print $1}] } else { echo "# hash size_unix size_stmhal size_barearm size_minimal size_cc3200 pystones" > $output setglobal last_rev = '"v1.0'" } # get a list of hashes between last revision (exclusive) and master setglobal hashes = $[git log --format=format:"%H" --reverse $(last_rev)..master] #hashes=$(git log --format=format:"%H" --reverse ${last_rev}..master | $AWK '{if (NR % 10 == 0) print $0}') # do every 10th one for hash in [$hashes] { #### checkout the revision #### git checkout $hash if test $Status -ne 0 { echo "aborting" exit 1 } #### apply patches to get it to build #### if grep -q '#if defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000000) // POSIX' unix/modtime.c { echo apply patch git apply - << """ diff --git a/unix/modtime.c b/unix/modtime.c index 77d2945..dae0644 100644 --- a/unix/modtime.c +++ b/unix/modtime.c @@ -55,10 +55,8 @@ void msec_sleep_tv(struct timeval *tv) { #define MP_CLOCKS_PER_SEC CLOCKS_PER_SEC #endif -#if defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000000) // POSIX -#define CLOCK_DIV 1000.0 -#elif defined(MP_CLOCKS_PER_SEC) && (MP_CLOCKS_PER_SEC == 1000) // WIN32 -#define CLOCK_DIV 1.0 +#if defined(MP_CLOCKS_PER_SEC) +#define CLOCK_DIV (MP_CLOCKS_PER_SEC / 1000.0F) #else #error Unsupported clock() implementation #endif """ } #### unix #### $RM $bin_unix $MAKE -C unix CFLAGS_EXTRA=-DNDEBUG setglobal size_unix = $[get_size $size_unix $bin_unix] # undo patch if it was applied git checkout unix/modtime.c #### stmhal #### $RM $bin_stmhal $MAKE -C stmhal board=PYBV10 setglobal size_stmhal = $[get_size $size_stmhal $bin_stmhal] #### bare-arm #### $RM $bin_barearm_1 $bin_barearm_2 $MAKE -C bare-arm setglobal size_barearm = $[get_size2 $size_barearm $bin_barearm_1 $bin_barearm_2] #### minimal #### if test -r minimal/Makefile { $RM $bin_minimal $MAKE -C minimal CROSS=1 setglobal size_minimal = $[get_size $size_minimal $bin_minimal] } #### cc3200 #### if test -r cc3200/Makefile { $RM $bin_cc3200_1 $bin_cc3200_2 $bin_cc3200_3 $MAKE -C cc3200 BTARGET=application setglobal size_cc3200 = $[get_size3 $size_cc3200 $bin_cc3200_1 $bin_cc3200_2 $bin_cc3200_3] } #### run pystone #### if test -x $bin_unix { setglobal new_pystones = $[$bin_unix $pystoneavg] # only update the variable if pystone executed successfully if echo $new_pystones | grep -q "^stones" { setglobal pystones = $[echo $new_pystones | $AWK '{print $2}] } } #### output data for this commit #### echo "$hash $size_unix $size_stmhal $size_barearm $size_minimal $size_cc3200 $pystones" >> $output } # checkout master and cleanup git checkout master $RM $pystoneavg