From: Geneviève Bastien Date: Wed, 18 May 2016 14:58:08 +0000 (-0400) Subject: lttng: Add system call analysis usage benchmark X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=1796ec68113570ef3e7a57bf77ed6efc8713b9a4;p=deliverable%2Ftracecompass.git lttng: Add system call analysis usage benchmark This benchmarks iterating through all the segments and getting the intersecting elements for different times Change-Id: I1bef84370bec226625ff052a9a912f51aa33e6b0 Signed-off-by: Geneviève Bastien Reviewed-on: https://git.eclipse.org/r/73054 Reviewed-by: Hudson CI Reviewed-by: Matthew Khouzam --- diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF index 8b3039a84b..0d39bb82c5 100644 --- a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF +++ b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/META-INF/MANIFEST.MF @@ -21,7 +21,8 @@ Require-Bundle: org.junit;bundle-version="4.0.0", org.eclipse.tracecompass.analysis.os.linux.core, org.eclipse.tracecompass.analysis.os.linux.core.tests, org.eclipse.tracecompass.analysis.graph.core, - org.eclipse.tracecompass.analysis.timing.core + org.eclipse.tracecompass.analysis.timing.core, + org.eclipse.tracecompass.segmentstore.core Export-Package: org.eclipse.tracecompass.lttng2.kernel.core.tests, org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.graph, org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.kernel;x-internal:=true, diff --git a/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/tracecompass/lttng2/kernel/core/tests/perf/analysis/syscall/SystemCallAnalysisUsageBenchmark.java b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/tracecompass/lttng2/kernel/core/tests/perf/analysis/syscall/SystemCallAnalysisUsageBenchmark.java new file mode 100644 index 0000000000..854a294e63 --- /dev/null +++ b/lttng/org.eclipse.tracecompass.lttng2.kernel.core.tests/perf/org/eclipse/tracecompass/lttng2/kernel/core/tests/perf/analysis/syscall/SystemCallAnalysisUsageBenchmark.java @@ -0,0 +1,242 @@ +/******************************************************************************* + * Copyright (c) 2016 É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 v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +package org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.syscall; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +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.os.linux.core.tid.TidAnalysisModule; +import org.eclipse.tracecompass.internal.analysis.os.linux.core.latency.SystemCallLatencyAnalysis; +import org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.kernel.KernelAnalysisBenchmark; +import org.eclipse.tracecompass.lttng2.kernel.core.trace.LttngKernelTrace; +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.analysis.IAnalysisModule; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +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.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; +import org.eclipse.tracecompass.tmf.ctf.core.event.CtfTmfEvent; +import org.eclipse.tracecompass.tmf.ctf.core.tests.shared.CtfTmfTestTraceUtils; +import org.junit.Test; + +/** + * Benchmarks the system call latency analysis + * + * @author Geneviève Bastien + */ +public class SystemCallAnalysisUsageBenchmark { + + /** + * Test test ID for the system call analysis benchmarks + */ + public static final String TEST_ID = "org.eclipse.tracecompass#System Call Analysis#"; + private static final String TEST_ITERATE_CPU = "Iterate cpu (%s)"; + private static final String TEST_ITERATE_MEMORY = "Iterate memory (%s)"; + private static final String TEST_INTERSECTION_CPU = "Intersection cpu (%s)"; + private static final String TEST_INTERSECTION_MEMORY = "Intersection memory (%s)"; + + private static final int LOOP_COUNT = 25; + + private static void deleteSupplementaryFiles(ITmfTrace trace) { + /* + * Delete the supplementary files at the beginning and end of the benchmarks + */ + File suppDir = new File(TmfTraceManager.getSupplementaryFileDir(trace)); + for (File file : suppDir.listFiles()) { + file.delete(); + } + } + + private static SystemCallLatencyAnalysis getModule(@NonNull CtfTestTrace testTrace, @NonNull LttngKernelTrace trace) { + SystemCallLatencyAnalysis module = null; + String path = CtfTmfTestTraceUtils.getTrace(testTrace).getPath(); + + try { + + // Make sure the TID analysis has run on this trace + trace.initTrace(null, path, CtfTmfEvent.class); + deleteSupplementaryFiles(trace); + + trace.traceOpened(new TmfTraceOpenedSignal(trace, trace, null)); + IAnalysisModule tidModule = trace.getAnalysisModule(TidAnalysisModule.ID); + assertNotNull(tidModule); + tidModule.schedule(); + tidModule.waitForCompletion(); + + /* Initialize the analysis module */ + module = new SystemCallLatencyAnalysis(); + module.setId("test"); + module.setTrace(trace); + TmfTestHelper.executeAnalysis(module); + } catch (TmfAnalysisException | TmfTraceException e) { + fail(e.getMessage()); + } + return module; + } + + /** + * Run the benchmark with "trace2" + */ + @Test + public void testTrace2() { + runTest(CtfTestTrace.TRACE2, "Trace2"); + } + + /** + * Run the benchmark with "many thread" + */ + @Test + public void testManyThreads() { + runTest(CtfTestTrace.MANY_THREADS, "Many threads"); + } + + /** + * Run the benchmark with "django httpd" + */ + @Test + public void testDjangoHttpd() { + runTest(CtfTestTrace.DJANGO_HTTPD, "Django HTTPD"); + } + + private static void runTest(@NonNull CtfTestTrace testTrace, String traceName) { + /* First, complete the analysis */ + LttngKernelTrace trace = new LttngKernelTrace(); + SystemCallLatencyAnalysis module = getModule(testTrace, trace); + + long segmentEnd = benchmarkIteration(traceName, module); + benchmarkIntersection(traceName, module, trace.getStartTime().getValue(), segmentEnd); + + /* + * Delete the supplementary files at the end of the benchmarks + */ + deleteSupplementaryFiles(trace); + + module.dispose(); + trace.dispose(); + + CtfTmfTestTraceUtils.dispose(testTrace); + } + + /** + * Benchmarks iterating through all the segments of the analysis + */ + private static long benchmarkIteration(String testName, SystemCallLatencyAnalysis module) { + + Performance perf = Performance.getDefault(); + PerformanceMeter pmCpu = perf.createPerformanceMeter(KernelAnalysisBenchmark.TEST_ID + String.format(TEST_ITERATE_CPU, testName)); + perf.tagAsSummary(pmCpu, "Syscall " + String.format(TEST_ITERATE_CPU, testName), Dimension.CPU_TIME); + + PerformanceMeter pmMemory = perf.createPerformanceMeter(KernelAnalysisBenchmark.TEST_ID + String.format(TEST_ITERATE_MEMORY, testName)); + perf.tagAsSummary(pmMemory, "Syscall " + String.format(TEST_ITERATE_MEMORY, testName), Dimension.USED_JAVA_HEAP); + + ISegmentStore<@NonNull ISegment> ss = module.getSegmentStore(); + if (ss == null) { + fail("The segment store is null"); + return -1; + } + + long endTime = -1; + + /** Benchmark for CPU time */ + for (int i = 0; i < LOOP_COUNT; i++) { + /* Make a full query at fixed intervals */ + pmCpu.start(); + for (ISegment segment : ss) { + endTime = Math.max(endTime, segment.getEnd()); + } + pmCpu.stop(); + } + + /** Benchmark for memory usage */ + for (int i = 0; i < LOOP_COUNT; i++) { + /* Make a full query at fixed intervals */ + System.gc(); + pmMemory.start(); + for (ISegment segment : ss) { + endTime = Math.max(endTime, segment.getEnd()); + } + System.gc(); + pmMemory.stop(); + } + + pmCpu.commit(); + pmMemory.commit(); + return endTime; + } + + /** + * Benchmarks iterating through all the segments of the analysis + */ + private static void benchmarkIntersection(String testName, SystemCallLatencyAnalysis module, long start, long end) { + + Performance perf = Performance.getDefault(); + PerformanceMeter pmCpu = perf.createPerformanceMeter(KernelAnalysisBenchmark.TEST_ID + String.format(TEST_INTERSECTION_CPU, testName)); + perf.tagAsSummary(pmCpu, "Syscall " + String.format(TEST_INTERSECTION_CPU, testName), Dimension.CPU_TIME); + + PerformanceMeter pmMemory = perf.createPerformanceMeter(KernelAnalysisBenchmark.TEST_ID + String.format(TEST_INTERSECTION_MEMORY, testName)); + perf.tagAsSummary(pmMemory, "Syscall " + String.format(TEST_INTERSECTION_MEMORY, testName), Dimension.USED_JAVA_HEAP); + + ISegmentStore<@NonNull ISegment> ss = module.getSegmentStore(); + if (ss == null) { + fail("The segment store is null"); + return; + } + + /** Benchmark for CPU time */ + for (int i = 0; i < LOOP_COUNT; i++) { + /* Make a full query at fixed intervals */ + long intersectStart = start; + long intersectEnd = end; + pmCpu.start(); + for (int j = 0; j < 10; j++) { + ss.getIntersectingElements(intersectStart, intersectEnd); + long step = (long) ((intersectEnd - intersectStart) * 0.1); + intersectStart += step; + intersectEnd -= step; + } + pmCpu.stop(); + } + + /** Benchmark for memory usage */ + for (int i = 0; i < LOOP_COUNT; i++) { + /* Make a full query at fixed intervals */ + List> lists = new ArrayList<>(); + long intersectStart = start; + long intersectEnd = end; + System.gc(); + pmMemory.start(); + for (int j = 0; j < 5; j++) { + Iterable<@NonNull ISegment> elements = ss.getIntersectingElements(intersectStart, intersectEnd); + lists.add(elements); + long step = (long) ((intersectEnd - intersectStart) * 0.2); + intersectStart += step; + intersectEnd -= step; + } + System.gc(); + pmMemory.stop(); + } + + pmCpu.commit(); + pmMemory.commit(); + } + +} diff --git a/releng/org.eclipse.tracecompass.alltests/src/org/eclipse/tracecompass/alltests/perf/RunAllPerfTests.java b/releng/org.eclipse.tracecompass.alltests/src/org/eclipse/tracecompass/alltests/perf/RunAllPerfTests.java index 5d84042192..91823f19b0 100644 --- a/releng/org.eclipse.tracecompass.alltests/src/org/eclipse/tracecompass/alltests/perf/RunAllPerfTests.java +++ b/releng/org.eclipse.tracecompass.alltests/src/org/eclipse/tracecompass/alltests/perf/RunAllPerfTests.java @@ -26,6 +26,7 @@ import org.junit.runners.Suite; org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.kernel.KernelAnalysisBenchmark.class, org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.kernel.KernelAnalysisUsageBenchmark.class, org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.syscall.SystemCallAnalysisBenchmark.class, + org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.syscall.SystemCallAnalysisUsageBenchmark.class, org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.tid.TidAnalysisUsageBenchmark.class, org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.analysis.StatisticsAnalysisBenchmark.class, org.eclipse.tracecompass.lttng2.kernel.core.tests.perf.event.matching.EventMatchingBenchmark.class,