package wcet.devel; import com.jopdesign.sys.Config; import com.jopdesign.sys.Const; import com.jopdesign.sys.Native; /** * Binary search for the array of n integer elements. * * WCET aspect: Completely structured. * * Ported from C code written by Sung-Soo Lim for the SNU-RT benchmark suite with * modifications by Jan Gustafsson. See <a * href="http://www.mrtc.mdh.se/projects/wcet/benchmarks.html">Maelardalen WCET * Benchmarks</a>. * <p> * Note: this implementation of binary search is both hard to analyze and * inefficient. See rtlib/BinarySearch#bsearch for a fast and easy to * analyze real-time variant. * </p> */ public class BinarySearch { private static class Data { public int key; public int value; public Data(int key, int value) { this.key = key; this.value = value; } } public static final int MAX_SIZE = 128; private Data[] data; private int size; public BinarySearch(int capacity) { data = new Data[capacity]; for (int i = 0; i < capacity; i++) // @WCA loop <= 129 // @WC3A loop <= $1 { data[i] = new Data(i<<1, i * 100); } } int loopCount; public int binarySearch(int x) { int fvalue, mid, up, low; low = 0; up = size-1; fvalue = -1; // all data are positive /* Loop Bound <= floor ( log(up-low+1) / log 2 ) + 1 * Proof by induction: * up-low = 0 => iterations <= 0 + 1 = 1 * Proof: Assume mid = low = up * (a) up' = mid - 1 = low - 1 ==> up-low = -1 * (b) low' = mid + 1 = up + 1 ==> up-low = -1 * Assume for all k < n, up-low = k ==> iterations <= floor(ld [k+1]) + 1 * We have to show that ==> up-low = n ==> iterations <= floor(ld [n+1]) + 1 * Proof: Assume mid = (low + low + n) >> 1; * mid = floor( (2 low + n) / 2 ); * mid = floor( low + n/2 ) = low + floor (n/2); * (a) up' = mid - 1 = low + floor (n/2) - 1 * (up-low)' = low + floor (n/2) - 1 - low = floor (n/2) - 1 * ==> iterations <= floor(ld [floor(n/2) - 1 + 1]) + 1 + 1 * <= floor(ld [floor(n/2)]) + 2 * <= floor(ld(n/2)) + 2 * = floor(ld(n)) + 1 * <= floor(ld(n+1)) + 1 * (b) low' = mid + 1 = low + floor (n/2) + 1 * (up-low)' = low+n -low-floor(n/2)-1 = n-floor(n/2)-1 * ==> iterations <= (floor(ld [n-floor(n/2)-1 + 1]) + 1) + 1 * = floor(ld[n-floor(n/2)]) + 2 * <= floor(ld[n-(n-1)/2]) + 2 * = floor(ld[(n+1)/2]) + 2 * = floor(ld(n+1)) + 1 * <= floor(ld(n+1)) + 1 */ loopCount = 0; while (low <= up) // @WC1A loop <= bitlength(128) // @WCA loop <= bitlength(MAX_SIZE) // @WC3A: loop <= bitlength($this.size) { loopCount++; mid = (low + up) >> 1; if (data[mid].key == x) // @WC4A: WCA flow <= 1 loop { up = low - 1; fvalue = data[mid].value; } else if (data[mid].key > x) { up = mid - 1; } else { low = mid + 1; } } return fvalue; } static int ts, te, to; private static BinarySearch b; public static void main(String[] args) { if(Config.MEASURE) { ts = Native.rdMem(Const.IO_CNT); te = Native.rdMem(Const.IO_CNT); to = te-ts; } int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; b = new BinarySearch(MAX_SIZE); for(int i = 1; i <= MAX_SIZE; i++) { b.size = i; // double lb = Math.floor ( Math.log(i) / Math.log(2) ) + 1; int maxLb = 0; for(int j = -1; j < (i<<1)+1;++j) { if(Config.MEASURE) ts = Native.rdMem(Const.IO_CNT); b.binarySearch(j); if(Config.MEASURE) te = Native.rdMem(Const.IO_CNT); if(b.loopCount > maxLb) maxLb = b.loopCount; if (Config.MEASURE) { int dt = te-ts-to; if(dt > max) max = dt; if(dt < min) min = dt; } } System.out.print("wcet[BinarySearch,n="); System.out.print(i); System.out.print("] "); System.out.print(min); System.out.print(" - "); System.out.print(max); System.out.print(", max. "); System.out.print(maxLb); System.out.println(" iterations"); } } }