Commit a9c1dccc authored by Noric Couderc's avatar Noric Couderc
Browse files

Fix: Caching of featureSet

I would create several eventSets before, that were not needed. Now I pass
the FeatureSet, and we use the EvenSetBuilder to make an eventSet based
on the FeatureSet. The EventSetBuilder caches eventSets, so it should
not build unnecessary eventSets. It should create only one for a full
run (they don't change often).
parent 9fe6c4bb
...@@ -5,6 +5,7 @@ import se.lth.cs.papicounters.PAPICounter ...@@ -5,6 +5,7 @@ import se.lth.cs.papicounters.PAPICounter
import se.lth.cs.papicounters.PapiBenchmarkAnalyzer import se.lth.cs.papicounters.PapiBenchmarkAnalyzer
import se.lth.cs.timing.OperationTypeTable import se.lth.cs.timing.OperationTypeTable
import se.lth.cs.util.Experiment import se.lth.cs.util.Experiment
import se.lth.cs.util.FeatureSet
import java.io.Writer import java.io.Writer
import java.util.* import java.util.*
...@@ -13,7 +14,7 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer, ...@@ -13,7 +14,7 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer,
methodPrintFormat: String, methodPrintFormat: String,
normalizeFeatures: Boolean, normalizeFeatures: Boolean,
val numberRuns : Int, val numberRuns : Int,
val papiCounters : List<PAPICounter>) val features: FeatureSet)
: SyntheticBenchmarkDataPrinter(out, methodPrintFormat) { : SyntheticBenchmarkDataPrinter(out, methodPrintFormat) {
private val papiRunner: PapiRunner = papiRunner private val papiRunner: PapiRunner = papiRunner
...@@ -93,10 +94,10 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer, ...@@ -93,10 +94,10 @@ class SyntheticBenchmarkFeaturePrinter(out: Writer,
private fun runBenchmarks(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) { private fun runBenchmarks(syntheticBenchmarks: List<BCBenchmarkPackage<*>>) {
benchmarkResults = when (normalizeFeatures) { benchmarkResults = when (normalizeFeatures) {
true -> papiRunner.runApplicationsNormalized(numberRuns, papiCounters, syntheticBenchmarks).groupBy { true -> papiRunner.runApplicationsNormalized(numberRuns, features, syntheticBenchmarks).groupBy {
it.benchmark.benchmarkIdentifier it.benchmark.benchmarkIdentifier
} }
false -> papiRunner.runApplications(numberRuns, papiCounters, syntheticBenchmarks).groupBy { false -> papiRunner.runApplications(numberRuns, features, syntheticBenchmarks).groupBy {
it.benchmark.benchmarkIdentifier it.benchmark.benchmarkIdentifier
} }
} }
......
...@@ -4,13 +4,19 @@ import papi.EventSet ...@@ -4,13 +4,19 @@ import papi.EventSet
import se.lth.cs.bcgen.BCBenchmarkPackage import se.lth.cs.bcgen.BCBenchmarkPackage
import se.lth.cs.timing.OperationType import se.lth.cs.timing.OperationType
import se.lth.cs.util.Feature import se.lth.cs.util.Feature
import se.lth.cs.util.FeatureSet
interface PapiBenchmarkAnalyzer { interface PapiBenchmarkAnalyzer {
class RunSpec(val numberRuns : Int, class RunSpec(val numberRuns : Int,
val features : List<Feature>, val features : FeatureSet,
val eventSet: EventSet,
val syntheticBenchmark: BCBenchmarkPackage<*>) { val syntheticBenchmark: BCBenchmarkPackage<*>) {
fun eventSet(): EventSet {
val eb = EventSetBuilder()
features.accept(eb)
return eb.getEventSet()
}
/** /**
Tells you if a RunSpec can be sampled in one single pass Tells you if a RunSpec can be sampled in one single pass
for that, the counters have to be 2 counters + (optionally) PAPI_TOT_CYC and PAPI_TOT_INS for that, the counters have to be 2 counters + (optionally) PAPI_TOT_CYC and PAPI_TOT_INS
...@@ -54,6 +60,6 @@ interface PapiBenchmarkAnalyzer { ...@@ -54,6 +60,6 @@ interface PapiBenchmarkAnalyzer {
fun runSpec(spec : RunSpec) : List<BenchmarkRunData> fun runSpec(spec : RunSpec) : List<BenchmarkRunData>
fun runApplications(numberRuns: Int, fun runApplications(numberRuns: Int,
papiCounters : List<PAPICounter>, features : FeatureSet,
syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<BenchmarkRunData> syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<BenchmarkRunData>
} }
\ No newline at end of file
...@@ -4,9 +4,11 @@ import org.openjdk.jmh.infra.Blackhole ...@@ -4,9 +4,11 @@ import org.openjdk.jmh.infra.Blackhole
import papi.EventSet import papi.EventSet
import papi.Papi import papi.Papi
import se.lth.cs.bcgen.BCBenchmarkPackage import se.lth.cs.bcgen.BCBenchmarkPackage
import se.lth.cs.papicounters.EventSetBuilder
import se.lth.cs.papicounters.PAPICounter import se.lth.cs.papicounters.PAPICounter
import se.lth.cs.papicounters.PapiBenchmarkAnalyzer import se.lth.cs.papicounters.PapiBenchmarkAnalyzer
import se.lth.cs.timing.OperationType import se.lth.cs.timing.OperationType
import se.lth.cs.util.FeatureSet
import java.io.FileWriter import java.io.FileWriter
open class PapiRunner() : PapiBenchmarkAnalyzer { open class PapiRunner() : PapiBenchmarkAnalyzer {
...@@ -21,13 +23,15 @@ open class PapiRunner() : PapiBenchmarkAnalyzer { ...@@ -21,13 +23,15 @@ open class PapiRunner() : PapiBenchmarkAnalyzer {
* Empty benchmark: * Empty benchmark:
* Test to see if the results are stable. * Test to see if the results are stable.
*/ */
fun emptyBenchmark(counters : List<PAPICounter>): Map<PAPICounter, List<Long>> { fun emptyBenchmark(counters : FeatureSet): Map<PAPICounter, List<Long>> {
// For each counter, // For each counter,
// we store the values for each run (10 runs) // we store the values for each run (10 runs)
var data: MutableMap<PAPICounter, List<Long>> = mutableMapOf() var data: MutableMap<PAPICounter, List<Long>> = mutableMapOf()
val eb = EventSetBuilder()
counters.accept(eb)
for (counter in counters) { for (counter in eb.getCounterSet()) {
val evset = EventSet.create(counter.toPAPIConstant()!!) val evset = eb.getEventSet()
val current: MutableList<Long> = mutableListOf() val current: MutableList<Long> = mutableListOf()
...@@ -57,15 +61,13 @@ open class PapiRunner() : PapiBenchmarkAnalyzer { ...@@ -57,15 +61,13 @@ open class PapiRunner() : PapiBenchmarkAnalyzer {
/** /**
* Creates a list of specifications of what counter to get from what benchmarks * Creates a list of specifications of what counter to get from what benchmarks
*/ */
fun createRunSpecs(numRuns: Int, counters: List<PAPICounter>, fun createRunSpecs(numRuns: Int, features : FeatureSet,
syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<PapiBenchmarkAnalyzer.RunSpec> { syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<PapiBenchmarkAnalyzer.RunSpec> {
// Let's say we want to minimize the counter change // Let's say we want to minimize the counter change
// We put it in the outer loop // We put it in the outer loop
val specification = mutableListOf<PapiBenchmarkAnalyzer.RunSpec>() val specification = mutableListOf<PapiBenchmarkAnalyzer.RunSpec>()
val counterValues = counters.map { it.toPAPIConstant()!! }
val eventSet = EventSet.create(*counterValues.toIntArray())
for (b in syntheticBenchmarks) { for (b in syntheticBenchmarks) {
specification.add(PapiBenchmarkAnalyzer.RunSpec(numRuns, counters, eventSet, b)) specification.add(PapiBenchmarkAnalyzer.RunSpec(numRuns, features, b))
} }
return specification.toList() return specification.toList()
} }
...@@ -77,7 +79,7 @@ open class PapiRunner() : PapiBenchmarkAnalyzer { ...@@ -77,7 +79,7 @@ open class PapiRunner() : PapiBenchmarkAnalyzer {
for (i in 0 until spec.numberRuns) { for (i in 0 until spec.numberRuns) {
val app = spec.syntheticBenchmark val app = spec.syntheticBenchmark
val evset = spec.eventSet val evset = spec.eventSet()
// We do the measurements // We do the measurements
app.reset(app.getDatastructureSize()) app.reset(app.getDatastructureSize())
var accumulator = 0 var accumulator = 0
...@@ -106,10 +108,10 @@ open class PapiRunner() : PapiBenchmarkAnalyzer { ...@@ -106,10 +108,10 @@ open class PapiRunner() : PapiBenchmarkAnalyzer {
} }
override fun runApplications(numberRuns: Int, override fun runApplications(numberRuns: Int,
papiCounters: List<PAPICounter>, features : FeatureSet,
syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<PapiBenchmarkAnalyzer.BenchmarkRunData> { syntheticBenchmarks: List<BCBenchmarkPackage<*>>): List<PapiBenchmarkAnalyzer.BenchmarkRunData> {
// return syntheticBenchmarks.map { b -> runApplication(iterations, b) } // return syntheticBenchmarks.map { b -> runApplication(iterations, b) }
val specs = createRunSpecs(numberRuns, papiCounters, syntheticBenchmarks) val specs = createRunSpecs(numberRuns, features, syntheticBenchmarks)
val numberBenchmarks = specs.size val numberBenchmarks = specs.size
var i = 0 var i = 0
val samples = specs.flatMap { val samples = specs.flatMap {
...@@ -122,9 +124,9 @@ open class PapiRunner() : PapiBenchmarkAnalyzer { ...@@ -122,9 +124,9 @@ open class PapiRunner() : PapiBenchmarkAnalyzer {
return samples return samples
} }
fun runApplicationsNormalized(numberRuns : Int, papiCounters : List<PAPICounter>, fun runApplicationsNormalized(numberRuns : Int, features : FeatureSet,
syntheticBenchmarks: List<BCBenchmarkPackage<*>>) : List<PapiBenchmarkAnalyzer.BenchmarkRunData> { syntheticBenchmarks: List<BCBenchmarkPackage<*>>) : List<PapiBenchmarkAnalyzer.BenchmarkRunData> {
val benchmarkRuns = runApplications(numberRuns, papiCounters, syntheticBenchmarks) val benchmarkRuns = runApplications(numberRuns, features, syntheticBenchmarks)
return benchmarkRuns.map { return benchmarkRuns.map {
it.normalized() it.normalized()
......
...@@ -28,14 +28,8 @@ class Experiment(val numberIterations : Int, ...@@ -28,14 +28,8 @@ class Experiment(val numberIterations : Int,
} }
fun getIterations(): Stream<List<PapiTracerRunner.TraceRecord>> { fun getIterations(): Stream<List<PapiTracerRunner.TraceRecord>> {
val eventSetBuilder = EventSetBuilder()
eventSetBuilder.visitFeatureSet(features)
val counters = eventSetBuilder.getCounterSet()
val evSet = eventSetBuilder.getEventSet()
val iterations = papiRunner.runIterations( val iterations = papiRunner.runIterations(
PapiBenchmarkAnalyzer.RunSpec(numberIterations, counters.toList(), evSet, benchmark) PapiBenchmarkAnalyzer.RunSpec(numberIterations, features, benchmark)
) )
return iterations.stream() return iterations.stream()
......
...@@ -12,6 +12,7 @@ import se.lth.cs.bcgen.*; ...@@ -12,6 +12,7 @@ import se.lth.cs.bcgen.*;
import se.lth.cs.SyntheticBenchmarkGeneration.*; import se.lth.cs.SyntheticBenchmarkGeneration.*;
import se.lth.cs.papicounters.PAPICounter; import se.lth.cs.papicounters.PAPICounter;
import se.lth.cs.papicounters.PapiBenchmarkAnalyzer; import se.lth.cs.papicounters.PapiBenchmarkAnalyzer;
import se.lth.cs.util.FeatureSet;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
...@@ -27,7 +28,7 @@ public class PapiRunnerTest { ...@@ -27,7 +28,7 @@ public class PapiRunnerTest {
CounterSpecification specification = null; CounterSpecification specification = null;
PapiRunner runner = null; PapiRunner runner = null;
List<PAPICounter> counters = listOf(new PAPICounter("PAPI_L1_DCM"), FeatureSet counters = new FeatureSet(new PAPICounter("PAPI_L1_DCM"),
new PAPICounter("PAPI_TOT_CYC"), new PAPICounter("PAPI_TOT_CYC"),
new PAPICounter("PAPI_BR_MSP")); new PAPICounter("PAPI_BR_MSP"));
...@@ -83,9 +84,7 @@ public class PapiRunnerTest { ...@@ -83,9 +84,7 @@ public class PapiRunnerTest {
100 100
); );
List<PAPICounter> counters = listOf( FeatureSet counters = new FeatureSet(new PAPICounter("PAPI_BR_MSP"), new PAPICounter("PAPI_L1_DCM"),
new PAPICounter("PAPI_BR_MSP"),
new PAPICounter("PAPI_L1_DCM"),
new PAPICounter("PAPI_TOT_CYC")); new PAPICounter("PAPI_TOT_CYC"));
List<PapiRunner.BenchmarkRunData> data = runner.runApplications(numberRuns, counters, syntheticBenchmarks); List<PapiRunner.BenchmarkRunData> data = runner.runApplications(numberRuns, counters, syntheticBenchmarks);
......
...@@ -12,17 +12,18 @@ import se.lth.cs.bcgen.MethodSelectionStrategyLoader ...@@ -12,17 +12,18 @@ import se.lth.cs.bcgen.MethodSelectionStrategyLoader
import se.lth.cs.bcgen.MethodSelectionType import se.lth.cs.bcgen.MethodSelectionType
import se.lth.cs.papicounters.PAPICounter import se.lth.cs.papicounters.PAPICounter
import se.lth.cs.timing.MockupStopWatchRunner import se.lth.cs.timing.MockupStopWatchRunner
import se.lth.cs.util.FeatureSet
import java.io.StringReader import java.io.StringReader
import java.io.StringWriter import java.io.StringWriter
import java.lang.Float.parseFloat import java.lang.Float.parseFloat
import java.nio.file.Paths import java.nio.file.Paths
class SyntheticBenchmarkFeaturePrinterTest { class SyntheticBenchmarkFeaturePrinterTest {
val counters = listOf( val counters = FeatureSet(
"PAPI_L1_DCM", PAPICounter("PAPI_L1_DCM"),
"PAPI_L2_DCM", PAPICounter("PAPI_L2_DCM"),
"PAPI_TOT_CYC", PAPICounter("PAPI_TOT_CYC"),
"PAPI_TOT_INS").map { PAPICounter(it) } PAPICounter("PAPI_TOT_INS"))
val methodOutputFormat = "JAVA-STANDARD-FORMAT" val methodOutputFormat = "JAVA-STANDARD-FORMAT"
val normalizeFeatures = false val normalizeFeatures = false
......
...@@ -14,6 +14,7 @@ import se.lth.cs.papicounters.PapiBenchmarkAnalyzer ...@@ -14,6 +14,7 @@ import se.lth.cs.papicounters.PapiBenchmarkAnalyzer
import se.lth.cs.papicounters.PapiTracerRunner import se.lth.cs.papicounters.PapiTracerRunner
import se.lth.cs.smartmodules.tracer.Tracer import se.lth.cs.smartmodules.tracer.Tracer
import se.lth.cs.timing.OperationType import se.lth.cs.timing.OperationType
import se.lth.cs.util.FeatureSet
import se.lth.cs.variance import se.lth.cs.variance
import se.lth.util.ArrayListTracer import se.lth.util.ArrayListTracer
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
...@@ -132,7 +133,9 @@ class TracingCollectionRunnerTest { ...@@ -132,7 +133,9 @@ class TracingCollectionRunnerTest {
BCBenchmarkPackage.LIST(10, 10, 0, ArrayList<Int>()) BCBenchmarkPackage.LIST(10, 10, 0, ArrayList<Int>())
) )
val counters = listOf("PAPI_TOT_CYC", "PAPI_TOT_INS", "PAPI_L1_DCM").map { PAPICounter(it) } val counters = FeatureSet(PAPICounter("PAPI_TOT_CYC"),
PAPICounter("PAPI_TOT_INS"),
PAPICounter("PAPI_L1_DCM"))
val res = runner!!.runApplications(10, counters, benches) val res = runner!!.runApplications(10, counters, benches)
// We only tried one benchmark, but we should get several counters. // We only tried one benchmark, but we should get several counters.
...@@ -155,8 +158,7 @@ class TracingCollectionRunnerTest { ...@@ -155,8 +158,7 @@ class TracingCollectionRunnerTest {
val spec = PapiBenchmarkAnalyzer.RunSpec( val spec = PapiBenchmarkAnalyzer.RunSpec(
10, 10,
listOf(PAPICounter("PAPI_TOT_CYC")), FeatureSet(PAPICounter("PAPI_TOT_CYC")),
EventSet.create(Constants.PAPI_TOT_CYC),
bench) bench)
val iterations = runner!!.runSpec(spec) val iterations = runner!!.runSpec(spec)
...@@ -181,7 +183,9 @@ class TracingCollectionRunnerTest { ...@@ -181,7 +183,9 @@ class TracingCollectionRunnerTest {
BCBenchmarkPackage.MAP(seed, 20, 0, HashMap<Int, Int>()) BCBenchmarkPackage.MAP(seed, 20, 0, HashMap<Int, Int>())
) )
val counters = listOf("PAPI_TOT_CYC", "PAPI_TOT_INS", "PAPI_L1_DCM").map { PAPICounter(it) } val counters = FeatureSet(PAPICounter("PAPI_TOT_CYC"),
PAPICounter("PAPI_TOT_INS"),
PAPICounter("PAPI_L1_DCM"))
val iterations = runner!!.createRunSpecs(10, counters, benches) val iterations = runner!!.createRunSpecs(10, counters, benches)
val samples = iterations.flatMap { val samples = iterations.flatMap {
...@@ -203,7 +207,7 @@ class TracingCollectionRunnerTest { ...@@ -203,7 +207,7 @@ class TracingCollectionRunnerTest {
fun testBenchmarkRunsOnce(seed : Long) { fun testBenchmarkRunsOnce(seed : Long) {
val bench = BCBenchmarkPackage.SET(seed, 100, 0, HashSet<Int>()) val bench = BCBenchmarkPackage.SET(seed, 100, 0, HashSet<Int>())
val results = runner!!.runApplications(10, listOf(), listOf(bench)) val results = runner!!.runApplications(10, FeatureSet(), listOf(bench))
for (r in results) { for (r in results) {
Assertions.assertEquals(1, r.benchmark.numberRuns) Assertions.assertEquals(1, r.benchmark.numberRuns)
...@@ -215,14 +219,15 @@ class TracingCollectionRunnerTest { ...@@ -215,14 +219,15 @@ class TracingCollectionRunnerTest {
// TODO: Do the same, but create a lot of benchmarks! // TODO: Do the same, but create a lot of benchmarks!
val bench = BCBenchmarkPackage.LIST(12345, 1000, 0, ArrayList<Int>()) val bench = BCBenchmarkPackage.LIST(12345, 1000, 0, ArrayList<Int>())
val features = listOf(PAPICounter("PAPI_TOT_CYC"), PAPICounter("PAPI_TOT_INS")) val features = FeatureSet(PAPICounter("PAPI_TOT_CYC"),
PAPICounter("PAPI_TOT_INS"))
val times = mutableListOf<Double>() val times = mutableListOf<Double>()
val max = 100 val max = 100
for (i in 0..max) { for (i in 0..max) {
val timeSpent = measureTimeMillis { val timeSpent = measureTimeMillis {
runner!!.runIterations( runner!!.runIterations(
PapiBenchmarkAnalyzer.RunSpec(10, features, EventSet.create(), bench) PapiBenchmarkAnalyzer.RunSpec(10, features, bench)
) )
} }
times.add(timeSpent / 1000.0) times.add(timeSpent / 1000.0)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment