Revision: 73b887c7de3c
Author: Paul Smith <psm...@apache.org>
Date: Mon Jun 20 04:55:47 2011
Log: Unused Import auto-fix (babylon-bdd)
http://code.google.com/p/parfait/source/detail?r=73b887c7de3c
Revision: 66719c4b5d23
Author: psmith <psm...@aconex.com>
Date: Fri Feb 10 18:21:40 2012
Log: QuiescentRegistryListener started a timer that wasn't marked as a
Daem...
http://code.google.com/p/parfait/source/detail?r=66719c4b5d23
Revision: ddfad49de597
Author: psmith <psm...@aconex.com>
Date: Fri Feb 10 18:54:35 2012
Log: Get rid of timer that wasn't actually used, the Scheduler is
already n...
http://code.google.com/p/parfait/source/detail?r=ddfad49de597
Revision: 6c6871c1fefc
Author: psmith <psm...@aconex.com>
Date: Fri Feb 10 18:55:26 2012
Log: Very basic benchmark to test the number of counter increments can
occu...
http://code.google.com/p/parfait/source/detail?r=6c6871c1fefc
Revision: 8813e3217991
Author: psmith <psm...@aconex.com>
Date: Fri Feb 10 19:09:02 2012
Log: Run 2 benchmarks, one with pcp not started to see difference
between t...
http://code.google.com/p/parfait/source/detail?r=8813e3217991
Revision: 604a789ff728
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:25:36 2012
Log: Add appassembler and assembly to build a tar ball for the
benchmark se...
http://code.google.com/p/parfait/source/detail?r=604a789ff728
Revision: 78ce0cf99a35
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:27:55 2012
Log: Introduce perMetricLock option, which is actually on by default
now to...
http://code.google.com/p/parfait/source/detail?r=78ce0cf99a35
Revision: 3552f7493e16
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:29:22 2012
Log: Mark these long's as volatile because the main thread will read
these ...
http://code.google.com/p/parfait/source/detail?r=3552f7493e16
Revision: 8d3c0937229c
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:31:53 2012
Log: Refactor the benchmark class to an Object-like existence and run
2 com...
http://code.google.com/p/parfait/source/detail?r=8d3c0937229c
Revision: d6d9a6118992
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:32:46 2012
Log: Hg: --
http://code.google.com/p/parfait/source/detail?r=d6d9a6118992
==============================================================================
Revision: 73b887c7de3c
Author: Paul Smith <psm...@apache.org>
Date: Mon Jun 20 04:55:47 2011
Log: Unused Import auto-fix (babylon-bdd)
http://code.google.com/p/parfait/source/detail?r=73b887c7de3c
Modified:
/parfait-core/src/test/java/com/custardsource/parfait/QuiescentRegistryListenerTest.java
/parfait-spring/src/test/java/com/custardsource/parfait/spring/MonitorTest.java
=======================================
---
/parfait-core/src/test/java/com/custardsource/parfait/QuiescentRegistryListenerTest.java
Mon Dec 20 21:35:37 2010
+++
/parfait-core/src/test/java/com/custardsource/parfait/QuiescentRegistryListenerTest.java
Mon Jun 20 04:55:47 2011
@@ -3,7 +3,6 @@
import org.junit.Test;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
public class QuiescentRegistryListenerTest {
private static final int QUIET_PERIOD_IN_SECONDS = 1;
=======================================
---
/parfait-spring/src/test/java/com/custardsource/parfait/spring/MonitorTest.java
Sat Feb 19 18:50:52 2011
+++
/parfait-spring/src/test/java/com/custardsource/parfait/spring/MonitorTest.java
Mon Jun 20 04:55:47 2011
@@ -4,7 +4,6 @@
import com.custardsource.parfait.MonitorableRegistry;
import com.custardsource.parfait.MonitoredCounter;
import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
import com.google.common.collect.Iterators;
import com.sun.istack.internal.Nullable;
import org.springframework.context.ApplicationContext;
@@ -13,7 +12,6 @@
import junit.framework.TestCase;
import java.util.Collection;
-import java.util.Collections;
public class MonitorTest extends TestCase {
==============================================================================
Revision: 66719c4b5d23
Author: psmith <psm...@aconex.com>
Date: Fri Feb 10 18:21:40 2012
Log: QuiescentRegistryListener started a timer that wasn't marked as a
Daemon.
http://code.google.com/p/parfait/source/detail?r=66719c4b5d23
Modified:
/parfait-core/src/main/java/com/custardsource/parfait/QuiescentRegistryListener.java
=======================================
---
/parfait-core/src/main/java/com/custardsource/parfait/QuiescentRegistryListener.java
Mon Dec 20 21:35:37 2010
+++
/parfait-core/src/main/java/com/custardsource/parfait/QuiescentRegistryListener.java
Fri Feb 10 18:21:40 2012
@@ -1,11 +1,10 @@
package com.custardsource.parfait;
-import org.apache.log4j.Logger;
-
import java.util.Timer;
import java.util.TimerTask;
import com.google.common.base.Supplier;
+import org.apache.log4j.Logger;
/**
* Designed to run code after the MonitorableRegistry has become quiet, in
terms of addition of new metrics
@@ -21,7 +20,7 @@
private final Supplier<Long> clock;
public QuiescentRegistryListener(final Runnable runnable, final long
quietPeriodInMillis) {
- this (runnable, new SystemTimePoller(), quietPeriodInMillis, new
TimerScheduler(new Timer(QuiescentRegistryListener.class.getName())));
+ this (runnable, new SystemTimePoller(), quietPeriodInMillis, new
TimerScheduler(new Timer(QuiescentRegistryListener.class.getName(),true)));
}
QuiescentRegistryListener(final Runnable runnable, final
Supplier<Long> clock, final long quietPeriodInMillis, Scheduler scheduler) {
==============================================================================
Revision: ddfad49de597
Author: psmith <psm...@aconex.com>
Date: Fri Feb 10 18:54:35 2012
Log: Get rid of timer that wasn't actually used, the Scheduler is
already now using a non-daemon thread, so things stop properly now.
http://code.google.com/p/parfait/source/detail?r=ddfad49de597
Modified:
/parfait-core/src/main/java/com/custardsource/parfait/QuiescentRegistryListener.java
=======================================
---
/parfait-core/src/main/java/com/custardsource/parfait/QuiescentRegistryListener.java
Fri Feb 10 18:21:40 2012
+++
/parfait-core/src/main/java/com/custardsource/parfait/QuiescentRegistryListener.java
Fri Feb 10 18:54:35 2012
@@ -13,7 +13,6 @@
private static final Logger LOG =
Logger.getLogger(QuiescentRegistryListener.class);
- private final Timer quiescentTimer = new
Timer(getClass().getSimpleName(), true);
private final Scheduler quiescentScheduler;
private volatile long lastTimeMonitorableAdded = 0;
private final Object lock = new Object();
@@ -47,6 +46,5 @@
}
public void stop(){
- quiescentTimer.cancel();
}
}
==============================================================================
Revision: 6c6871c1fefc
Author: psmith <psm...@aconex.com>
Date: Fri Feb 10 18:55:26 2012
Log: Very basic benchmark to test the number of counter increments can
occur and what sort of blocked time/count is observed.
http://code.google.com/p/parfait/source/detail?r=6c6871c1fefc
Added:
/parfait-benchmark/pom.xml
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/CounterIncrementer.java
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/StandardMetricThroughPutBenchmark.java
Modified:
/pom.xml
=======================================
--- /dev/null
+++ /parfait-benchmark/pom.xml Fri Feb 10 18:55:26 2012
@@ -0,0 +1,39 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.custardsource.parfait</groupId>
+ <artifactId>parfait-benchmark</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>parfait-benchmark</name>
+ <description>Benchmarking tools to test various changes to
pcp</description>
+ <parent>
+ <groupId>com.custardsource</groupId>
+ <artifactId>parfait</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>com.custardsource.parfait</groupId>
+ <artifactId>dxm</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.custardsource.parfait</groupId>
+ <artifactId>parfait-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.custardsource.parfait</groupId>
+ <artifactId>parfait-pcp</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.custardsource.parfait</groupId>
+ <artifactId>parfait-spring</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ </dependencies>
+</project>
=======================================
--- /dev/null
+++
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/CounterIncrementer.java
Fri Feb 10 18:55:26 2012
@@ -0,0 +1,53 @@
+package com.custardsource.parfait.benchmark;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.util.List;
+
+import com.custardsource.parfait.MonitoredCounter;
+
+class CounterIncrementer implements Runnable{
+
+ private final List<MonitoredCounter> counters;
+ private final int iterations;
+ private ThreadInfo initialThreadInfo;
+ private long totalBlockedCount;
+ private long totalBlockedTime;
+
+ public CounterIncrementer(List<MonitoredCounter> counters, int
iterations) {
+ this.counters = counters;
+ this.iterations = iterations;
+ }
+
+ @Override
+ public void run() {
+
+
ManagementFactory.getThreadMXBean().setThreadContentionMonitoringEnabled(true);
+
+ this.initialThreadInfo =
ManagementFactory.getThreadMXBean().getThreadInfo(Thread.currentThread().getId());
+ long initialBlockedCount = initialThreadInfo.getBlockedCount();
+ long initialBlockedTime = initialThreadInfo.getBlockedTime();
+ for (int i = 0; i < iterations; i++) {
+
+ for (MonitoredCounter counter : counters) {
+ counter.inc();
+ }
+ }
+
+ ThreadInfo finalThreadInfo =
ManagementFactory.getThreadMXBean().getThreadInfo(Thread.currentThread().getId());
+ long finalBlockedCount = finalThreadInfo.getBlockedCount();
+ long finalBlockedTime = finalThreadInfo.getBlockedTime();
+
+ totalBlockedCount = finalBlockedCount-initialBlockedCount;
+ totalBlockedTime = finalBlockedTime-initialBlockedTime;
+ }
+
+
+ public long getTotalBlockedCount() {
+ return totalBlockedCount;
+ }
+
+ public long getTotalBlockedTime() {
+ return totalBlockedTime;
+ }
+}
=======================================
--- /dev/null
+++
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/StandardMetricThroughPutBenchmark.java
Fri Feb 10 18:55:26 2012
@@ -0,0 +1,113 @@
+package com.custardsource.parfait.benchmark;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import com.custardsource.parfait.MonitorableRegistry;
+import com.custardsource.parfait.MonitoredCounter;
+import com.custardsource.parfait.dxm.IdentifierSourceSet;
+import com.custardsource.parfait.dxm.PcpMmvWriter;
+import com.custardsource.parfait.pcp.EmptyTextSource;
+import com.custardsource.parfait.pcp.MetricDescriptionTextSource;
+import com.custardsource.parfait.pcp.MetricNameMapper;
+import com.custardsource.parfait.pcp.PcpMonitorBridge;
+import com.custardsource.parfait.spring.SelfStartingMonitoringView;
+
+public class StandardMetricThroughPutBenchmark {
+
+
+ private static final int CLUSTER_IDENTIFIER = 123;
+
+ public static void main(String[] args) throws InterruptedException {
+
+ int numThreads = 8;
+ int iterations = 1000;
+ int numCounters = 1000;
+
+ long begin = System.currentTimeMillis();
+ MonitorableRegistry monitorableRegistry = new
MonitorableRegistry();
+
+ List<MonitoredCounter> counters = createCounters(numCounters,
monitorableRegistry);
+
+
+ final PcpMmvWriter mmvWriter = new
PcpMmvWriter("parfait-microbenchmark-" +
StandardMetricThroughPutBenchmark.class.getSimpleName() + ".mmv",
IdentifierSourceSet.DEFAULT_SET);
+ mmvWriter.setClusterIdentifier(CLUSTER_IDENTIFIER);
+
+ final PcpMonitorBridge pcpMonitorBridge = new
PcpMonitorBridge(mmvWriter, MetricNameMapper.PASSTHROUGH_MAPPER, new
MetricDescriptionTextSource(), new EmptyTextSource());
+
+ SelfStartingMonitoringView selfStartingMonitoringView = new
SelfStartingMonitoringView(monitorableRegistry, pcpMonitorBridge, 2000);
+ selfStartingMonitoringView.start();
+
+ List<CounterIncrementer> counterIncrementers =
executeBenchmark(numThreads, iterations, counters);
+ selfStartingMonitoringView.stop();
+
+ long timeTaken = System.currentTimeMillis() - begin;
+
+ report(numThreads, iterations, counters, timeTaken,
counterIncrementers);
+
+
+ }
+
+ private static List<MonitoredCounter> createCounters(int numCounters,
MonitorableRegistry registry) {
+ List<MonitoredCounter> counters = newArrayList();
+
+ for (int i = 0; i < numCounters; i++) {
+ counters.add(new MonitoredCounter("counter." + i, "Counter " +
i, registry));
+ }
+
+ return counters;
+ }
+
+ private static void report(int numThreads, int iterations,
List<MonitoredCounter> counters, long timeTaken, List<CounterIncrementer>
counterIncrementers) {
+ long totalBlockedCount =
computeTotalBlockedCount(counterIncrementers);
+ long totalBlockedTime =
computeTotalBlockedTime(counterIncrementers);
+ double counterIncrements = computeTotalCounterIncrements(counters);
+ double incrementRate = counterIncrements / ((double) timeTaken /
1000);
+
+ System.out.printf("iterations: %d, numThreads: %d,
numCounters: %d, incrementRate: %.2f/sec, blockedCount: %d,
blockedTime: %d", iterations, numThreads, counters.size(), incrementRate,
totalBlockedCount, totalBlockedTime);
+ }
+
+ private static long computeTotalBlockedCount(List<CounterIncrementer>
counterIncrementers) {
+ long totalBlockedCount = 0;
+ for (CounterIncrementer counterIncrementer : counterIncrementers) {
+ totalBlockedCount+=counterIncrementer.getTotalBlockedCount();
+ }
+ return totalBlockedCount;
+ }
+ private static long computeTotalBlockedTime(List<CounterIncrementer>
counterIncrementers) {
+ long totalBlockedTime = 0;
+ for (CounterIncrementer counterIncrementer : counterIncrementers) {
+ totalBlockedTime+=counterIncrementer.getTotalBlockedTime();
+ }
+ return totalBlockedTime;
+ }
+
+ private static double
computeTotalCounterIncrements(List<MonitoredCounter> counters) {
+ double counterIncrements = 0;
+ for (MonitoredCounter counter : counters) {
+ counterIncrements += counter.get();
+ }
+ return counterIncrements;
+ }
+
+
+ private static List<CounterIncrementer> executeBenchmark(int
numThreads, int iterations, List<MonitoredCounter> counters) throws
InterruptedException {
+ ExecutorService executorService =
Executors.newFixedThreadPool(numThreads);
+
+ List<CounterIncrementer> counterIncrementers = newArrayList();
+ for (int i = 0; i < numThreads; i++) {
+ CounterIncrementer counterIncrementer = new
CounterIncrementer(counters, iterations);
+ counterIncrementers.add(counterIncrementer);
+ executorService.execute(counterIncrementer);
+ }
+
+ executorService.shutdown();
+ executorService.awaitTermination(1, TimeUnit.MINUTES);
+ return counterIncrementers;
+ }
+
+}
=======================================
--- /pom.xml Sun Feb 20 18:09:35 2011
+++ /pom.xml Fri Feb 10 18:55:26 2012
@@ -21,6 +21,7 @@
<module>parfait-jdbc</module>
<module>parfait-cxf</module>
<module>parfait-spring</module>
+ <module>parfait-benchmark</module>
</modules>
<url>http://code.google.com/p/parfait/</url>
<inceptionYear>2009</inceptionYear>
==============================================================================
Revision: 8813e3217991
Author: psmith <psm...@aconex.com>
Date: Fri Feb 10 19:09:02 2012
Log: Run 2 benchmarks, one with pcp not started to see difference
between the overhead of it on/off. Change the formatting to use
tab-separated and left pad the incrementRate counter value for easier
comparison.
http://code.google.com/p/parfait/source/detail?r=8813e3217991
Modified:
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/StandardMetricThroughPutBenchmark.java
=======================================
---
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/StandardMetricThroughPutBenchmark.java
Fri Feb 10 18:55:26 2012
+++
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/StandardMetricThroughPutBenchmark.java
Fri Feb 10 19:09:02 2012
@@ -2,6 +2,7 @@
import static com.google.common.collect.Lists.newArrayList;
+import java.text.NumberFormat;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -16,6 +17,7 @@
import com.custardsource.parfait.pcp.MetricNameMapper;
import com.custardsource.parfait.pcp.PcpMonitorBridge;
import com.custardsource.parfait.spring.SelfStartingMonitoringView;
+import org.apache.commons.lang.StringUtils;
public class StandardMetricThroughPutBenchmark {
@@ -25,9 +27,16 @@
public static void main(String[] args) throws InterruptedException {
int numThreads = 8;
- int iterations = 1000;
+ int iterations = 10000;
int numCounters = 1000;
+ runBenchmark(numThreads, iterations, numCounters, false);
+ runBenchmark(numThreads, iterations, numCounters, true);
+
+
+ }
+
+ private static void runBenchmark(int numThreads, int iterations, int
numCounters, boolean startPcp) throws InterruptedException {
long begin = System.currentTimeMillis();
MonitorableRegistry monitorableRegistry = new
MonitorableRegistry();
@@ -40,16 +49,19 @@
final PcpMonitorBridge pcpMonitorBridge = new
PcpMonitorBridge(mmvWriter, MetricNameMapper.PASSTHROUGH_MAPPER, new
MetricDescriptionTextSource(), new EmptyTextSource());
SelfStartingMonitoringView selfStartingMonitoringView = new
SelfStartingMonitoringView(monitorableRegistry, pcpMonitorBridge, 2000);
- selfStartingMonitoringView.start();
+
+ if (startPcp) {
+ selfStartingMonitoringView.start();
+ }
List<CounterIncrementer> counterIncrementers =
executeBenchmark(numThreads, iterations, counters);
- selfStartingMonitoringView.stop();
+ if (startPcp) {
+ selfStartingMonitoringView.stop();
+ }
long timeTaken = System.currentTimeMillis() - begin;
- report(numThreads, iterations, counters, timeTaken,
counterIncrementers);
-
-
+ report(startPcp, numThreads, iterations, counters, timeTaken,
counterIncrementers);
}
private static List<MonitoredCounter> createCounters(int numCounters,
MonitorableRegistry registry) {
@@ -58,30 +70,37 @@
for (int i = 0; i < numCounters; i++) {
counters.add(new MonitoredCounter("counter." + i, "Counter " +
i, registry));
}
-
+
return counters;
}
- private static void report(int numThreads, int iterations,
List<MonitoredCounter> counters, long timeTaken, List<CounterIncrementer>
counterIncrementers) {
+ private static void report(boolean startPcp, int numThreads, int
iterations, List<MonitoredCounter> counters, long timeTaken,
List<CounterIncrementer> counterIncrementers) {
long totalBlockedCount =
computeTotalBlockedCount(counterIncrementers);
long totalBlockedTime =
computeTotalBlockedTime(counterIncrementers);
double counterIncrements = computeTotalCounterIncrements(counters);
+
double incrementRate = counterIncrements / ((double) timeTaken /
1000);
-
- System.out.printf("iterations: %d, numThreads: %d,
numCounters: %d, incrementRate: %.2f/sec, blockedCount: %d,
blockedTime: %d", iterations, numThreads, counters.size(), incrementRate,
totalBlockedCount, totalBlockedTime);
+ NumberFormat numberFormat = NumberFormat.getNumberInstance();
+ numberFormat.setGroupingUsed(true);
+ numberFormat.setMaximumFractionDigits(2);
+ numberFormat.setMinimumFractionDigits(2);
+ String incrementRateString =
StringUtils.leftPad(numberFormat.format(incrementRate), 15);
+
+ System.out.printf("pcpStarted: %s\titerations: %d\t
numThreads: %d\t numCounters: %d\t incrementRate(/sec): %s\t
blockedCount: %d\t blockedTime: %d\n", startPcp, iterations, numThreads,
counters.size(), incrementRateString, totalBlockedCount, totalBlockedTime);
}
private static long computeTotalBlockedCount(List<CounterIncrementer>
counterIncrementers) {
long totalBlockedCount = 0;
for (CounterIncrementer counterIncrementer : counterIncrementers) {
- totalBlockedCount+=counterIncrementer.getTotalBlockedCount();
+ totalBlockedCount += counterIncrementer.getTotalBlockedCount();
}
return totalBlockedCount;
}
+
private static long computeTotalBlockedTime(List<CounterIncrementer>
counterIncrementers) {
long totalBlockedTime = 0;
for (CounterIncrementer counterIncrementer : counterIncrementers) {
- totalBlockedTime+=counterIncrementer.getTotalBlockedTime();
+ totalBlockedTime += counterIncrementer.getTotalBlockedTime();
}
return totalBlockedTime;
}
==============================================================================
Revision: 604a789ff728
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:25:36 2012
Log: Add appassembler and assembly to build a tar ball for the
benchmark set for easier running.
http://code.google.com/p/parfait/source/detail?r=604a789ff728
Added:
/parfait-benchmark/src/main/assembly/appassembler.xml
Modified:
/parfait-benchmark/pom.xml
=======================================
--- /dev/null
+++ /parfait-benchmark/src/main/assembly/appassembler.xml Sat Feb 11
04:25:36 2012
@@ -0,0 +1,23 @@
+<assembly>
+ <formats>
+ <format>tar.gz</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <includes>
+ <include>README*</include>
+ <include>LICENSE*</include>
+ <include>NOTICE*</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/appassembler/lib</directory>
+ <outputDirectory>lib</outputDirectory>
+ </fileSet>
+ <fileSet>
+ <directory>target/appassembler/bin</directory>
+ <outputDirectory>bin</outputDirectory>
+ <fileMode>755</fileMode>
+ </fileSet>
+ </fileSets>
+</assembly>
=======================================
--- /parfait-benchmark/pom.xml Fri Feb 10 18:55:26 2012
+++ /parfait-benchmark/pom.xml Sat Feb 11 04:25:36 2012
@@ -12,6 +12,51 @@
<artifactId>parfait</artifactId>
<version>0.3.0-SNAPSHOT</version>
</parent>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>appassembler-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>assemble</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <repositoryLayout>flat</repositoryLayout>
+ <repositoryName>lib</repositoryName>
+ <programs>
+ <program>
+
<mainClass>com.custardsource.parfait.benchmark.StandardMetricThroughPutBenchmark</mainClass>
+ <name>standardmetricthroughput</name>
+ </program>
+ </programs>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+
<descriptor>src/main/assembly/appassembler.xml</descriptor>
+ </descriptors>
+ <attach>false</attach>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
<dependencies>
<dependency>
<groupId>com.custardsource.parfait</groupId>
@@ -33,7 +78,5 @@
<artifactId>parfait-spring</artifactId>
<version>${project.version}</version>
</dependency>
-
-
</dependencies>
</project>
==============================================================================
Revision: 78ce0cf99a35
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:27:55 2012
Log: Introduce perMetricLock option, which is actually on by default
now to allow writing to differing areas of the memory mapped file to reduce
synchronization contention. This one needs a good review for sure.
http://code.google.com/p/parfait/source/detail?r=78ce0cf99a35
Modified:
/dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java
=======================================
--- /dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java Mon
Feb 21 02:51:09 2011
+++ /dxm/src/main/java/com/custardsource/parfait/dxm/BasePcpWriter.java Sat
Feb 11 04:27:55 2012
@@ -1,12 +1,6 @@
package com.custardsource.parfait.dxm;
-import com.custardsource.parfait.dxm.semantics.Semantics;
-import com.custardsource.parfait.dxm.types.DefaultTypeHandlers;
-import com.custardsource.parfait.dxm.types.TypeHandler;
-import com.google.common.collect.Maps;
-import net.jcip.annotations.GuardedBy;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
+import static com.google.common.collect.Maps.newConcurrentMap;
import javax.measure.unit.Unit;
import java.io.File;
@@ -21,6 +15,15 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import com.custardsource.parfait.dxm.semantics.Semantics;
+import com.custardsource.parfait.dxm.types.DefaultTypeHandlers;
+import com.custardsource.parfait.dxm.types.TypeHandler;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import net.jcip.annotations.GuardedBy;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
public abstract class BasePcpWriter implements PcpWriter {
// TODO only include in-use indoms/instances/metrics (/strings?) in the
header
private final Store<PcpMetricInfo> metricInfoStore;
@@ -32,8 +35,12 @@
private volatile boolean started = false;
@GuardedBy("itself")
private volatile ByteBuffer dataFileBuffer = null;
+ private final Object globalLock = new Object();
+
private final Collection<PcpString> stringInfo = new
CopyOnWriteArrayList<PcpString>();
private final ByteBufferFactory byteBufferFactory;
+ private final Map<PcpValueInfo,ByteBuffer> perMetricByteBuffers =
newConcurrentMap();
+ private boolean usePerMetricLock = true;
protected BasePcpWriter(File file, IdentifierSourceSet
identifierSources) {
@@ -100,8 +107,17 @@
initialiseOffsets();
dataFileBuffer = byteBufferFactory.build(getBufferLength());
- synchronized (dataFileBuffer) {
+ synchronized (globalLock) {
populateDataBuffer(dataFileBuffer, metricData.values());
+
+ for (PcpValueInfo info : metricData.values()) {
+ TypeHandler<?> rawHandler = info.getTypeHandler();
+ int bufferPosition = rawHandler.requiresLargeStorage() ?
info.getLargeValue()
+ .getOffset() : info.getOffset();
+ ByteBuffer metricByteBufferSlice = dataFileBuffer.slice();
+ metricByteBufferSlice.position(bufferPosition);
+ perMetricByteBuffers.put(info, metricByteBufferSlice);
+ }
}
started = true;
@@ -124,8 +140,27 @@
@SuppressWarnings("unchecked")
protected final void updateValue(PcpValueInfo info, Object value) {
@SuppressWarnings("rawtypes")
- TypeHandler rawHandler = info.getTypeHandler();
- synchronized (dataFileBuffer) {
+ TypeHandler rawHandler = info.getTypeHandler();
+
+ if (usePerMetricLock) {
+ writeValueWithLockPerMetric(info, value, rawHandler);
+ } else {
+ writeValueWithGlobalLock(info, value, rawHandler);
+ }
+ }
+
+ private void writeValueWithLockPerMetric(PcpValueInfo info, Object
value, TypeHandler rawHandler) {
+ ByteBuffer perMetricByteBuffer = perMetricByteBuffers.get(info);
+ synchronized (info) {
+ int originalBufferPosition = perMetricByteBuffer.position();
+ rawHandler.putBytes(perMetricByteBuffer, value);
+ perMetricByteBuffer.position(originalBufferPosition);
+ }
+
+ }
+
+ private void writeValueWithGlobalLock(PcpValueInfo info, Object value,
TypeHandler rawHandler) {
+ synchronized (globalLock) {
dataFileBuffer.position(rawHandler.requiresLargeStorage() ?
info.getLargeValue()
.getOffset() : info.getOffset());
rawHandler.putBytes(dataFileBuffer, value);
@@ -227,6 +262,12 @@
stringInfo .add(string);
return string;
}
+
+ public void setPerMetricLock(boolean usePerMetricLock) {
+ Preconditions.checkState(!started, "Cannot change use of
perMetricLock when started");
+ this.usePerMetricLock = usePerMetricLock;
+ }
+
static abstract class Store<T extends PcpId> {
private final Map<String, T> byName = new LinkedHashMap<String,
T>();
==============================================================================
Revision: 3552f7493e16
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:29:22 2012
Log: Mark these long's as volatile because the main thread will read
these after running. I did this because I'm getting 0's during runs with
global locks which seems crazy given how slow they are compared with the
perMetric lock. Still, this doesn't appear to solve the 0, but in my mind
makes more sense due to the interactions between the main thread and the
running thread, this value information may not be read correctly.
http://code.google.com/p/parfait/source/detail?r=3552f7493e16
Modified:
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/CounterIncrementer.java
=======================================
---
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/CounterIncrementer.java
Fri Feb 10 18:55:26 2012
+++
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/CounterIncrementer.java
Sat Feb 11 04:29:22 2012
@@ -11,8 +11,8 @@
private final List<MonitoredCounter> counters;
private final int iterations;
private ThreadInfo initialThreadInfo;
- private long totalBlockedCount;
- private long totalBlockedTime;
+ private volatile long totalBlockedCount;
+ private volatile long totalBlockedTime;
public CounterIncrementer(List<MonitoredCounter> counters, int
iterations) {
this.counters = counters;
==============================================================================
Revision: 8d3c0937229c
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:31:53 2012
Log: Refactor the benchmark class to an Object-like existence and run
2 complete sets of runs, in ascending and descending order to show any
variance that might be associated with JVM warm up that unfairly (or too
fairly) treats the 1st or last benchmark run. Default to use the num
available processors, or use optional parameter passed from the command
line. Tidied up the reporting a bit
http://code.google.com/p/parfait/source/detail?r=8d3c0937229c
Modified:
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/StandardMetricThroughPutBenchmark.java
=======================================
---
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/StandardMetricThroughPutBenchmark.java
Fri Feb 10 19:09:02 2012
+++
/parfait-benchmark/src/main/java/com/custardsource/parfait/benchmark/StandardMetricThroughPutBenchmark.java
Sat Feb 11 04:31:53 2012
@@ -2,6 +2,10 @@
import static com.google.common.collect.Lists.newArrayList;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
import java.text.NumberFormat;
import java.util.List;
import java.util.concurrent.ExecutorService;
@@ -18,25 +22,31 @@
import com.custardsource.parfait.pcp.PcpMonitorBridge;
import com.custardsource.parfait.spring.SelfStartingMonitoringView;
import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.SystemUtils;
public class StandardMetricThroughPutBenchmark {
-
private static final int CLUSTER_IDENTIFIER = 123;
- public static void main(String[] args) throws InterruptedException {
-
- int numThreads = 8;
- int iterations = 10000;
- int numCounters = 1000;
-
- runBenchmark(numThreads, iterations, numCounters, false);
- runBenchmark(numThreads, iterations, numCounters, true);
-
-
+ private final boolean startPcp ;
+ private final boolean usePerMetricLock;
+ private final int numThreads;
+ private final int iterations;
+ private final int numCounters;
+ private final ExecutorService executorService;
+
+
+ public StandardMetricThroughPutBenchmark(int numThreads, int
numCounters, int iterations, boolean startPcp, boolean usePerMetricLock) {
+ this.numThreads = numThreads;
+ this.numCounters = numCounters;
+ this.iterations = iterations;
+ this.startPcp = startPcp;
+ this.usePerMetricLock = usePerMetricLock;
+ this.executorService =
Executors.newFixedThreadPool(this.numThreads);
}
- private static void runBenchmark(int numThreads, int iterations, int
numCounters, boolean startPcp) throws InterruptedException {
+
+ private void runBenchmark() throws InterruptedException {
long begin = System.currentTimeMillis();
MonitorableRegistry monitorableRegistry = new
MonitorableRegistry();
@@ -44,6 +54,8 @@
final PcpMmvWriter mmvWriter = new
PcpMmvWriter("parfait-microbenchmark-" +
StandardMetricThroughPutBenchmark.class.getSimpleName() + ".mmv",
IdentifierSourceSet.DEFAULT_SET);
+ mmvWriter.setPerMetricLock(usePerMetricLock);
+
mmvWriter.setClusterIdentifier(CLUSTER_IDENTIFIER);
final PcpMonitorBridge pcpMonitorBridge = new
PcpMonitorBridge(mmvWriter, MetricNameMapper.PASSTHROUGH_MAPPER, new
MetricDescriptionTextSource(), new EmptyTextSource());
@@ -61,10 +73,10 @@
long timeTaken = System.currentTimeMillis() - begin;
- report(startPcp, numThreads, iterations, counters, timeTaken,
counterIncrementers);
+ report(startPcp, counters, timeTaken, counterIncrementers);
}
- private static List<MonitoredCounter> createCounters(int numCounters,
MonitorableRegistry registry) {
+ private List<MonitoredCounter> createCounters(int numCounters,
MonitorableRegistry registry) {
List<MonitoredCounter> counters = newArrayList();
for (int i = 0; i < numCounters; i++) {
@@ -74,7 +86,7 @@
return counters;
}
- private static void report(boolean startPcp, int numThreads, int
iterations, List<MonitoredCounter> counters, long timeTaken,
List<CounterIncrementer> counterIncrementers) {
+ private void report(boolean startPcp, List<MonitoredCounter> counters,
long timeTaken, List<CounterIncrementer> counterIncrementers) {
long totalBlockedCount =
computeTotalBlockedCount(counterIncrementers);
long totalBlockedTime =
computeTotalBlockedTime(counterIncrementers);
double counterIncrements = computeTotalCounterIncrements(counters);
@@ -86,10 +98,10 @@
numberFormat.setMinimumFractionDigits(2);
String incrementRateString =
StringUtils.leftPad(numberFormat.format(incrementRate), 15);
- System.out.printf("pcpStarted: %s\titerations: %d\t
numThreads: %d\t numCounters: %d\t incrementRate(/sec): %s\t
blockedCount: %d\t blockedTime: %d\n", startPcp, iterations, numThreads,
counters.size(), incrementRateString, totalBlockedCount, totalBlockedTime);
+
System.out.printf("pcpStarted: %s\tperMetricLock: %s\tincrementRate(/sec): %s\t
blockedCount: %d\t blockedTime: %d\n", startPcp, usePerMetricLock,
incrementRateString, totalBlockedCount, totalBlockedTime);
}
- private static long computeTotalBlockedCount(List<CounterIncrementer>
counterIncrementers) {
+ private long computeTotalBlockedCount(List<CounterIncrementer>
counterIncrementers) {
long totalBlockedCount = 0;
for (CounterIncrementer counterIncrementer : counterIncrementers) {
totalBlockedCount += counterIncrementer.getTotalBlockedCount();
@@ -97,7 +109,7 @@
return totalBlockedCount;
}
- private static long computeTotalBlockedTime(List<CounterIncrementer>
counterIncrementers) {
+ private long computeTotalBlockedTime(List<CounterIncrementer>
counterIncrementers) {
long totalBlockedTime = 0;
for (CounterIncrementer counterIncrementer : counterIncrementers) {
totalBlockedTime += counterIncrementer.getTotalBlockedTime();
@@ -105,7 +117,7 @@
return totalBlockedTime;
}
- private static double
computeTotalCounterIncrements(List<MonitoredCounter> counters) {
+ private double computeTotalCounterIncrements(List<MonitoredCounter>
counters) {
double counterIncrements = 0;
for (MonitoredCounter counter : counters) {
counterIncrements += counter.get();
@@ -114,9 +126,7 @@
}
- private static List<CounterIncrementer> executeBenchmark(int
numThreads, int iterations, List<MonitoredCounter> counters) throws
InterruptedException {
- ExecutorService executorService =
Executors.newFixedThreadPool(numThreads);
-
+ private List<CounterIncrementer> executeBenchmark(int numThreads, int
iterations, List<MonitoredCounter> counters) throws InterruptedException {
List<CounterIncrementer> counterIncrementers = newArrayList();
for (int i = 0; i < numThreads; i++) {
CounterIncrementer counterIncrementer = new
CounterIncrementer(counters, iterations);
@@ -128,5 +138,27 @@
executorService.awaitTermination(1, TimeUnit.MINUTES);
return counterIncrementers;
}
+
+ public static void main(String[] args) throws InterruptedException,
UnknownHostException {
+ int numThreads =
args.length<1?Runtime.getRuntime().availableProcessors():Integer.valueOf(args[0]);
+ int numCounters = 1000;
+ int iterations = 10000;
+
+ System.out.printf("Host: %s\tJava: %s\n",
Inet4Address.getLocalHost().getCanonicalHostName(),
SystemUtils.JAVA_VERSION);
+ ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+ System.out.printf("Thread Contention Supported: %s, Enabled by
default: %s\n", threadMXBean.isThreadContentionMonitoringSupported(),
threadMXBean.isThreadContentionMonitoringEnabled());
+ System.out.printf("numThreads: %d, numCounters=%d,
iterations=%d\n", numThreads, numCounters, iterations);
+
+ new StandardMetricThroughPutBenchmark(numThreads, numCounters,
iterations, false, false).runBenchmark();
+ new StandardMetricThroughPutBenchmark(numThreads, numCounters,
iterations, true, false).runBenchmark();
+ new StandardMetricThroughPutBenchmark(numThreads, numCounters,
iterations, true, true).runBenchmark();
+
+ // now do it all again reverse, in case there's any JVM warmup
issues unfairly treating the first/last runs
+ new StandardMetricThroughPutBenchmark(numThreads, numCounters,
iterations, true, true).runBenchmark();
+ new StandardMetricThroughPutBenchmark(numThreads, numCounters,
iterations, true, false).runBenchmark();
+ new StandardMetricThroughPutBenchmark(numThreads, numCounters,
iterations, false, false).runBenchmark();
+
+
+ }
}
==============================================================================
Revision: d6d9a6118992
Author: psmith <psm...@aconex.com>
Date: Sat Feb 11 04:32:46 2012
Log: Hg: --
http://code.google.com/p/parfait/source/detail?r=d6d9a6118992
Modified:
/parfait-spring/src/test/java/com/custardsource/parfait/spring/MonitorTest.java
=======================================
---
/parfait-spring/src/test/java/com/custardsource/parfait/spring/MonitorTest.java
Mon Jun 20 04:55:47 2011
+++
/parfait-spring/src/test/java/com/custardsource/parfait/spring/MonitorTest.java
Sat Feb 11 04:32:46 2012
@@ -5,7 +5,6 @@
import com.custardsource.parfait.MonitoredCounter;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
-import com.sun.istack.internal.Nullable;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -51,7 +50,7 @@
Collection<Monitorable<?>> monitorables =
registry.getMonitorables();
Monitorable<?> monitorable =
Iterators.find(monitorables.iterator(), new Predicate<Monitorable<?>>() {
@Override
- public boolean apply(@Nullable Monitorable<?> monitorable) {
+ public boolean apply(Monitorable<?> monitorable) {
return monitorable.getName().equals(name);
}
});