Skip to content
Snippets Groups Projects
Commit 7e76bb76 authored by Christian Wulf's avatar Christian Wulf
Browse files

added performance comparison for methodcallWithPorts variant

parent 6dc589e3
Branches
Tags
No related merge requests found
Showing
with 443 additions and 51 deletions
...@@ -47,6 +47,7 @@ public class StatisticsUtil { ...@@ -47,6 +47,7 @@ public class StatisticsUtil {
public static PerformanceResult printStatistics(final long overallDurationInNs, final List<TimestampObject> timestampObjects) { public static PerformanceResult printStatistics(final long overallDurationInNs, final List<TimestampObject> timestampObjects) {
PerformanceResult performanceResult = new PerformanceResult(); PerformanceResult performanceResult = new PerformanceResult();
performanceResult.overallDurationInNs = overallDurationInNs;
System.out.println("Duration: " + TimeUnit.NANOSECONDS.toMillis(overallDurationInNs) + " ms"); System.out.println("Duration: " + TimeUnit.NANOSECONDS.toMillis(overallDurationInNs) + " ms");
final List<Long> sortedDurationsInNs = new ArrayList<Long>(timestampObjects.size() / 2); final List<Long> sortedDurationsInNs = new ArrayList<Long>(timestampObjects.size() / 2);
......
...@@ -11,7 +11,7 @@ public class OrderedGrowableArrayPipe<T> extends AbstractPipe<T> { ...@@ -11,7 +11,7 @@ public class OrderedGrowableArrayPipe<T> extends AbstractPipe<T> {
private int tail; private int tail;
public OrderedGrowableArrayPipe() { public OrderedGrowableArrayPipe() {
this(17); this(1);
} }
public OrderedGrowableArrayPipe(final int initialCapacity) { public OrderedGrowableArrayPipe(final int initialCapacity) {
......
...@@ -6,10 +6,14 @@ import teetime.variant.methodcallWithPorts.framework.core.OutputPort; ...@@ -6,10 +6,14 @@ import teetime.variant.methodcallWithPorts.framework.core.OutputPort;
public class SpScPipe<T> extends AbstractPipe<T> { public class SpScPipe<T> extends AbstractPipe<T> {
private final FFBufferOrdered3<T> queue = new FFBufferOrdered3<T>(100010); private final FFBufferOrdered3<T> queue;
public static <T> void connect(final OutputPort<T> sourcePort, final InputPort<T> targetPort) { public SpScPipe(final int initialCapacity) {
IPipe<T> pipe = new SpScPipe<T>(); this.queue = new FFBufferOrdered3<T>(initialCapacity);
}
public static <T> void connect(final OutputPort<T> sourcePort, final InputPort<T> targetPort, final int initialCapacity) {
IPipe<T> pipe = new SpScPipe<T>(initialCapacity);
sourcePort.setPipe(pipe); sourcePort.setPipe(pipe);
targetPort.setPipe(pipe); targetPort.setPipe(pipe);
} }
......
package teetime.variant.methodcallWithPorts.examples;
import static org.junit.Assert.assertEquals;
import java.util.Map;
import java.util.Map.Entry;
import org.junit.AfterClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import teetime.variant.methodcall.examples.experiment01.MethodCallThoughputTimestampAnalysis1Test;
import teetime.variant.methodcallWithPorts.examples.experiment09.MethodCallThoughputTimestampAnalysis9Test;
import teetime.variant.methodcallWithPorts.examples.experiment10.MethodCallThoughputTimestampAnalysis10Test;
import teetime.variant.methodcallWithPorts.examples.experiment11.MethodCallThoughputTimestampAnalysis11Test;
import teetime.variant.methodcallWithPorts.examples.experiment14.MethodCallThoughputTimestampAnalysis14Test;
import teetime.variant.methodcallWithPorts.examples.experiment15.MethodCallThoughputTimestampAnalysis15Test;
import teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test;
import teetime.variant.methodcallWithPorts.examples.experiment17.MethodCallThoughputTimestampAnalysis17Test;
import teetime.variant.methodcallWithPorts.examples.experiment19.MethodCallThoughputTimestampAnalysis19Test;
import test.PerformanceResult;
import test.PerformanceTest;
@RunWith(Suite.class)
@SuiteClasses({
MethodCallThoughputTimestampAnalysis1Test.class,
MethodCallThoughputTimestampAnalysis9Test.class,
MethodCallThoughputTimestampAnalysis10Test.class,
MethodCallThoughputTimestampAnalysis11Test.class,
MethodCallThoughputTimestampAnalysis14Test.class,
MethodCallThoughputTimestampAnalysis15Test.class,
MethodCallThoughputTimestampAnalysis16Test.class,
MethodCallThoughputTimestampAnalysis17Test.class,
MethodCallThoughputTimestampAnalysis19Test.class,
})
public class AllTests {
private static final double RESULT_TESTS_16 = 30;
private static final double RESULT_TESTS_19 = 70;
@AfterClass
public static void compareResults() {
Map<String, PerformanceResult> performanceResults = PerformanceTest.measurementRepository.performanceResults;
for (Entry<String, PerformanceResult> entry : performanceResults.entrySet()) {
System.out.println("---> " + entry.getKey() + "\n" + entry.getValue());
}
PerformanceResult test1 = performanceResults
.get("testWithManyObjects(teetime.variant.methodcall.examples.experiment01.MethodCallThoughputTimestampAnalysis1Test)");
PerformanceResult test9 = performanceResults
.get("testWithManyObjects(teetime.variant.methodcallWithPorts.examples.experiment09.MethodCallThoughputTimestampAnalysis9Test)");
PerformanceResult test10 = performanceResults
.get("testWithManyObjects(teetime.variant.methodcallWithPorts.examples.experiment10.MethodCallThoughputTimestampAnalysis10Test)");
PerformanceResult test11 = performanceResults
.get("testWithManyObjects(teetime.variant.methodcallWithPorts.examples.experiment11.MethodCallThoughputTimestampAnalysis11Test)");
PerformanceResult test14 = performanceResults
.get("testWithManyObjects(teetime.variant.methodcallWithPorts.examples.experiment14.MethodCallThoughputTimestampAnalysis14Test)");
PerformanceResult test15 = performanceResults
.get("testWithManyObjects(teetime.variant.methodcallWithPorts.examples.experiment15.MethodCallThoughputTimestampAnalysis15Test)");
PerformanceResult test16a = performanceResults
.get("testWithManyObjectsAnd1Thread(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
PerformanceResult test16b = performanceResults
.get("testWithManyObjectsAnd2Threads(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
PerformanceResult test16c = performanceResults
.get("testWithManyObjectsAnd4Threads(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
PerformanceResult test17 = performanceResults
.get("testWithManyObjects(teetime.variant.methodcallWithPorts.examples.experiment17.MethodCallThoughputTimestampAnalysis17Test)");
PerformanceResult test19a = performanceResults
.get("testWithManyObjectsAnd1Thread(teetime.variant.methodcallWithPorts.examples.experiment19.MethodCallThoughputTimestampAnalysis19Test)");
PerformanceResult test19b = performanceResults
.get("testWithManyObjectsAnd2Threads(teetime.variant.methodcallWithPorts.examples.experiment19.MethodCallThoughputTimestampAnalysis19Test)");
PerformanceResult test19c = performanceResults
.get("testWithManyObjectsAnd4Threads(teetime.variant.methodcallWithPorts.examples.experiment19.MethodCallThoughputTimestampAnalysis19Test)");
assertEquals(60, (double) test14.quantiles.get(0.5) / test1.quantiles.get(0.5), 5.1);
assertEquals(14, (double) test10.quantiles.get(0.5) / test1.quantiles.get(0.5), 2.1);
assertEquals(32, (double) test11.quantiles.get(0.5) / test1.quantiles.get(0.5), 4.1);
assertEquals(22, (double) test9.quantiles.get(0.5) / test1.quantiles.get(0.5), 2.1);
assertEquals(44, (double) test15.quantiles.get(0.5) / test1.quantiles.get(0.5), 4.1);
// below results vary too much
// assertEquals(RESULT_TESTS_16, (double) test16a.quantiles.get(0.5) / test1.quantiles.get(0.5), 5.1);
// assertEquals(RESULT_TESTS_16, (double) test16b.quantiles.get(0.5) / test1.quantiles.get(0.5), 5.1);
// assertEquals(RESULT_TESTS_16, (double) test16c.quantiles.get(0.5) / test1.quantiles.get(0.5), 5.1);
//
// assertEquals(RESULT_TESTS_19, (double) test19a.quantiles.get(0.5) / test1.quantiles.get(0.5), 5.1);
// assertEquals(RESULT_TESTS_19, (double) test19b.quantiles.get(0.5) / test1.quantiles.get(0.5), 5.1);
// assertEquals(RESULT_TESTS_19, (double) test19c.quantiles.get(0.5) / test1.quantiles.get(0.5), 5.1);
assertEquals(39, (double) test17.quantiles.get(0.5) / test1.quantiles.get(0.5), 4.1);
// check speedup
assertEquals(2, (double) test16a.overallDurationInNs / test16b.overallDurationInNs, 0.2);
assertEquals(2.5, (double) test16a.overallDurationInNs / test16c.overallDurationInNs, 0.2);
assertEquals(2, (double) test19a.overallDurationInNs / test19b.overallDurationInNs, 0.2);
assertEquals(2.5, (double) test19a.overallDurationInNs / test19c.overallDurationInNs, 0.2);
}
}
...@@ -36,6 +36,8 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter; ...@@ -36,6 +36,8 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter;
*/ */
public class MethodCallThroughputAnalysis14 extends Analysis { public class MethodCallThroughputAnalysis14 extends Analysis {
private static final int SPSC_INITIAL_CAPACITY = 4;
private long numInputObjects; private long numInputObjects;
private ConstructorClosure<TimestampObject> inputObjectCreator; private ConstructorClosure<TimestampObject> inputObjectCreator;
private int numNoopFilters; private int numNoopFilters;
...@@ -71,13 +73,13 @@ public class MethodCallThroughputAnalysis14 extends Analysis { ...@@ -71,13 +73,13 @@ public class MethodCallThroughputAnalysis14 extends Analysis {
pipeline.addIntermediateStage(stopTimestampFilter); pipeline.addIntermediateStage(stopTimestampFilter);
pipeline.setLastStage(collectorSink); pipeline.setLastStage(collectorSink);
SpScPipe.connect(objectProducer.getOutputPort(), startTimestampFilter.getInputPort()); SpScPipe.connect(objectProducer.getOutputPort(), startTimestampFilter.getInputPort(), SPSC_INITIAL_CAPACITY);
SpScPipe.connect(startTimestampFilter.getOutputPort(), noopFilters[0].getInputPort()); SpScPipe.connect(startTimestampFilter.getOutputPort(), noopFilters[0].getInputPort(), SPSC_INITIAL_CAPACITY);
for (int i = 0; i < noopFilters.length - 1; i++) { for (int i = 0; i < noopFilters.length - 1; i++) {
SpScPipe.connect(noopFilters[i].getOutputPort(), noopFilters[i + 1].getInputPort()); SpScPipe.connect(noopFilters[i].getOutputPort(), noopFilters[i + 1].getInputPort(), SPSC_INITIAL_CAPACITY);
} }
SpScPipe.connect(noopFilters[noopFilters.length - 1].getOutputPort(), stopTimestampFilter.getInputPort()); SpScPipe.connect(noopFilters[noopFilters.length - 1].getOutputPort(), stopTimestampFilter.getInputPort(), SPSC_INITIAL_CAPACITY);
SpScPipe.connect(stopTimestampFilter.getOutputPort(), collectorSink.getInputPort()); SpScPipe.connect(stopTimestampFilter.getOutputPort(), collectorSink.getInputPort(), SPSC_INITIAL_CAPACITY);
return new RunnableStage(pipeline); return new RunnableStage(pipeline);
} }
......
...@@ -40,6 +40,8 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter; ...@@ -40,6 +40,8 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter;
*/ */
public class MethodCallThroughputAnalysis15 extends Analysis { public class MethodCallThroughputAnalysis15 extends Analysis {
private static final int SPSC_INITIAL_CAPACITY = 4;
private int numInputObjects; private int numInputObjects;
private ConstructorClosure<TimestampObject> inputObjectCreator; private ConstructorClosure<TimestampObject> inputObjectCreator;
private int numNoopFilters; private int numNoopFilters;
...@@ -95,7 +97,7 @@ public class MethodCallThroughputAnalysis15 extends Analysis { ...@@ -95,7 +97,7 @@ public class MethodCallThroughputAnalysis15 extends Analysis {
pipeline.addIntermediateStage(delay); pipeline.addIntermediateStage(delay);
pipeline.setLastStage(collectorSink); pipeline.setLastStage(collectorSink);
SpScPipe.connect(clock.getOutputPort(), delay.getTimestampTriggerInputPort()); SpScPipe.connect(clock.getOutputPort(), delay.getTimestampTriggerInputPort(), SPSC_INITIAL_CAPACITY);
UnorderedGrowablePipe.connect(objectProducer.getOutputPort(), startTimestampFilter.getInputPort()); UnorderedGrowablePipe.connect(objectProducer.getOutputPort(), startTimestampFilter.getInputPort());
UnorderedGrowablePipe.connect(startTimestampFilter.getOutputPort(), noopFilters[0].getInputPort()); UnorderedGrowablePipe.connect(startTimestampFilter.getOutputPort(), noopFilters[0].getInputPort());
......
...@@ -15,13 +15,12 @@ ...@@ -15,13 +15,12 @@
***************************************************************************/ ***************************************************************************/
package teetime.variant.methodcallWithPorts.examples.experiment16; package teetime.variant.methodcallWithPorts.examples.experiment16;
import java.util.List; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
import org.junit.runners.MethodSorters;
import teetime.util.ConstructorClosure; import teetime.util.ConstructorClosure;
import teetime.util.ListUtil; import teetime.util.ListUtil;
import teetime.util.StatisticsUtil;
import teetime.variant.explicitScheduling.examples.throughput.TimestampObject; import teetime.variant.explicitScheduling.examples.throughput.TimestampObject;
import test.PerformanceTest; import test.PerformanceTest;
...@@ -30,17 +29,40 @@ import test.PerformanceTest; ...@@ -30,17 +29,40 @@ import test.PerformanceTest;
* *
* @since 1.10 * @since 1.10
*/ */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MethodCallThoughputTimestampAnalysis16Test extends PerformanceTest { public class MethodCallThoughputTimestampAnalysis16Test extends PerformanceTest {
// TODO use @Parameter for the number of threads
@Test @Test
public void testWithManyObjectsAnd1Thread() { public void testWithManyObjectsAnd1Thread() {
long durationWith1Thread = this.performAnalysis(1, -1); this.performAnalysis(1);
this.performAnalysis(2, durationWith1Thread); }
this.performAnalysis(4, durationWith1Thread);
// this.performAnalysis(8, stopWatch.getDurationInNs()); @Test
public void testWithManyObjectsAnd2Threads() {
this.performAnalysis(2);
}
@Test
public void testWithManyObjectsAnd4Threads() {
this.performAnalysis(4);
} }
private long performAnalysis(final int numThreads, final long durationWith1Thread) { // @AfterClass
// public static void afterClass() {
// PerformanceResult test16a = PerformanceTest.measurementRepository.performanceResults
// .get("testWithManyObjectsAnd1Thread(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
// PerformanceResult test16b = PerformanceTest.measurementRepository.performanceResults
// .get("testWithManyObjectsAnd2Threads(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
// PerformanceResult test16c = PerformanceTest.measurementRepository.performanceResults
// .get("testWithManyObjectsAnd4Threads(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
// // check speedup
// assertEquals(2, (double) test16a.overallDurationInNs / test16b.overallDurationInNs, 0.2);
// assertEquals(2.5, (double) test16a.overallDurationInNs / test16c.overallDurationInNs, 0.2);
// }
private void performAnalysis(final int numThreads) {
System.out.println("Testing teetime (mc) with NUM_OBJECTS_TO_CREATE=" + NUM_OBJECTS_TO_CREATE + ", NUM_NOOP_FILTERS=" System.out.println("Testing teetime (mc) with NUM_OBJECTS_TO_CREATE=" + NUM_OBJECTS_TO_CREATE + ", NUM_NOOP_FILTERS="
+ NUM_NOOP_FILTERS + "..."); + NUM_NOOP_FILTERS + "...");
...@@ -63,22 +85,7 @@ public class MethodCallThoughputTimestampAnalysis16Test extends PerformanceTest ...@@ -63,22 +85,7 @@ public class MethodCallThoughputTimestampAnalysis16Test extends PerformanceTest
analysis.onTerminate(); analysis.onTerminate();
} }
// TODO refactor test this.timestampObjects = ListUtil.merge(analysis.getTimestampObjectsList());
List<TimestampObject> timestampObjects = ListUtil.merge(analysis.getTimestampObjectsList());
StatisticsUtil.printStatistics(this.stopWatch.getDurationInNs(), timestampObjects);
if (durationWith1Thread != -1) {
double speedup = (double) durationWith1Thread / this.stopWatch.getDurationInNs();
System.out.println("Speedup (from 1 to " + numThreads + " threads): " + String.format("%.2f", speedup));
} }
return this.stopWatch.getDurationInNs();
}
public static void main(final String[] args) {
MethodCallThoughputTimestampAnalysis16Test test = new MethodCallThoughputTimestampAnalysis16Test();
test.before();
test.testWithManyObjectsAnd1Thread();
}
} }
...@@ -25,8 +25,8 @@ import teetime.variant.explicitScheduling.framework.core.Analysis; ...@@ -25,8 +25,8 @@ import teetime.variant.explicitScheduling.framework.core.Analysis;
import teetime.variant.methodcallWithPorts.framework.core.Pipeline; import teetime.variant.methodcallWithPorts.framework.core.Pipeline;
import teetime.variant.methodcallWithPorts.framework.core.RunnableStage; import teetime.variant.methodcallWithPorts.framework.core.RunnableStage;
import teetime.variant.methodcallWithPorts.framework.core.StageWithPort; import teetime.variant.methodcallWithPorts.framework.core.StageWithPort;
import teetime.variant.methodcallWithPorts.framework.core.pipe.SingleElementPipe;
import teetime.variant.methodcallWithPorts.framework.core.pipe.SpScPipe; import teetime.variant.methodcallWithPorts.framework.core.pipe.SpScPipe;
import teetime.variant.methodcallWithPorts.framework.core.pipe.UnorderedGrowablePipe;
import teetime.variant.methodcallWithPorts.stage.CollectorSink; import teetime.variant.methodcallWithPorts.stage.CollectorSink;
import teetime.variant.methodcallWithPorts.stage.Distributor; import teetime.variant.methodcallWithPorts.stage.Distributor;
import teetime.variant.methodcallWithPorts.stage.NoopFilter; import teetime.variant.methodcallWithPorts.stage.NoopFilter;
...@@ -42,6 +42,7 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter; ...@@ -42,6 +42,7 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter;
*/ */
public class MethodCallThroughputAnalysis16 extends Analysis { public class MethodCallThroughputAnalysis16 extends Analysis {
private static final int SPSC_INITIAL_CAPACITY = 100100;
private static final int NUM_WORKER_THREADS = Runtime.getRuntime().availableProcessors(); private static final int NUM_WORKER_THREADS = Runtime.getRuntime().availableProcessors();
private int numInputObjects; private int numInputObjects;
...@@ -92,7 +93,7 @@ public class MethodCallThroughputAnalysis16 extends Analysis { ...@@ -92,7 +93,7 @@ public class MethodCallThroughputAnalysis16 extends Analysis {
pipeline.setFirstStage(objectProducer); pipeline.setFirstStage(objectProducer);
pipeline.setLastStage(this.distributor); pipeline.setLastStage(this.distributor);
UnorderedGrowablePipe.connect(objectProducer.getOutputPort(), this.distributor.getInputPort()); SingleElementPipe.connect(objectProducer.getOutputPort(), this.distributor.getInputPort());
return pipeline; return pipeline;
} }
...@@ -120,16 +121,16 @@ public class MethodCallThroughputAnalysis16 extends Analysis { ...@@ -120,16 +121,16 @@ public class MethodCallThroughputAnalysis16 extends Analysis {
pipeline.addIntermediateStage(stopTimestampFilter); pipeline.addIntermediateStage(stopTimestampFilter);
pipeline.setLastStage(collectorSink); pipeline.setLastStage(collectorSink);
SpScPipe.connect(previousStage.getOutputPort(), relay.getInputPort()); SpScPipe.connect(previousStage.getOutputPort(), relay.getInputPort(), SPSC_INITIAL_CAPACITY);
UnorderedGrowablePipe.connect(relay.getOutputPort(), startTimestampFilter.getInputPort()); SingleElementPipe.connect(relay.getOutputPort(), startTimestampFilter.getInputPort());
UnorderedGrowablePipe.connect(startTimestampFilter.getOutputPort(), noopFilters[0].getInputPort()); SingleElementPipe.connect(startTimestampFilter.getOutputPort(), noopFilters[0].getInputPort());
for (int i = 0; i < noopFilters.length - 1; i++) { for (int i = 0; i < noopFilters.length - 1; i++) {
UnorderedGrowablePipe.connect(noopFilters[i].getOutputPort(), noopFilters[i + 1].getInputPort()); SingleElementPipe.connect(noopFilters[i].getOutputPort(), noopFilters[i + 1].getInputPort());
} }
UnorderedGrowablePipe.connect(noopFilters[noopFilters.length - 1].getOutputPort(), stopTimestampFilter.getInputPort()); SingleElementPipe.connect(noopFilters[noopFilters.length - 1].getOutputPort(), stopTimestampFilter.getInputPort());
UnorderedGrowablePipe.connect(stopTimestampFilter.getOutputPort(), collectorSink.getInputPort()); SingleElementPipe.connect(stopTimestampFilter.getOutputPort(), collectorSink.getInputPort());
return new RunnableStage(pipeline); return new RunnableStage(pipeline);
} }
......
...@@ -15,13 +15,10 @@ ...@@ -15,13 +15,10 @@
***************************************************************************/ ***************************************************************************/
package teetime.variant.methodcallWithPorts.examples.experiment17; package teetime.variant.methodcallWithPorts.examples.experiment17;
import java.util.List;
import org.junit.Test; import org.junit.Test;
import teetime.util.ConstructorClosure; import teetime.util.ConstructorClosure;
import teetime.util.ListUtil; import teetime.util.ListUtil;
import teetime.util.StatisticsUtil;
import teetime.variant.explicitScheduling.examples.throughput.TimestampObject; import teetime.variant.explicitScheduling.examples.throughput.TimestampObject;
import test.PerformanceTest; import test.PerformanceTest;
...@@ -58,10 +55,7 @@ public class MethodCallThoughputTimestampAnalysis17Test extends PerformanceTest ...@@ -58,10 +55,7 @@ public class MethodCallThoughputTimestampAnalysis17Test extends PerformanceTest
analysis.onTerminate(); analysis.onTerminate();
} }
// TODO refactor test this.timestampObjects = ListUtil.merge(analysis.getTimestampObjectsList());
List<TimestampObject> timestampObjects = ListUtil.merge(analysis.getTimestampObjectsList());
StatisticsUtil.printStatistics(this.stopWatch.getDurationInNs(), timestampObjects);
// } // }
} }
} }
...@@ -45,6 +45,7 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter; ...@@ -45,6 +45,7 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter;
*/ */
public class MethodCallThroughputAnalysis17 extends Analysis { public class MethodCallThroughputAnalysis17 extends Analysis {
private static final int SPSC_INITIAL_CAPACITY = 100100;
private static final int NUM_WORKER_THREADS = Runtime.getRuntime().availableProcessors(); private static final int NUM_WORKER_THREADS = Runtime.getRuntime().availableProcessors();
private int numInputObjects; private int numInputObjects;
...@@ -153,7 +154,7 @@ public class MethodCallThroughputAnalysis17 extends Analysis { ...@@ -153,7 +154,7 @@ public class MethodCallThroughputAnalysis17 extends Analysis {
pipeline.addIntermediateStage(stopTimestampFilter); pipeline.addIntermediateStage(stopTimestampFilter);
pipeline.setLastStage(collectorSink); pipeline.setLastStage(collectorSink);
IPipe<TimestampObject> startPipe = new SpScPipe<TimestampObject>(); IPipe<TimestampObject> startPipe = new SpScPipe<TimestampObject>(SPSC_INITIAL_CAPACITY);
try { try {
for (int i = 0; i < this.numInputObjects; i++) { for (int i = 0; i < this.numInputObjects; i++) {
startPipe.add(this.inputObjectCreator.create()); startPipe.add(this.inputObjectCreator.create());
......
...@@ -42,6 +42,7 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter; ...@@ -42,6 +42,7 @@ import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter;
*/ */
public class MethodCallThroughputAnalysis18 extends Analysis { public class MethodCallThroughputAnalysis18 extends Analysis {
private static final int SPSC_INITIAL_CAPACITY = 4;
private static final int NUM_WORKER_THREADS = Runtime.getRuntime().availableProcessors(); private static final int NUM_WORKER_THREADS = Runtime.getRuntime().availableProcessors();
private int numInputObjects; private int numInputObjects;
...@@ -111,7 +112,7 @@ public class MethodCallThroughputAnalysis18 extends Analysis { ...@@ -111,7 +112,7 @@ public class MethodCallThroughputAnalysis18 extends Analysis {
pipeline.addIntermediateStage(stopTimestampFilter); pipeline.addIntermediateStage(stopTimestampFilter);
pipeline.setLastStage(collectorSink); pipeline.setLastStage(collectorSink);
SpScPipe.connect(previousStage.getOutputPort(), relay.getInputPort()); SpScPipe.connect(previousStage.getOutputPort(), relay.getInputPort(), SPSC_INITIAL_CAPACITY);
UnorderedGrowablePipe.connect(relay.getOutputPort(), startTimestampFilter.getInputPort()); UnorderedGrowablePipe.connect(relay.getOutputPort(), startTimestampFilter.getInputPort());
......
/***************************************************************************
* Copyright 2014 Kieker Project (http://kieker-monitoring.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
package teetime.variant.methodcallWithPorts.examples.experiment19;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import teetime.util.ConstructorClosure;
import teetime.util.ListUtil;
import teetime.variant.explicitScheduling.examples.throughput.TimestampObject;
import test.PerformanceTest;
/**
* @author Christian Wulf
*
* @since 1.10
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MethodCallThoughputTimestampAnalysis19Test extends PerformanceTest {
// TODO use @Parameter for the number of threads
@Test
public void testWithManyObjectsAnd1Thread() {
this.performAnalysis(1);
}
@Test
public void testWithManyObjectsAnd2Threads() {
this.performAnalysis(2);
}
@Test
public void testWithManyObjectsAnd4Threads() {
this.performAnalysis(4);
}
// @AfterClass
// public static void afterClass() {
// PerformanceResult test16a = PerformanceTest.measurementRepository.performanceResults
// .get("testWithManyObjectsAnd1Thread(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
// PerformanceResult test16b = PerformanceTest.measurementRepository.performanceResults
// .get("testWithManyObjectsAnd2Threads(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
// PerformanceResult test16c = PerformanceTest.measurementRepository.performanceResults
// .get("testWithManyObjectsAnd4Threads(teetime.variant.methodcallWithPorts.examples.experiment16.MethodCallThoughputTimestampAnalysis16Test)");
// // check speedup
// assertEquals(2, (double) test16a.overallDurationInNs / test16b.overallDurationInNs, 0.2);
// assertEquals(2.5, (double) test16a.overallDurationInNs / test16c.overallDurationInNs, 0.2);
// }
private void performAnalysis(final int numThreads) {
System.out.println("Testing teetime (mc) with NUM_OBJECTS_TO_CREATE=" + NUM_OBJECTS_TO_CREATE + ", NUM_NOOP_FILTERS="
+ NUM_NOOP_FILTERS + "...");
final MethodCallThroughputAnalysis19 analysis = new MethodCallThroughputAnalysis19();
analysis.setNumWorkerThreads(numThreads);
analysis.setNumNoopFilters(NUM_NOOP_FILTERS);
analysis.setInput(NUM_OBJECTS_TO_CREATE, new ConstructorClosure<TimestampObject>() {
@Override
public TimestampObject create() {
return new TimestampObject();
}
});
analysis.init();
this.stopWatch.start();
try {
analysis.start();
} finally {
this.stopWatch.end();
analysis.onTerminate();
}
this.timestampObjects = ListUtil.merge(analysis.getTimestampObjectsList());
}
}
/***************************************************************************
* Copyright 2014 Kieker Project (http://kieker-monitoring.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
package teetime.variant.methodcallWithPorts.examples.experiment19;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import teetime.util.ConstructorClosure;
import teetime.variant.explicitScheduling.examples.throughput.TimestampObject;
import teetime.variant.explicitScheduling.framework.core.Analysis;
import teetime.variant.methodcallWithPorts.framework.core.Pipeline;
import teetime.variant.methodcallWithPorts.framework.core.RunnableStage;
import teetime.variant.methodcallWithPorts.framework.core.StageWithPort;
import teetime.variant.methodcallWithPorts.framework.core.pipe.OrderedGrowableArrayPipe;
import teetime.variant.methodcallWithPorts.framework.core.pipe.SpScPipe;
import teetime.variant.methodcallWithPorts.stage.CollectorSink;
import teetime.variant.methodcallWithPorts.stage.Distributor;
import teetime.variant.methodcallWithPorts.stage.NoopFilter;
import teetime.variant.methodcallWithPorts.stage.ObjectProducer;
import teetime.variant.methodcallWithPorts.stage.Relay;
import teetime.variant.methodcallWithPorts.stage.StartTimestampFilter;
import teetime.variant.methodcallWithPorts.stage.StopTimestampFilter;
/**
* @author Christian Wulf
*
* @since 1.10
*/
public class MethodCallThroughputAnalysis19 extends Analysis {
private static final int SPSC_INITIAL_CAPACITY = 100100;
private static final int NUM_WORKER_THREADS = Runtime.getRuntime().availableProcessors();
private int numInputObjects;
private ConstructorClosure<TimestampObject> inputObjectCreator;
private int numNoopFilters;
private final List<List<TimestampObject>> timestampObjectsList = new LinkedList<List<TimestampObject>>();
private Distributor<TimestampObject> distributor;
private Thread producerThread;
private Thread[] workerThreads;
private int numWorkerThreads;
@Override
public void init() {
super.init();
Pipeline<Void, TimestampObject> producerPipeline = this.buildProducerPipeline(this.numInputObjects, this.inputObjectCreator);
this.producerThread = new Thread(new RunnableStage(producerPipeline));
this.numWorkerThreads = Math.min(NUM_WORKER_THREADS, this.numWorkerThreads);
this.workerThreads = new Thread[this.numWorkerThreads];
for (int i = 0; i < this.workerThreads.length; i++) {
List<TimestampObject> resultList = new ArrayList<TimestampObject>(this.numInputObjects);
this.timestampObjectsList.add(resultList);
Runnable workerRunnable = this.buildPipeline(producerPipeline, resultList);
this.workerThreads[i] = new Thread(workerRunnable);
}
}
private Pipeline<Void, TimestampObject> buildProducerPipeline(final int numInputObjects, final ConstructorClosure<TimestampObject> inputObjectCreator) {
final ObjectProducer<TimestampObject> objectProducer = new ObjectProducer<TimestampObject>(numInputObjects, inputObjectCreator);
this.distributor = new Distributor<TimestampObject>();
final Pipeline<Void, TimestampObject> pipeline = new Pipeline<Void, TimestampObject>();
pipeline.setFirstStage(objectProducer);
pipeline.setLastStage(this.distributor);
OrderedGrowableArrayPipe.connect(objectProducer.getOutputPort(), this.distributor.getInputPort());
return pipeline;
}
/**
* @param numNoopFilters
* @since 1.10
*/
private Runnable buildPipeline(final StageWithPort<Void, TimestampObject> previousStage, final List<TimestampObject> timestampObjects) {
Relay<TimestampObject> relay = new Relay<TimestampObject>();
@SuppressWarnings("unchecked")
final NoopFilter<TimestampObject>[] noopFilters = new NoopFilter[this.numNoopFilters];
// create stages
final StartTimestampFilter startTimestampFilter = new StartTimestampFilter();
for (int i = 0; i < noopFilters.length; i++) {
noopFilters[i] = new NoopFilter<TimestampObject>();
}
final StopTimestampFilter stopTimestampFilter = new StopTimestampFilter();
final CollectorSink<TimestampObject> collectorSink = new CollectorSink<TimestampObject>(timestampObjects);
final Pipeline<TimestampObject, Object> pipeline = new Pipeline<TimestampObject, Object>();
pipeline.setFirstStage(relay);
pipeline.addIntermediateStage(startTimestampFilter);
pipeline.addIntermediateStages(noopFilters);
pipeline.addIntermediateStage(stopTimestampFilter);
pipeline.setLastStage(collectorSink);
SpScPipe.connect(previousStage.getOutputPort(), relay.getInputPort(), SPSC_INITIAL_CAPACITY);
OrderedGrowableArrayPipe.connect(relay.getOutputPort(), startTimestampFilter.getInputPort());
OrderedGrowableArrayPipe.connect(startTimestampFilter.getOutputPort(), noopFilters[0].getInputPort());
for (int i = 0; i < noopFilters.length - 1; i++) {
OrderedGrowableArrayPipe.connect(noopFilters[i].getOutputPort(), noopFilters[i + 1].getInputPort());
}
OrderedGrowableArrayPipe.connect(noopFilters[noopFilters.length - 1].getOutputPort(), stopTimestampFilter.getInputPort());
OrderedGrowableArrayPipe.connect(stopTimestampFilter.getOutputPort(), collectorSink.getInputPort());
return new RunnableStage(pipeline);
}
@Override
public void start() {
super.start();
this.producerThread.start();
for (Thread workerThread : this.workerThreads) {
workerThread.start();
}
try {
this.producerThread.join();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
for (Thread workerThread : this.workerThreads) {
workerThread.join();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setInput(final int numInputObjects, final ConstructorClosure<TimestampObject> inputObjectCreator) {
this.numInputObjects = numInputObjects;
this.inputObjectCreator = inputObjectCreator;
}
public int getNumNoopFilters() {
return this.numNoopFilters;
}
public void setNumNoopFilters(final int numNoopFilters) {
this.numNoopFilters = numNoopFilters;
}
public List<List<TimestampObject>> getTimestampObjectsList() {
return this.timestampObjectsList;
}
public int getNumWorkerThreads() {
return this.numWorkerThreads;
}
public void setNumWorkerThreads(final int numWorkerThreads) {
this.numWorkerThreads = numWorkerThreads;
}
}
...@@ -6,6 +6,7 @@ import teetime.util.StatisticsUtil; ...@@ -6,6 +6,7 @@ import teetime.util.StatisticsUtil;
public class PerformanceResult { public class PerformanceResult {
public long overallDurationInNs;
public long sumInNs; public long sumInNs;
public Map<Double, Long> quantiles; public Map<Double, Long> quantiles;
public long avgDurInNs; public long avgDurInNs;
...@@ -14,6 +15,10 @@ public class PerformanceResult { ...@@ -14,6 +15,10 @@ public class PerformanceResult {
@Override @Override
public String toString() { public String toString() {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("overallDurationInNs: ");
stringBuilder.append(this.overallDurationInNs);
stringBuilder.append("\n");
stringBuilder.append("sumInNs: "); stringBuilder.append("sumInNs: ");
stringBuilder.append(this.sumInNs); stringBuilder.append(this.sumInNs);
stringBuilder.append("\n"); stringBuilder.append("\n");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment