linux: tid analysis benchmark
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.kernel.core.tests / perf / org / eclipse / tracecompass / lttng2 / kernel / core / tests / perf / analysis / tid / TidAnalysisUsageBenchmark.java
1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9
10 package org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.tid;
11
12 import static org.junit.Assert.fail;
13
14 import java.io.File;
15 import java.util.List;
16 import java.util.Random;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.eclipse.test.performance.Dimension;
21 import org.eclipse.test.performance.Performance;
22 import org.eclipse.test.performance.PerformanceMeter;
23 import org.eclipse.tracecompass.analysis.os.linux.core.tid.TidAnalysisModule;
24 import org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.kernel.KernelAnalysisBenchmark;
25 import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace;
26 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
27 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
28 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
29 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
30 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
31 import org.eclipse.tracecompass.tmf.core.tests.shared.TmfTestHelper;
32 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
33 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
34 import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent;
35 import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils;
36 import org.junit.Test;
37
38 /**
39 * Benchmarks some typical usages of the thread id analysis
40 *
41 * @author Matthew Khouzam
42 */
43 public class TidAnalysisUsageBenchmark {
44
45 private static final String TEST_GET_RUNNING_THREAD = "TID: Threads On CPU";
46 private static final int LOOP_COUNT = 25;
47 private static final long SEED = 65423897234L;
48 private static final int NUM_CPU_QUERIES = 20000;
49
50 /**
51 * Run the benchmark with "trace2"
52 */
53 @Test
54 public void testTrace2() {
55 runTest(CtfTestTrace.TRACE2, "Trace2");
56 }
57
58 /**
59 * Run the benchmark with "many threads"
60 */
61 @Test
62 public void testManyThreads() {
63 runTest(CtfTestTrace.MANY_THREADS, "ManyThreads");
64 }
65
66 /**
67 * Run the benchmark with "django httpd"
68 */
69 @Test
70 public void testDjangoHttpd() {
71 runTest(CtfTestTrace.DJANGO_HTTPD, "Django httpd");
72 }
73
74 private static TidAnalysisModule getModule(@NonNull CtfTestTrace testTrace, @NonNull LttngKernelTrace trace) {
75 TidAnalysisModule module = null;
76 String path = CtfTmfTestTraceUtils.getTrace(testTrace).getPath();
77
78 try {
79 /* Initialize the analysis module */
80 module = new TidAnalysisModule();
81 module.setId("test");
82 trace.initTrace(null, path, CtfTmfEvent.class);
83 module.setTrace(trace);
84 TmfTestHelper.executeAnalysis(module);
85 } catch (TmfAnalysisException | TmfTraceException e) {
86 fail(e.getMessage());
87 }
88 return module;
89 }
90
91 private static void deleteSupplementaryFiles(ITmfTrace trace) {
92 /*
93 * Delete the supplementary files at the end of the benchmarks
94 */
95 File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace));
96 for (File file : suppDir.listFiles()) {
97 file.delete();
98 }
99 }
100
101 private static void runTest(@NonNull CtfTestTrace testTrace, String testName) {
102
103 /* First, complete the analysis */
104 LttngKernelTrace trace = new LttngKernelTrace();
105 deleteSupplementaryFiles(trace);
106 TidAnalysisModule module = getModule(testTrace, trace);
107
108 /* Benchmark some query use cases */
109 benchmarkGetThreadOnCpu(testName, module);
110
111 deleteSupplementaryFiles(trace);
112 module.dispose();
113 trace.dispose();
114
115 CtfTmfTestTraceUtils.dispose(testTrace);
116 }
117
118 /**
119 * Benchmarks getting a thread running on a random CPU from the kernel
120 * analysis at fixed intervals. This use case mimics an analysis that reads
121 * events and needs to get the currently running thread for those events.
122 */
123 private static void benchmarkGetThreadOnCpu(String testName, TidAnalysisModule module) {
124
125 Performance perf = Performance.getDefault();
126 PerformanceMeter pmRunningThread = perf.createPerformanceMeter(KernelAnalysisBenchmark.TEST_ID + testName + ": " + TEST_GET_RUNNING_THREAD);
127 perf.tagAsSummary(pmRunningThread, TEST_GET_RUNNING_THREAD + '(' + testName + ')', Dimension.CPU_TIME);
128
129 @Nullable
130 ITmfStateSystem ss = module.getStateSystem();
131 if (ss == null) {
132 fail("The state system is null");
133 return;
134 }
135
136 /* Get the number of CPUs */
137 int cpuCount = -1;
138 try {
139 @NonNull
140 List<@NonNull Integer> cpus = ss.getSubAttributes(ITmfStateSystem.ROOT_ATTRIBUTE, false);
141 cpuCount = cpus.size();
142 } catch (AttributeNotFoundException e) {
143 fail(e.getMessage());
144 }
145 if (cpuCount < 1) {
146 fail("Impossible to get the number of CPUs");
147 }
148
149 /* Get the step and start time of the queries */
150 long startTime = ss.getStartTime();
151 long endTime = ss.getCurrentEndTime();
152 long step = Math.floorDiv(endTime - startTime, NUM_CPU_QUERIES);
153
154 if (step < 1) {
155 fail("Trace is too short to run the get thread on CPU benchmark");
156 }
157
158 /* Verify the query work by fetching a value at the end of the trace */
159 Integer threadOnCpu = module.getThreadOnCpuAtTime(0, endTime);
160 if (threadOnCpu == null) {
161 fail("null thread on CPU at the end of the trace. Something is not right with the state system");
162 }
163
164 for (int i = 0; i < LOOP_COUNT; i++) {
165 /* Get the thread running on a random CPU at fixed intervals */
166 Random randomGenerator = new Random(SEED);
167 pmRunningThread.start();
168 for (long nextTime = startTime; nextTime < endTime; nextTime += step) {
169 int cpu = Math.abs(randomGenerator.nextInt()) % cpuCount;
170 module.getThreadOnCpuAtTime(cpu, nextTime);
171 }
172 pmRunningThread.stop();
173 }
174 pmRunningThread.commit();
175 }
176 }
This page took 0.03694 seconds and 5 git commands to generate.