1#!/bin/bash 2# Filename: mixed_load.sh 3# Author: Darren Hart <dvhltc@us.ibm.com> 4# Description: Run multiple copies of periodic threads and compare their 5# runtime average. 6# 7# Use "-j" to enable the jvm simulator. 8# 9# This program is free software; you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation; either version 2 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# Copyright (C) IBM Corporation, 2007 20# 21# 2007-Aug-29: Initial version by Darren Hart <dvhltc@us.ibm.com> 22 23 24# Run multiple copies of periodic threads and compare their runtime average 25 26MASTER_PRIO=90 # just above highest prio of jvmsim 27ITERATIONS=1000 28 29T1_PRIO=73 30T1_PERIOD=20 31T1_LOOPS=750 32 33T2_PRIO=63 34T2_PERIOD=40 35T2_LOOPS=1500 36 37T3_PRIO=53 38T3_PERIOD=80 39T3_LOOPS=3000 40 41T4_PRIO=43 42T4_PERIOD=160 43T4_LOOPS=6000 44 45CRITERIA=10 46 47# Remove logs laying around 48rm -f pcl*.log > /dev/null 49 50# Ensure we can spawn all the threads without being preempted 51chrt -p -f $MASTER_PRIO $$ 52 53# Run $1 copies of the thread group, only run one copy of the jvm simulater per group of threads 54function run_thread_groups() { 55 CON=$1 # Concurrency 56 for ((i=0; i<$CON; i++)); do 57 ./periodic_cpu_load_single -i $ITERATIONS -r $T1_PRIO -t $T1_PERIOD -c $T1_LOOPS -f pcl-${CON}x-t1_$i > pcl-${CON}x-t1-$i.log & 58 ./periodic_cpu_load_single -i $ITERATIONS -r $T2_PRIO -t $T2_PERIOD -c $T2_LOOPS -f pcl-${CON}x-t2_$i > pcl-${CON}x-t2-$i.log & 59 ./periodic_cpu_load_single -i $ITERATIONS -r $T3_PRIO -t $T3_PERIOD -c $T3_LOOPS -f pcl-${CON}x-t3-$i > pcl-${CON}x-t3-$i.log & 60 ./periodic_cpu_load_single $JVM_ARG -i $ITERATIONS -r $T4_PRIO -t $T4_PERIOD -c $T4_LOOPS -f pcl-${CON}x-t4-$i > pcl-${CON}x-t4-$i.log & 61 done 62 wait 63} 64 65# grab the average from a log file 66function parse_avg() { 67 grep Avg $1 | sed "s/Avg: \(.*\) us/\1/" 68} 69# grab composite averages from a glob of log files 70function parse_avg_avg() { 71 SUM=0 72 COUNT=$# 73 for LOG in $@; do 74 A=`parse_avg $LOG` 75 SUM=`echo "scale=2; $SUM + $A" | bc` 76 done 77 echo "scale=2; $SUM / $COUNT" | bc 78} 79# determine the min of the floating point averages 80function min_float() { 81 MIN=$1 82 shift 83 for VAL in $@; do 84 LT=`echo "$VAL < $MIN" | bc` 85 if [ $LT -eq 1 ]; then 86 MIN=$VAL 87 fi 88 shift 89 done 90 echo $MIN 91} 92# determine the max of the floating point averages 93function max_float() { 94 MAX=$1 95 shift 96 for VAL in $@; do 97 GT=`echo "$VAL > $MIN" | bc` 98 if [ $GT -eq 1 ]; then 99 MAX=$VAL 100 fi 101 shift 102 done 103 echo $MAX 104} 105# calculate (max-min)/min of the args passed in 106function percent_error() { 107 MIN=`min_float $@` 108 MAX=`max_float $@` 109 echo "scale=2; 100*($MAX - $MIN)/$MIN" | bc 110} 111 112# return 1 if all args are less than CRITERIA 113function pass_criteria() { 114 for ERR in $@; do 115 LT=`echo "$ERR < $CRITERIA" | bc` 116 if [ $LT -eq 0 ]; then 117 return 0 118 fi 119 done 120 return 1 121} 122 123 124# Parse args 125JVM_ARG="" 126JVM_STATUS="Disabled" 127if [ "$1" == "-j" ]; then 128 JVM_ARG="-j" 129 JVM_STATUS="Enabled" 130fi 131 132cat <<EOL 133 134------------------------------------------------ 135Periodic CPU Load: Average Runtime Percent Error 136------------------------------------------------ 137 138Running $ITERATIONS iterations per thread 139JVM Simulator: $JVM_STATUS 140 141`printf "%8s%6s%10s%10s" Thread Prio Period Loops` 142`printf "%8s%6s%10s%10s" ------ ---- ------ -----` 143`printf "%8s%6s%10s%10s" T1 $T1_PRIO $T1_PERIOD $T1_LOOPS` 144`printf "%8s%6s%10s%10s" T2 $T2_PRIO $T2_PERIOD $T2_LOOPS` 145`printf "%8s%6s%10s%10s" T3 $T3_PRIO $T3_PERIOD $T3_LOOPS` 146`printf "%8s%6s%10s%10s" T4 $T4_PRIO $T4_PERIOD $T4_LOOPS` 147EOL 148 149# Determine the average run time for a single instance of each thread 150run_thread_groups 1 151T1_1X_AVG=`parse_avg_avg pcl-1x-t1-0.log` 152T2_1X_AVG=`parse_avg_avg pcl-1x-t2-0.log` 153T3_1X_AVG=`parse_avg_avg pcl-1x-t3-0.log` 154T4_1X_AVG=`parse_avg_avg pcl-1x-t4-0.log` 155 156cat <<EOL 157 158Single Instance Averages 159------------------------ 160 T1: $T1_1X_AVG us 161 T2: $T2_1X_AVG us 162 T3: $T3_1X_AVG us 163 T4: $T4_1X_AVG us 164EOL 165# allow console to update 166sleep 1 167 168run_thread_groups 2 169T1_2X_AVG=`parse_avg_avg pcl-2x-t1-[01].log` 170T2_2X_AVG=`parse_avg_avg pcl-2x-t2-[01].log` 171T3_2X_AVG=`parse_avg_avg pcl-2x-t3-[01].log` 172T4_2X_AVG=`parse_avg_avg pcl-2x-t4-[01].log` 173 174cat <<EOL 175 1762x Concurrent Run Averages 177-------------------------- 178 T1: $T1_2X_AVG us 179 T2: $T2_2X_AVG us 180 T3: $T3_2X_AVG us 181 T3: $T4_2X_AVG us 182EOL 183# allow console to update 184sleep 1 185 186run_thread_groups 4 187T1_4X_AVG=`parse_avg_avg pcl-4x-t1-[0-3].log` 188T2_4X_AVG=`parse_avg_avg pcl-4x-t2-[0-3].log` 189T3_4X_AVG=`parse_avg_avg pcl-4x-t3-[0-3].log` 190T4_4X_AVG=`parse_avg_avg pcl-4x-t4-[0-3].log` 191 192cat <<EOL 193 1944x Concurrent Run Averages 195-------------------------- 196 T1: $T1_4X_AVG us 197 T2: $T2_4X_AVG us 198 T3: $T3_4X_AVG us 199 T3: $T4_4X_AVG us 200EOL 201 202# Calculate the percent error 203# %err = 100*(max-min)/min 204T1_ERR=`percent_error $T1_1X_AVG $T1_2X_AVG $T1_4X_AVG` 205T2_ERR=`percent_error $T2_1X_AVG $T2_2X_AVG $T2_4X_AVG` 206T3_ERR=`percent_error $T3_1X_AVG $T3_2X_AVG $T3_4X_AVG` 207T4_ERR=`percent_error $T4_1X_AVG $T4_2X_AVG $T4_4X_AVG` 208 209cat <<EOL 210 211Thread Runtime Percent Differences 212---------------------------------- 213 T1: $T1_ERR% 214 T2: $T2_ERR% 215 T3: $T3_ERR% 216 T4: $T4_ERR% 217EOL 218 219pass_criteria $T1_ERR $T2_ERR $T3_ERR $T4_ERR 220PASS=$? 221if [ $PASS -eq 1 ]; then 222 RESULT="PASSED" 223 RET=0 224else 225 RESULT="FAILED" 226 RET=1 227fi 228 229echo -e "\nTest complete, see logs pcl-\$CONCURRENTx-t\$THREAD-\$NUM.log for detailed results." 230echo "Criteria: < 10% Difference in average runs" 231echo "Result: $RESULT" 232 233exit $RET 234