blob: a59857f184081f37de67332c37807e520e8bde73 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.lttng2.ust.core.tests.perf.cygprofile;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.test.performance.Dimension;
import org.eclipse.test.performance.Performance;
import org.eclipse.test.performance.PerformanceMeter;
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.ICallGraphProvider;
import org.eclipse.tracecompass.analysis.profiling.core.callstack.CallStackAnalysis;
import org.eclipse.tracecompass.ctf.core.tests.shared.CtfBenchmarkTrace;
import org.eclipse.tracecompass.internal.analysis.profiling.core.callgraph.CallGraphAnalysis;
import org.eclipse.tracecompass.internal.lttng2.ust.core.callstack.LttngUstCallStackAnalysis;
import org.eclipse.tracecompass.lttng2.ust.core.trace.LttngUstTrace;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper;
import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils;
import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Benchmarks the lttng ust callstack analysis execution and call graph
* execution
*
* @author Geneviève Bastien
*/
@SuppressWarnings("restriction")
@RunWith(Parameterized.class)
public class CallStackAndGraphBenchmark {
/**
* Test ID for this benchmark
*/
public static final String TEST_ID = "org.eclipse.tracecompass.lttng2.ust#CallStack#";
private static final String TEST_CALLSTACK_BUILD = "Building Callstack (%s)";
private static final String TEST_CALLSTACK_PARSESEGSTORE = "Callstack segment store (%s)";
private static final String TEST_CALLGRAPH_BUILD = "Building CallGraph (%s)";
private static final int LOOP_COUNT = 25;
private final String fName;
private final String fTestTrace;
private final int fLoopCount;
private static String getPathFromCtfTestTrace(@NonNull CtfTestTrace testTrace) {
CtfTmfTrace ctftrace = CtfTmfTestTraceUtils.getTrace(testTrace);
String path = Objects.requireNonNull(ctftrace.getPath());
ctftrace.dispose();
return path;
}
/**
* Get the traces on which to run the benchmark
*
* @return The arrays of parameters
*/
@Parameters(name = "{index}: {0}")
public static Iterable<Object[]> getParameters() {
return Arrays.asList(new Object[][] {
{ CtfTestTrace.CYG_PROFILE.name(), getPathFromCtfTestTrace(CtfTestTrace.CYG_PROFILE), LOOP_COUNT },
{ CtfBenchmarkTrace.UST_QMLSCENE.name(), CtfBenchmarkTrace.UST_QMLSCENE.getTracePath().toString(), LOOP_COUNT },
{ CtfBenchmarkTrace.UST_VLC.name(), CtfBenchmarkTrace.UST_VLC.getTracePath().toString(), 5},
});
}
/**
* Constructor
*
* @param name
* The name of this test
* @param tracePath
* The path to the trace to the trace to test
* @param loopCount
* The number of times to run the benchmark
*/
public CallStackAndGraphBenchmark(String name, String tracePath, int loopCount) {
fName = name;
fTestTrace = tracePath;
fLoopCount = loopCount;
}
/**
* Run benchmark for the trace
*
* @throws TmfTraceException
* Exceptions thrown getting the trace
*/
@Test
public void runCpuBenchmark() throws TmfTraceException {
Performance perf = Performance.getDefault();
PerformanceMeter callStackBuildPm = Objects.requireNonNull(perf.createPerformanceMeter(TEST_ID + String.format(TEST_CALLSTACK_BUILD, fName)));
perf.tagAsSummary(callStackBuildPm, String.format(TEST_CALLSTACK_BUILD, fName), Dimension.CPU_TIME);
PerformanceMeter callStackSegStorePm = Objects.requireNonNull(perf.createPerformanceMeter(TEST_ID + String.format(TEST_CALLSTACK_PARSESEGSTORE, fName)));
perf.tagAsSummary(callStackSegStorePm, String.format(TEST_CALLSTACK_PARSESEGSTORE, fName), Dimension.CPU_TIME);
PerformanceMeter callgraphBuildPm = Objects.requireNonNull(perf.createPerformanceMeter(TEST_ID + String.format(TEST_CALLGRAPH_BUILD, fName)));
perf.tagAsSummary(callgraphBuildPm, String.format(TEST_CALLGRAPH_BUILD, fName), Dimension.CPU_TIME);
for (int i = 0; i < fLoopCount; i++) {
TmfTrace trace = null;
try {
trace = getTrace();
trace.traceOpened(new TmfTraceOpenedSignal(this, trace, null));
CallStackAnalysis callStackModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, CallStackAnalysis.class, LttngUstCallStackAnalysis.ID);
assertNotNull(callStackModule);
callStackModule.triggerAutomatically(false);
// Benchmark the call stack analysis
callStackBuildPm.start();
TmfTestHelper.executeAnalysis(callStackModule);
callStackBuildPm.stop();
// Benchmark the segment store iteration
ISegmentStore<@NonNull ISegment> segmentStore = callStackModule.getSegmentStore();
assertNotNull(segmentStore);
callStackSegStorePm.start();
// Iterate through the whole segment store
Iterator<ISegment> iterator = segmentStore.iterator();
while (iterator.hasNext()) {
iterator.next();
}
callStackSegStorePm.stop();
ICallGraphProvider callGraphModule = callStackModule.getCallGraph();
assertTrue(callGraphModule instanceof CallGraphAnalysis);
// Benchmark the call graph analysis
callgraphBuildPm.start();
TmfTestHelper.executeAnalysis((CallGraphAnalysis) callGraphModule);
callgraphBuildPm.stop();
/*
* Delete the supplementary files, so that the next iteration rebuilds the state
* system.
*/
File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace));
for (File file : suppDir.listFiles()) {
file.delete();
}
} finally {
if (trace != null) {
trace.dispose();
}
}
}
callStackBuildPm.commit();
callgraphBuildPm.commit();
}
private TmfTrace getTrace() throws TmfTraceException {
LttngUstTrace trace = new LttngUstTrace();
trace.initTrace(null, fTestTrace, ITmfEvent.class);
return trace;
}
}