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

Added PAPI-benchmarking things

Added a kotlin file (+ build stuff) for benchmarking with PAPI.
Also added a test file for testing benches with papi.
parent d31799e3
......@@ -10,6 +10,15 @@
// Apply the java plugin to add support for Java
buildscript {
ext.kotlin_version = '1.3.11'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id 'java'
id 'idea'
......@@ -17,6 +26,7 @@ plugins {
// $ ./gradlew wrapper --gradle-version <version>
id "me.champeau.gradle.jmh" version "0.4.7"
}
apply plugin: 'kotlin'
jmh {
// 'perf' uses perf over the whole iteration
......@@ -52,12 +62,23 @@ test {
dependencies {
// The production code uses the SLF4J logging API at compile time
compile 'org.slf4j:slf4j-api:1.7.13'
compile files('lib/papi.jar')
implementation 'com.google.code.gson:gson:2.8.5'
// Declare the dependency for your favourite test framework you want to use in your tests.
// TestNG is also supported by the Gradle Test task. Just change the
// testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
// 'test.useTestNG()' to your build script.
testCompile 'junit:junit:4.12'
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
jvmTarget = "1.8"
}
}
File added
package se.lth.cs
import com.google.gson.Gson
import papi.Constants
import papi.EventSet
import papi.Papi
import java.io.File
import java.util.*
import kotlin.collections.HashMap
val counterSpec =
hashMapOf(
"PAPI_L1_DCM" to Constants.PAPI_L1_DCM,
"PAPI_L1_ICM" to Constants.PAPI_L1_ICM,
"PAPI_L2_DCM" to Constants.PAPI_L2_DCM,
"PAPI_L2_ICM" to Constants.PAPI_L2_ICM,
"PAPI_L1_TCM" to Constants.PAPI_L1_TCM,
"PAPI_L2_TCM" to Constants.PAPI_L2_TCM,
"PAPI_L3_TCM" to Constants.PAPI_L3_TCM,
"PAPI_CA_SNP" to Constants.PAPI_CA_SNP,
"PAPI_CA_SHR" to Constants.PAPI_CA_SHR,
"PAPI_CA_CLN" to Constants.PAPI_CA_CLN,
"PAPI_CA_ITV" to Constants.PAPI_CA_ITV,
"PAPI_L3_LDM" to Constants.PAPI_L3_LDM,
"PAPI_TLB_DM" to Constants.PAPI_TLB_DM,
"PAPI_TLB_IM" to Constants.PAPI_TLB_IM,
"PAPI_L1_LDM" to Constants.PAPI_L1_LDM,
"PAPI_L1_STM" to Constants.PAPI_L1_STM,
"PAPI_L2_LDM" to Constants.PAPI_L2_LDM,
"PAPI_L2_STM" to Constants.PAPI_L2_STM,
"PAPI_PRF_DM" to Constants.PAPI_PRF_DM,
"PAPI_MEM_WCY" to Constants.PAPI_MEM_WCY,
"PAPI_STL_ICY" to Constants.PAPI_STL_ICY,
"PAPI_FUL_ICY" to Constants.PAPI_FUL_ICY,
"PAPI_STL_CCY" to Constants.PAPI_STL_CCY,
"PAPI_FUL_CCY" to Constants.PAPI_FUL_CCY,
"PAPI_BR_UCN" to Constants.PAPI_BR_UCN,
"PAPI_BR_CN" to Constants.PAPI_BR_CN,
"PAPI_BR_TKN" to Constants.PAPI_BR_TKN,
"PAPI_BR_NTK" to Constants.PAPI_BR_NTK,
"PAPI_BR_MSP" to Constants.PAPI_BR_MSP,
"PAPI_BR_PRC" to Constants.PAPI_BR_PRC,
"PAPI_TOT_INS" to Constants.PAPI_TOT_INS,
"PAPI_LD_INS" to Constants.PAPI_LD_INS,
"PAPI_SR_INS" to Constants.PAPI_SR_INS,
"PAPI_BR_INS" to Constants.PAPI_BR_INS,
"PAPI_RES_STL" to Constants.PAPI_RES_STL,
"PAPI_TOT_CYC" to Constants.PAPI_TOT_CYC,
"PAPI_LST_INS" to Constants.PAPI_LST_INS,
"PAPI_L2_DCA" to Constants.PAPI_L2_DCA,
"PAPI_L3_DCA" to Constants.PAPI_L3_DCA,
"PAPI_L2_DCR" to Constants.PAPI_L2_DCR,
"PAPI_L3_DCR" to Constants.PAPI_L3_DCR,
"PAPI_L2_DCW" to Constants.PAPI_L2_DCW,
"PAPI_L3_DCW" to Constants.PAPI_L3_DCW,
"PAPI_L2_ICH" to Constants.PAPI_L2_ICH,
"PAPI_L2_ICA" to Constants.PAPI_L2_ICA,
"PAPI_L3_ICA" to Constants.PAPI_L3_ICA,
"PAPI_L2_ICR" to Constants.PAPI_L2_ICR,
"PAPI_L3_ICR" to Constants.PAPI_L3_ICR,
"PAPI_L2_TCA" to Constants.PAPI_L2_TCA,
"PAPI_L3_TCA" to Constants.PAPI_L3_TCA,
"PAPI_L2_TCR" to Constants.PAPI_L2_TCR,
"PAPI_L3_TCR" to Constants.PAPI_L3_TCR,
"PAPI_L2_TCW" to Constants.PAPI_L2_TCW,
"PAPI_L3_TCW" to Constants.PAPI_L3_TCW,
"PAPI_SP_OPS" to Constants.PAPI_SP_OPS,
"PAPI_DP_OPS" to Constants.PAPI_DP_OPS,
"PAPI_VEC_SP" to Constants.PAPI_VEC_SP,
"PAPI_VEC_DP" to Constants.PAPI_VEC_DP,
"PAPI_REF_CYC" to Constants.PAPI_REF_CYC
)
val counters = counterSpec.values.toIntArray()
class PapiRunner() {
// All supported constants on the current proc in PAPI
/**
* Empty benchmark:
* Test to see if the results are stable.
*/
fun emptyBenchmark(): MutableMap<String, List<Long>> {
Papi.init()
// For each counter,
// we store the values for each run (10 runs)
var data : MutableMap<String, List<Long>> = mutableMapOf()
for (kvp in counterSpec) {
val evset = EventSet.create(kvp.value)
val current : MutableList<Long> = mutableListOf()
for(warmup in 0 .. 100) {
val a = (0..warmup).toList().toTypedArray()
val b = IntArray(warmup)
evset.start()
// Synthetic piece of code to see if counters run as expected
var acc = 0
for (i in 0 until warmup) {
acc += a[i]
if(acc % 2 == 1) {
b[i] = acc
}
}
evset.stop()
// Get data
val currentData = evset.counters
current.addAll(currentData.toList())
}
data.set(kvp.key, current)
}
return data
}
fun benchmark() {
Papi.init()
// Throws exception
val evset = EventSet.create(*counters)
val results = IntArray(10)
// 9 warmup runs before measuring
for (warmup in 10 downTo 0) {
for (i in 0..9) {
evset.start()
// some weird code to measure
for (k in 0..i * 10) {
results[i] += k * k
}
// done with the code
evset.stop()
val data = evset.counters
// only print the 10th run
if (warmup == 0) {
println("#" + i + ":\t" + data[0] + "\t" + data[1])
}
}
}
}
/** Runs a set of programs (functions) without interleaving
* (Performance should get better if there is JIT compilation)
* @Returns A map from couples (counter, program-name) -> values over all runs
*/
inline fun runWithoutInterleaving(numRuns : Int, functions : List<Pair<String,() -> Any>>):
MutableMap<String, List<Long>> {
Papi.init()
var data : MutableMap<String, List<Long>> = mutableMapOf()
// For each counter that is available
for (kvp in counterSpec) {
// We record only one counter
val evset = EventSet.create(kvp.value)
// For each program...
for (function in functions) {
val current = Pair(kvp.key, function.first)
// We run it n times
var values = mutableListOf<Long>()
for (run in 0..numRuns) {
// We do the measurements
evset.start()
val result = function.second()
evset.stop()
//println(result)
// We record the data
val data = evset.counters
values.addAll(data.toList())
}
val label = current.first + "_" + current.second
data[label] = values
}
}
return data
}
}
fun test1(): IntArray {
val a = (0..1000).toList().toTypedArray()
val b = IntArray(1000)
// Synthetic piece of code to see if counters run as expected
var acc = 0
for (i in 0 until 1000) {
acc += a[i]
if(acc % 2 == 1) {
b[i] = acc
}
}
return b
}
fun test2(): LinkedList<Int> {
var a = LinkedList<Int>()
a.add(0)
a.add(1)
for (i in 0 .. 1000) {
a.add(
a.last + a.get(a.size - 2)
)
}
return a
}
fun test3(): HashMap<Int, MutableList<Int>> {
var a = HashMap<Int, MutableList<Int>>()
for (i in 0 .. 1000) {
for (j in 1 until 9) {
if (i % j == 0) {
if (a.containsKey(j)) {
a[j]?.add(i)
} else {
a[j] = mutableListOf()
}
}
}
}
return a
}
fun main(args : Array<String>) {
val r = PapiRunner()
val functions = listOf(
Pair("1", { test1() }),
Pair("2", { test2() }),
Pair("3", { test3() }))
var data = r.runWithoutInterleaving(1000, functions)
val gson = Gson()
val file = File("benchmarkoutput-warmup.json")
file.writeText(gson.toJson(data))
}
......@@ -4,6 +4,11 @@ import se.lth.cs.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.function.Function;
import java.util.function.IntPredicate;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import papi.*;
import static junit.framework.TestCase.assertEquals;
......@@ -174,4 +179,45 @@ public class ApplicationTest {
}
}
}
/**
* Tests that all performance counters can be put in an eventSet
* (not at the same time!)
* @throws PapiException
*/
@Test
public void TestPapiEventSet() throws PapiException {
Papi.init();
int [] constants = se.lth.cs.PapiRunnerKt.getCounters();
IntPredicate throwsExp =
(integer -> {
try {
System.out.println(integer);
EventSet evset = EventSet.create(constants[integer],
constants[Math.min(integer + 1, 58)]);
return false;
} catch (PapiException e) {
return true;
}
});
IntStream range = IntStream.range(0, constants.length);
// IntStream vals = range.filter(throwsExp);
Assert.assertTrue(range.noneMatch(throwsExp));
}
@Test
public void TestBenchmark() throws PapiException {
PapiRunner r = new PapiRunner();
r.benchmark();
}
@Test
public void TestEmptyBenchmark() throws PapiException {
PapiRunner r = new PapiRunner();
r.emptyBenchmark();
}
}
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