<span class="Apple-style-span" style>Thanks David for your reply. </span><div style>The business for each F/J task is quite simple, taking message from the front-end I/O threads and put them back into a  transfer queue where the I/O threads would consume and send back to the clients eventually.  Yes, there is a blocking operation for each F/J task that put the messages into a transfer queue. It that okay? </div>
<div style><br></div><div style>Thanks,</div><div style>Min</div><br><div class="gmail_quote">On Tue, Apr 17, 2012 at 8:51 PM, David Holmes <span dir="ltr"><<a href="mailto:davidcholmes@aapt.net.au">davidcholmes@aapt.net.au</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><u></u>



<div>
<div><span><font color="#0000ff" face="Arial">Sorry 
that was somewhat terse.</font></span></div>
<div><span><font color="#0000ff" face="Arial"></font></span> </div>
<div><span><font color="#0000ff" face="Arial">ForkJoinPool is not a drop-in replacement as an arbitrary 
ExecutorService. It is specifically design to efficiently execute tasks that 
implement fork/join parallelism. If your tasks don't perform fork/join 
parallelism but are plain old Runnables/callables that do blocking I/O and other 
"regular" programming operations then they will not likely see any benefit from 
using a ForkJoinPool.</font></span></div><span class="HOEnZb"><font color="#888888">
<div><span><font color="#0000ff" face="Arial"></font></span> </div>
<div><span><font color="#0000ff" face="Arial">David</font></span></div></font></span><div><div class="h5">
<blockquote style="BORDER-LEFT:#0000ff 2px solid;PADDING-LEFT:5px;MARGIN-LEFT:5px;MARGIN-RIGHT:0px" dir="ltr">
  <div dir="ltr" align="left"><font face="Tahoma">-----Original Message-----<br><b>From:</b> 
  <a href="mailto:concurrency-interest-bounces@cs.oswego.edu" target="_blank">concurrency-interest-bounces@cs.oswego.edu</a> 
  [mailto:<a href="mailto:concurrency-interest-bounces@cs.oswego.edu" target="_blank">concurrency-interest-bounces@cs.oswego.edu</a>]<b>On Behalf Of </b>David 
  Holmes<br><b>Sent:</b> Tuesday, 17 April 2012 10:14 PM<br><b>To:</b> Min Zhou; 
  <a href="mailto:concurrency-interest@cs.oswego.edu" target="_blank">concurrency-interest@cs.oswego.edu</a><br><b>Subject:</b> Re: 
  [concurrency-interest] ForkJoinPool seems lead to a worselatencythan 
  traditional ExecutorServices<br><br></font></div>
  <div><span><font color="#0000ff" face="Arial">What 
  makes your RPC project suitable for Fork/Join parallelism?</font></span></div>
  <div><span><font color="#0000ff" face="Arial"></font></span> </div>
  <div><span><font color="#0000ff" face="Arial">David Holmes</font></span></div>
  <blockquote style="BORDER-LEFT:#0000ff 2px solid;PADDING-LEFT:5px;MARGIN-LEFT:5px">
    <div dir="ltr" align="left"><font face="Tahoma">-----Original Message-----<br><b>From:</b> 
    <a href="mailto:concurrency-interest-bounces@cs.oswego.edu" target="_blank">concurrency-interest-bounces@cs.oswego.edu</a> 
    [mailto:<a href="mailto:concurrency-interest-bounces@cs.oswego.edu" target="_blank">concurrency-interest-bounces@cs.oswego.edu</a>]<b>On Behalf Of </b>Min 
    Zhou<br><b>Sent:</b> Tuesday, 17 April 2012 8:30 PM<br><b>To:</b> 
    <a href="mailto:concurrency-interest@cs.oswego.edu" target="_blank">concurrency-interest@cs.oswego.edu</a><br><b>Subject:</b> [concurrency-interest] 
    ForkJoinPool seems lead to a worse latencythan traditional 
    ExecutorServices<br><br></font></div><span>Hi, 
    all,</span> 
    <div><font color="#0000ff" face="Arial"></font><br></div>
    <div>I tried to use  the newest version of  ForkJoinPool from the 
    cvs repository of jsr166y to replace the old  ExecutorService 
    on our RPC project opensource at <a style="COLOR:rgb(17,85,204)" href="http://code.google.com/p/nfs-rpc/" target="_blank">http://code.google.com/p/nfs-rpc/</a> . </div>
    <div><font color="#0000ff" face="Arial"></font><br></div>
    <div>The modification is quite slight. Here is the diff</div>
    <div><font color="#0000ff" face="Arial"></font><br></div>
    <div>
    <div>Index: 
    nfs-rpc-common/src/main/java/code/google/nfs/rpc/NamedForkJoinThreadFactory.java</div>
    <div>===================================================================</div>
    <div>--- 
    nfs-rpc-common/src/main/java/code/google/nfs/rpc/NamedForkJoinThreadFactory.java<span style="WHITE-SPACE:pre-wrap"> </span>(revision 0)</div>
    <div>+++ 
    nfs-rpc-common/src/main/java/code/google/nfs/rpc/NamedForkJoinThreadFactory.java<span style="WHITE-SPACE:pre-wrap"> </span>(revision 0)</div>
    <div>@@ -0,0 +1,48 @@</div>
    <div>+package code.google.nfs.rpc;</div>
    <div>+/**</div>
    <div>+ * nfs-rpc</div>
    <div>+ *   Apache License</div>
    <div>+ *   </div>
    <div>+ *   <a style="COLOR:rgb(17,85,204)" href="http://code.google.com/p/nfs-rpc" target="_blank">http://code.google.com/p/nfs-rpc</a> (c) 2011</div>
    <div>+ */</div>
    <div>+import java.util.concurrent.atomic.AtomicInteger;</div>
    <div>+</div>
    <div>+import code.google.nfs.rpc.jsr166y.ForkJoinPool;</div>
    <div>+import 
    code.google.nfs.rpc.jsr166y.ForkJoinPool.ForkJoinWorkerThreadFactory;</div>
    <div>+import code.google.nfs.rpc.jsr166y.ForkJoinWorkerThread;</div>
    <div>+</div>
    <div>+/**</div>
    <div>+ * Helper class to let user can monitor worker threads.</div>
    <div>+ * </div>
    <div>+ * @author <a href="mailto:<a style="COLOR:rgb(17,85,204)" href="mailto:coderplay@gmail.com" target="_blank">coderplay@gmail.com</a>">coderplay</a></div>
    <div>+ */</div>
    <div>+public class NamedForkJoinThreadFactory implements 
    ForkJoinWorkerThreadFactory {</div>
    <div>+</div>
    <div>+<span style="WHITE-SPACE:pre-wrap"> </span>static final AtomicInteger 
    poolNumber = new AtomicInteger(1);</div>
    <div>+</div>
    <div>+    final AtomicInteger threadNumber = new 
    AtomicInteger(1);</div>
    <div>+    final String namePrefix;</div>
    <div>+    final boolean isDaemon;</div>
    <div>+</div>
    <div>+    public NamedForkJoinThreadFactory() {</div>
    <div>+        this("pool");</div>
    <div>+    }</div>
    <div>+    public NamedForkJoinThreadFactory(String name) {</div>
    <div>+        this(name, false);</div>
    <div>+    }</div>
    <div>+    public NamedForkJoinThreadFactory(String preffix, 
    boolean daemon) {</div>
    <div>+        namePrefix = preffix + "-" + 
    poolNumber.getAndIncrement() + "-thread-";</div>
    <div>+        isDaemon = daemon;</div>
    <div>+    }</div>
    <div>+</div>
    <div>+    @Override</div>
    <div>+    public ForkJoinWorkerThread newThread(ForkJoinPool pool) 
    {</div>
    <div>+        ForkJoinWorkerThread t =</div>
    <div>+           
     ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);</div>
    <div>+        t.setName(namePrefix + 
    threadNumber.getAndIncrement());</div>
    <div>+        t.setDaemon(isDaemon);</div>
    <div>+        return t;</div>
    <div>+    }</div>
    <div>+</div>
    <div>+}</div>
    <div>+</div>
    <div>Index: 
    nfs-rpc-common/src/main/java/code/google/nfs/rpc/benchmark/AbstractBenchmarkServer.java</div>
    <div>===================================================================</div>
    <div>--- 
    nfs-rpc-common/src/main/java/code/google/nfs/rpc/benchmark/AbstractBenchmarkServer.java<span style="WHITE-SPACE:pre-wrap"> </span>(revision 120)</div>
    <div>+++ 
    nfs-rpc-common/src/main/java/code/google/nfs/rpc/benchmark/AbstractBenchmarkServer.java<span style="WHITE-SPACE:pre-wrap"> </span>(working copy)</div>
    <div>@@ -8,12 +8,10 @@</div>
    <div> import java.text.SimpleDateFormat;</div>
    <div> import java.util.Date;</div>
    <div> import java.util.concurrent.ExecutorService;</div>
    <div>-import java.util.concurrent.SynchronousQueue;</div>
    <div>-import java.util.concurrent.ThreadFactory;</div>
    <div>-import java.util.concurrent.ThreadPoolExecutor;</div>
    <div>-import java.util.concurrent.TimeUnit;</div>
    <div><font color="#0000ff" face="Arial"></font> </div>
    <div>-import code.google.nfs.rpc.NamedThreadFactory;</div>
    <div>+import code.google.nfs.rpc.NamedForkJoinThreadFactory;</div>
    <div>+import code.google.nfs.rpc.jsr166y.ForkJoinPool;</div>
    <div>+import 
    code.google.nfs.rpc.jsr166y.ForkJoinPool.ForkJoinWorkerThreadFactory;</div>
    <div> import code.google.nfs.rpc.protocol.PBDecoder;</div>
    <div> import code.google.nfs.rpc.protocol.RPCProtocol;</div>
    <div> import 
code.google.nfs.rpc.protocol.SimpleProcessorProtocol;</div>
    <div>@@ -66,9 +64,13 @@</div>
    <div> <span style="WHITE-SPACE:pre-wrap"> </span>});</div>
    <div> <span style="WHITE-SPACE:pre-wrap"> 
    </span>server.registerProcessor(RPCProtocol.TYPE, "testservice", new 
    BenchmarkTestServiceImpl(responseSize));</div>
    <div> <span style="WHITE-SPACE:pre-wrap"> 
    </span>server.registerProcessor(RPCProtocol.TYPE, "testservicepb", new 
    PBBenchmarkTestServiceImpl(responseSize));</div>
    <div>-<span style="WHITE-SPACE:pre-wrap"> </span>ThreadFactory tf = new 
    NamedThreadFactory("BUSINESSTHREADPOOL");</div>
    <div>-<span style="WHITE-SPACE:pre-wrap"> </span>ExecutorService threadPool 
    = new ThreadPoolExecutor(20, maxThreads,</div>
    <div>-<span style="WHITE-SPACE:pre-wrap"> </span>300, TimeUnit.SECONDS, new 
    SynchronousQueue<Runnable>(), tf);</div>
    <div>+<span style="WHITE-SPACE:pre-wrap"> 
    </span>ForkJoinWorkerThreadFactory tf = new 
    NamedForkJoinThreadFactory("BUSINESSTHREADPOOL");</div>
    <div>+<span style="WHITE-SPACE:pre-wrap"> </span>ExecutorService threadPool 
    = new ForkJoinPool(maxThreads, tf, </div>
    <div>+<span style="WHITE-SPACE:pre-wrap"> </span>       
      new Thread.UncaughtExceptionHandler() {</div>
    <div>+<span style="WHITE-SPACE:pre-wrap"> </span>       
          public void uncaughtException(Thread t, Throwable 
    e){</div>
    <div>+<span style="WHITE-SPACE:pre-wrap"> </span>       
            // do nothing;</div>
    <div>+<span style="WHITE-SPACE:pre-wrap"> </span>       
          };</div>
    <div>+<span style="WHITE-SPACE:pre-wrap"> </span>       
      }, true);</div>
    <div> <span style="WHITE-SPACE:pre-wrap"> 
    </span>server.start(listenPort, threadPool);</div>
    <div> <span style="WHITE-SPACE:pre-wrap"> </span>}</div></div>
    <div><font color="#0000ff" face="Arial"></font><br></div>
    <div><font color="#0000ff" face="Arial"></font><br></div>
    <div>I did a benchmark (see <a style="COLOR:rgb(17,85,204)" href="http://code.google.com/p/nfs-rpc/wiki/HowToRunBenchmark" target="_blank">http://code.google.com/p/nfs-rpc/wiki/HowToRunBenchmark</a> ) 
    with the hope of significant TPS improvments, but got a bad result cross to 
    the purpose.  ForkJoinPool (avg response time 12 ms) seems lead to 
    a worse latency than it did with traditional ExecutorService (avg response 
    time 3ms).</div>
    <div><font color="#0000ff" face="Arial"></font><br></div>
    <div>With ForkJoinPool:</div>
    <div><font color="#0000ff" face="Arial"></font><br></div>
    <div>
    <div>----------Benchmark Statistics--------------</div>
    <div> Concurrents: 500</div>
    <div> CodecType: 3</div>
    <div> ClientNums: 1</div>
    <div> RequestSize: 100 bytes</div>
    <div> Runtime: 120 seconds</div>
    <div> Benchmark Time: 81</div>
    <div> Requests: 3740311 Success: 99% (3739274) Error: 0% (1037)</div>
    <div> Avg TPS: 41374 Max TPS: 62881 Min TPS: 3333</div>
    <div> Avg RT: 12ms</div>
    <div> RT <= 0: 0% <a style="COLOR:rgb(17,85,204)" href="tel:1829%2F3740311" value="+18293740311" target="_blank">1829/3740311</a></div>
    <div> RT (0,1]: 1% 59989/3740311</div>
    <div> RT (1,5]: 47% 1778386/3740311</div>
    <div> RT (5,10]: 17% 655377/3740311</div>
    <div> RT (10,50]: 32% 1204205/3740311</div>
    <div> RT (50,100]: 0% 31479/3740311</div>
    <div> RT (100,500]: 0% 546/3740311</div>
    <div> RT (500,1000]: 0% 7463/3740311</div>
    <div> RT > 1000: 0% 1037/3740311</div></div>
    <div><br></div>
    <div><br></div>
    <div>With traditional thread pool:</div>
    <div>
    <div>----------Benchmark Statistics--------------</div>
    <div> Concurrents: 500</div>
    <div> CodecType: 3</div>
    <div> ClientNums: 1</div>
    <div> RequestSize: 100 bytes</div>
    <div> Runtime: 120 seconds</div>
    <div> Benchmark Time: 81</div>
    <div> Requests: 12957281 Success: 100% (12957281) Error: 0% (0)</div>
    <div> Avg TPS: 144261 Max TPS: 183390 Min TPS: 81526</div>
    <div> Avg RT: 3ms</div>
    <div> RT <= 0: 0% 3997/12957281</div>
    <div> RT (0,1]: 4% 592905/12957281</div>
    <div> RT (1,5]: 95% 12312500/12957281</div>
    <div> RT (5,10]: 0% 19280/12957281</div>
    <div> RT (10,50]: 0% 92/12957281</div>
    <div> RT (50,100]: 0% 507/12957281</div>
    <div> RT (100,500]: 0% 26500/12957281</div>
    <div> RT (500,1000]: 0% 1500/12957281</div>
    <div> RT > 1000: 0% 0/12957281</div></div>
    <div><br></div>
    <div>
    <div><br></div>
    <div>I ran this benchmark on two 16 cores Westmere machines ( Xeon E5620 8 
    core HT) with the same configuration below of the two tests. </div>
    <div><br></div>
    <div>1. JDK version: Oracle 1.7.0_03 (hotspot)</div>
    <div><br></div>
    <div>2. client side JVM options:</div>
    <div>-Xms4g -Xmx4g -Xmn1g -XX:+PrintGCDetails -XX:+PrintGCDateStamps 
    -Xloggc:gc.log -Dwrite.statistics=true -XX:+UseParallelGC 
    -XX:+UseCondCardMark -XX:-UseBiasedLocking -Djava.ext.dirs=/home/min/nfs-rpc 
    code.google.nfs.rpc.netty.benchmark.NettySimpleBenchmarkClient 10.232.98.96 
    8888 500 1000 3 100 120 1</div>
    <div><br></div>
    <div>3. server side JVM options:</div>
    <div>-Xms2g -Xmx2g -Xmn500m -XX:+UseParallelGC -XX:+PrintGCDetails 
    -XX:+PrintGCDateStamps -Xloggc:gc.log -XX:+UseCondCardMark 
    -XX:-UseBiasedLocking -Djava.ext.dirs=/home/min/nfs-rpc 
    code.google.nfs.rpc.netty.benchmark.NettyBenchmarkServer <a style="COLOR:rgb(17,85,204)" href="tel:8888%20100%20100" value="+18888100100" target="_blank">8888 100 100</a></div>
    <div><br></div>
    <div>Low context switches, about 8000 per second, is also observed with 
    ForkJoinPool against to which with the old threadpool it's about 
    150000.</div>
    <div>Benchmarks under Oracle JDK 1.6 is also did by me with similar 
    results.</div>
    <div><br></div>
    <div>Is there anyone kindly explain the reason why leading to those describe 
    above for me ?</div>
    <div><br></div>
    <div>Thanks,</div>
    <div>Min</div></div>
    <div><br></div>-- <br>My research interests are distributed systems, 
    parallel computing and bytecode based virtual machine.<br><br>My 
    profile:<br><a href="http://www.linkedin.com/in/coderplay" target="_blank">http://www.linkedin.com/in/coderplay</a><br>My 
    blog:<br><a href="http://coderplay.javaeye.com" target="_blank">http://coderplay.javaeye.com</a><br></blockquote></blockquote></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>My research interests are distributed systems, parallel computing and bytecode based virtual machine.<br><br>My profile:<br><a href="http://www.linkedin.com/in/coderplay">http://www.linkedin.com/in/coderplay</a><br>
My blog:<br><a href="http://coderplay.javaeye.com">http://coderplay.javaeye.com</a><br>