1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/parjs-benchmarks/util.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,225 @@ 1.4 +DEFAULT_WARMUP = 10 1.5 +DEFAULT_MEASURE = 3 1.6 +MODE = MODE || "compare" // MODE is often set on the command-line by run.sh 1.7 + 1.8 +/** 1.9 + * label: for the printouts 1.10 + * w: warmup runs 1.11 + * m: measurement runs 1.12 + * seq: closure to compute sequentially 1.13 + * par: closure to compute in parallel 1.14 + */ 1.15 +function benchmark(label, w, m, seq, par) { 1.16 + var SEQ = 1 1.17 + var PAR = 2 1.18 + var bits = 0 1.19 + if (MODE === "seq") { bits = SEQ; } 1.20 + else if (MODE === "par") { bits = PAR; } 1.21 + else { 1.22 + if (MODE !== "compare") { 1.23 + print("Invalid MODE, expected seq|par|compare: ", MODE); 1.24 + } 1.25 + bits = SEQ|PAR; 1.26 + } 1.27 + 1.28 + if (mode(SEQ)) { 1.29 + print("Warming up sequential runs"); 1.30 + warmup(w, seq); 1.31 + 1.32 + print("Measuring sequential runs"); 1.33 + var [seqTimes, seqResult] = measureN(m, seq); 1.34 + } 1.35 + 1.36 + if (mode(PAR)) { 1.37 + print("Warming up parallel runs"); 1.38 + warmup(w, par); 1.39 + 1.40 + print("Measuring parallel runs"); 1.41 + var [parTimes, parResult] = measureN(m, par); 1.42 + } 1.43 + 1.44 + if (mode(SEQ|PAR)) { 1.45 + // Check correctness 1.46 + print("Checking correctness"); 1.47 + assertStructuralEq(seqResult, parResult); 1.48 + } 1.49 + 1.50 + if (mode(SEQ)) { 1.51 + var seqAvg = average(seqTimes); 1.52 + for (var i = 0; i < seqTimes.length; i++) 1.53 + print(label + " SEQUENTIAL MEASUREMENT " + i + ": " + seqTimes[i]); 1.54 + print(label + " SEQUENTIAL AVERAGE: " + seqAvg); 1.55 + } 1.56 + 1.57 + if (mode(PAR)) { 1.58 + var parAvg = average(parTimes); 1.59 + for (var i = 0; i < parTimes.length; i++) 1.60 + print(label + " PARALLEL MEASUREMENT " + i + ": " + parTimes[i]); 1.61 + print(label + " PARALLEL AVERAGE : " + parAvg); 1.62 + } 1.63 + 1.64 + if (mode(SEQ|PAR)) { 1.65 + print(label + " SEQ/PAR RATIO : " + seqAvg/parAvg); 1.66 + print(label + " PAR/SEQ RATIO : " + parAvg/seqAvg); 1.67 + print(label + " IMPROVEMENT : " + 1.68 + (((seqAvg - parAvg) / seqAvg * 100.0) | 0) + "%"); 1.69 + } 1.70 + 1.71 + function mode(m) { 1.72 + return (bits & m) === m; 1.73 + } 1.74 +} 1.75 + 1.76 +function measure1(f) { 1.77 + var start = new Date(); 1.78 + result = f(); 1.79 + var end = new Date(); 1.80 + return [end.getTime() - start.getTime(), result]; 1.81 +} 1.82 + 1.83 +function warmup(iters, f) { 1.84 + for (var i = 0; i < iters; i++) { 1.85 + print("."); 1.86 + f(); 1.87 + } 1.88 +} 1.89 + 1.90 +function average(measurements) { 1.91 + var sum = measurements.reduce(function (x, y) { return x + y; }); 1.92 + return sum / measurements.length; 1.93 +} 1.94 + 1.95 +function measureN(iters, f) { 1.96 + var measurement, measurements = []; 1.97 + var result; 1.98 + 1.99 + for (var i = 0; i < iters; i++) { 1.100 + [measurement, result] = measure1(f); 1.101 + measurements.push(measurement); 1.102 + } 1.103 + 1.104 + return [measurements, result]; 1.105 +} 1.106 + 1.107 +function assertStructuralEq(e1, e2) { 1.108 + if (e1 instanceof ParallelArray && e2 instanceof ParallelArray) { 1.109 + assertEqParallelArray(e1, e2); 1.110 + } else if (typeof(RectArray) != "undefined" && 1.111 + e1 instanceof ParallelArray && e2 instanceof RectArray) { 1.112 + assertEqParallelArrayRectArray(e1, e2); 1.113 + } else if (typeof(RectArray) != "undefined" && 1.114 + e1 instanceof RectArray && e2 instanceof ParallelArray) { 1.115 + assertEqParallelArrayRectArray(e2, e1); 1.116 + } else if (typeof(WrapArray) != "undefined" && 1.117 + e1 instanceof ParallelArray && e2 instanceof WrapArray) { 1.118 + assertEqParallelArrayWrapArray(e1, e2); 1.119 + } else if (typeof(WrapArray) != "undefined" && 1.120 + e1 instanceof WrapArray && e2 instanceof ParallelArray) { 1.121 + assertEqParallelArrayWrapArray(e2, e1); 1.122 + } else if (e1 instanceof Array && e2 instanceof ParallelArray) { 1.123 + assertEqParallelArrayArray(e2, e1); 1.124 + } else if (e1 instanceof ParallelArray && e2 instanceof Array) { 1.125 + assertEqParallelArrayArray(e1, e2); 1.126 + } else if (typeof(RectArray) != "undefined" && 1.127 + e1 instanceof RectArray && e2 instanceof RectArray) { 1.128 + assertEqRectArray(e1, e2); 1.129 + } else if (typeof(WrapArray) != "undefined" && 1.130 + e1 instanceof WrapArray && e2 instanceof WrapArray) { 1.131 + assertEqWrapArray(e1, e2); 1.132 + } else if (e1 instanceof Array && e2 instanceof Array) { 1.133 + assertEqArray(e1, e2); 1.134 + } else if (e1 instanceof Object && e2 instanceof Object) { 1.135 + assertEq(e1.__proto__, e2.__proto__); 1.136 + for (prop in e1) { 1.137 + if (e1.hasOwnProperty(prop)) { 1.138 + assertEq(e2.hasOwnProperty(prop), true); 1.139 + assertStructuralEq(e1[prop], e2[prop]); 1.140 + } 1.141 + } 1.142 + } else { 1.143 + assertEq(e1, e2); 1.144 + } 1.145 +} 1.146 + 1.147 +function assertEqParallelArrayRectArray(a, b) { 1.148 + assertEq(a.shape.length, 2); 1.149 + assertEq(a.shape[0], b.width); 1.150 + assertEq(a.shape[1], b.height); 1.151 + for (var i = 0, w = a.shape[0]; i < w; i++) { 1.152 + for (var j = 0, h = a.shape[1]; j < h; j++) { 1.153 + assertStructuralEq(a.get(i,j), b.get(i,j)); 1.154 + } 1.155 + } 1.156 +} 1.157 + 1.158 +function assertEqParallelArrayWrapArray(a, b) { 1.159 + assertEq(a.shape.length, 2); 1.160 + assertEq(a.shape[0], b.width); 1.161 + assertEq(a.shape[1], b.height); 1.162 + for (var i = 0, w = a.shape[0]; i < w; i++) { 1.163 + for (var j = 0, h = a.shape[1]; j < h; j++) { 1.164 + assertStructuralEq(a.get(i,j), b.get(i,j)); 1.165 + } 1.166 + } 1.167 +} 1.168 + 1.169 +function assertEqParallelArrayArray(a, b) { 1.170 + assertEq(a.shape.length, 1); 1.171 + assertEq(a.length, b.length); 1.172 + for (var i = 0, l = a.shape[0]; i < l; i++) { 1.173 + assertStructuralEq(a.get(i), b[i]); 1.174 + } 1.175 +} 1.176 + 1.177 +function assertEqRectArray(a, b) { 1.178 + assertEq(a.width, b.width); 1.179 + assertEq(a.height, b.height); 1.180 + for (var i = 0, w = a.width; i < w; i++) { 1.181 + for (var j = 0, h = a.height; j < h; j++) { 1.182 + assertStructuralEq(a.get(i,j), b.get(i,j)); 1.183 + } 1.184 + } 1.185 +} 1.186 + 1.187 +function assertEqWrapArray(a, b) { 1.188 + assertEq(a.width, b.width); 1.189 + assertEq(a.height, b.height); 1.190 + for (var i = 0, w = a.width; i < w; i++) { 1.191 + for (var j = 0, h = a.height; j < h; j++) { 1.192 + assertStructuralEq(a.get(i,j), b.get(i,j)); 1.193 + } 1.194 + } 1.195 +} 1.196 + 1.197 +function assertEqArray(a, b) { 1.198 + assertEq(a.length, b.length); 1.199 + for (var i = 0, l = a.length; i < l; i++) { 1.200 + assertStructuralEq(a[i], b[i]); 1.201 + } 1.202 +} 1.203 + 1.204 +function assertEqParallelArray(a, b) { 1.205 + assertEq(a instanceof ParallelArray, true); 1.206 + assertEq(b instanceof ParallelArray, true); 1.207 + 1.208 + var shape = a.shape; 1.209 + assertEqArray(shape, b.shape); 1.210 + 1.211 + function bump(indices) { 1.212 + var d = indices.length - 1; 1.213 + while (d >= 0) { 1.214 + if (++indices[d] < shape[d]) 1.215 + break; 1.216 + indices[d] = 0; 1.217 + d--; 1.218 + } 1.219 + return d >= 0; 1.220 + } 1.221 + 1.222 + var iv = shape.map(function () { return 0; }); 1.223 + do { 1.224 + var e1 = a.get.apply(a, iv); 1.225 + var e2 = b.get.apply(b, iv); 1.226 + assertStructuralEq(e1, e2); 1.227 + } while (bump(iv)); 1.228 +}