Jim,<br><br>thanks for having some interest for my efforts ! <br>As I got almost no feedback, I felt quite disappointed and was thinking that improving pisces was not important ...<br><br>Here are ductus results and comparison (open office format):<br>
<a href="http://jmmc.fr/~bourgesl/share/java2d-pisces/ductus_det.log">http://jmmc.fr/~bourgesl/share/java2d-pisces/ductus_det.log</a><br><a href="http://jmmc.fr/~bourgesl/share/java2d-pisces/compareRef_Patch.ods">http://jmmc.fr/~bourgesl/share/java2d-pisces/compareRef_Patch.ods</a><br>
<br>



        
        
        
        
        <style>body, div, table, thead, tbody, tfoot, tr, th, td, p { font-family: "Liberation Sans"; font-size: x-small; }</style>
        

<table border="0" cellspacing="0" cols="10" frame="VOID" rules="NONE">
        <colgroup><col width="165"><col width="84"><col width="49"><col width="94"><col width="94"><col width="94"><col width="94"><col width="131"><col width="94"><col width="94"></colgroup>
        <tbody>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" width="165" align="LEFT">test</td>
                        <td style="border:1px solid rgb(0,0,0)" width="84" align="LEFT">threads</td>
                        <td style="border:1px solid rgb(0,0,0)" width="49" align="LEFT">ops</td>
                        <td style="border:1px solid rgb(0,0,0)" width="94" align="LEFT">Tavg</td>
                        <td style="border:1px solid rgb(0,0,0)" width="94" align="LEFT">Tmed</td>
                        <td style="border:1px solid rgb(0,0,0)" width="94" align="LEFT">stdDev</td>
                        <td style="border:1px solid rgb(0,0,0)" width="94" align="LEFT">rms</td>
                        <td style="border:1px solid rgb(0,0,0)" width="131" align="LEFT"><b>Med+Stddev</b></td>
                        <td style="border:1px solid rgb(0,0,0)" width="94" align="LEFT">min</td>
                        <td style="border:1px solid rgb(0,0,0)" width="94" align="LEFT">max</td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="LEFT">boulder_17</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">1</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">20</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">73,92%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">69,34%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">27,98%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">69,34%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>69,14%</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">69,81%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">146,89%</td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="LEFT">boulder_17</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">2</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">20</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">110,86%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">110,48%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">613,80%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">112,01%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>125,43%</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">94,71%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">136,35%</td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="LEFT">boulder_17</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">4</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">20</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">135,28%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">135,86%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">226,61%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">136,46%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>141,85%</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">125,14%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">111,32%</td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="LEFT">shp_alllayers_47</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">1</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">20</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">82,25%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">82,49%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">47,50%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">82,48%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>82,30%</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">82,64%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">78,08%</td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="LEFT">shp_alllayers_47</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">2</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">20</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">115,87%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">115,67%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">315,45%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">115,85%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>119,89%</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">109,33%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">128,71%</td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="LEFT">shp_alllayers_47</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">4</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">20</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">218,59%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">218,76%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">169,38%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">218,65%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>216,45%</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">220,17%</td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT">206,17%</td>
                </tr>
        </tbody>
</table>
<br>Ductus vs Patch<br>



        
        
        
        
        <style>body, div, table, thead, tbody, tfoot, tr, th, td, p { font-family: "Liberation Sans"; font-size: x-small; }</style>
        

<table border="0" cellspacing="0" cols="2" frame="VOID" rules="NONE">
        <colgroup><col width="84"><col width="94"></colgroup>
        <tbody>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" width="84" align="RIGHT"><b>1</b></td>
                        <td style="border:1px solid rgb(0,0,0)" width="94" align="RIGHT"><b>80,74%</b></td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="RIGHT"><b>2</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>120,69%</b></td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="RIGHT"><b>4</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>205,92%</b></td>
                </tr>
        </tbody>
</table>
<br>Reminder: Ref vs Patch<br>



        
        
        
        
        <style>body, div, table, thead, tbody, tfoot, tr, th, td, p { font-family: "Liberation Sans"; font-size: x-small; }</style>
        

<table border="0" cellspacing="0" cols="2" frame="VOID" rules="NONE">
        <colgroup><col width="84"><col width="94"></colgroup>
        <tbody>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" width="84" align="RIGHT"><b>1</b></td>
                        <td style="border:1px solid rgb(0,0,0)" width="94" align="RIGHT"><b>237,71%</b></td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="RIGHT"><b>2</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>271,68%</b></td>
                </tr>
                <tr>
                        <td style="border:1px solid rgb(0,0,0)" height="24" align="RIGHT"><b>4</b></td>
                        <td style="border:1px solid rgb(0,0,0)" align="RIGHT"><b>286,15%</b></td>
                </tr>
        </tbody>
</table>
<br><br>Note: I only have 2 cores + HT on my laptop and do not test with more threads (64 like andrea).<br><br><div class="gmail_quote">2013/4/16 Jim Graham <span dir="ltr"><<a href="mailto:james.graham@oracle.com" target="_blank">james.graham@oracle.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">If I'm reading this correctly, your patch is faster even for a single thread?  That's great news.<br>
</blockquote><div><br>Not yet, but ductus is now only 20% faster than my patch and 20% and 2x slower with 2 and 4 threads : <br>I still hope to beat it applying few more optimizations:<br>- Renderer.ScanLine iterator / Renderer.endRendering can be improved<br>
- avoid few more array zero fill (reset) if possible<br>- adding statistics to better set initial array sizes ...<br>- use SunGraphics2D to hold an hard reference (temporarly) on RendererContext (to avoid many ThreadLocal.get())<br>
- cache eviction (WeakReference or SoftReference) ?<br><br>Why not use divide and conquer (thread pool) to boost single thread rendering if the machine has more cpu cores ?<br>It would be helpful if the AATileGenerator has access to SunGraphics2D to get rendering hints or share variables (cache ...)<br>
<br>For the moment, I did not modify the algorithms itself but I will do it to enhance clipping (dasher segments / stroker) ...<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

One of the problems we've had with replacing Ductus is that it has been faster in a single thread situation than the open source versions we've created.  One of its drawbacks is that it had been designed to take advantage of some AA-accelerating hardware that never came to be.  With the accelerator it would have been insanely fast, but hardware went in a different direction.  The problem was that this early design goal caused the entire library to be built around an abstraction layer that allowed for a single "tile producer" internally (because there would be only one - insanely fast - hardware chip available) and the software version of the abstraction layer thus had a lot of native "static" data structures (there's only one of me, right?) that prevented MT access.  It was probably solvable, but I'd be happier if someone could come up with a faster rasterizer, imagining that there must have been some sort of advancements in the nearly 2 decades since the original was written.<br>

<br>
If I'm misinterpreting and single thread is still slower than Ductus (or if it is still slower on some other platforms), then <frowny face>.<br></blockquote><div><br>Not yet: slower than ductus by 20% but faster than current pisces by 2 times !<br>
<br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Also, this is with the Java version, right?  </blockquote><div><br>Yes, my patch is pure java given as webrev:<br>        <a href="http://jmmc.fr/%7Ebourgesl/share/java2d-pisces/webrev-1/" target="_blank">http://jmmc.fr/~bourgesl/share/java2d-pisces/webrev-1/</a><br>
 </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">We got a decent 2x speedup in FX by porting the version of Open Pisces that you started with to C code (all except on Linux where we couldn't find the right gcc options to make it faster than Hotspot).  So, we have yet to investigate a native version in the JDK which might provide even more gains...<br>
</blockquote><div><br>Personally I prefer working on java code as hotspot can perform so much optimizations for free and no pointers to deal with and more important: concurrent primitives (thread local, collections) !<br>
<br>Laurent<br><br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im"><br>
<br>
On 4/15/13 3:01 AM, Laurent Bourgčs wrote:<br>
</div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">
Jim, Andrea,<br>
<br>
I updated MapBench to provide test statistics (avg, median, stddev, rms,<br>
med + stddev, min, max) and CSV output (tab separator):<br>
<a href="http://jmmc.fr/%7Ebourgesl/share/java2d-pisces/MapBench/" target="_blank">http://jmmc.fr/~bourgesl/<u></u>share/java2d-pisces/MapBench/</a><br></div>
<<a href="http://jmmc.fr/%7Ebourgesl/share/java2d-pisces/MapBench/" target="_blank">http://jmmc.fr/%7Ebourgesl/<u></u>share/java2d-pisces/MapBench/</a>><div><div class="h5"><br>
<br>
<br>
Here are the results (OpenJDK8 Ref vs Patched):<br>
<a href="http://jmmc.fr/%7Ebourgesl/share/java2d-pisces/ref_det.log" target="_blank">http://jmmc.fr/~bourgesl/<u></u>share/java2d-pisces/ref_det.<u></u>log</a><br>
<a href="http://jmmc.fr/%7Ebourgesl/share/java2d-pisces/patch_det.log" target="_blank">http://jmmc.fr/~bourgesl/<u></u>share/java2d-pisces/patch_det.<u></u>log</a><br>
<br>
test    threads         ops     Tavg    Tmed    stdDev  rms     Med+Stddev      min     max<br>
boulder_17      1       20      180,22%         181,08%         1186,01%        181,17%         185,92%<br>
176,35%         170,36%<br>
boulder_17      2       20      183,15%         183,80%         162,68%         183,78%         183,17%<br>
174,01%         169,89%<br>
boulder_17      4       20      216,62%         218,03%         349,31%         218,87%         226,68%<br>
172,15%         167,54%<br>
shp_alllayers_47        1       20      243,90%         244,86%         537,92%         244,87%         246,39%<br>
240,64%         231,00%<br>
shp_alllayers_47        2       20      286,42%         287,07%         294,87%         287,07%         287,23%<br>
277,19%         272,23%<br>
shp_alllayers_47        4       20      303,08%         302,15%         168,19%         301,90%         295,90%<br>
462,70%         282,41%<br>
<br>
<br>
<br>
PATCH:<br>
test    threads         ops     Tavg    Tmed    stdDev  rms     Med+Stddev      min     max<br>
boulder_17      1       20      110,196         109,244         0,529   109,246         109,773         108,197<br>
129,327<br>
boulder_17      2       40      127,916         127,363         3,899   127,423         131,262         125,262<br>
151,561<br>
boulder_17      4       80      213,085         212,268         14,988  212,796         227,256         155,512<br>
334,407<br>
shp_alllayers_47        1       20      1139,452        1134,858        5,971   1134,873        1140,829<br>
1125,859        1235,746<br>
shp_alllayers_47        2       40      1306,889        1304,598        28,157  1304,902<br>
1332,755        1280,49         1420,351<br>
shp_alllayers_47        4       80      2296,487        2303,81         112,816         2306,57         2416,626<br>
1390,31         2631,455<br>
<br>
<br>
<br>
REF:<br>
test    threads         ops     Tavg    Tmed    stdDev  rms     Med+Stddev      min     max<br>
boulder_17      1       20      198,591         197,816         6,274   197,916         204,091         190,805<br>
220,319<br>
boulder_17      2       40      234,272         234,09  6,343   234,176         240,433         217,967<br>
257,485<br>
boulder_17      4       80      461,579         462,8   52,354  465,751         515,153         267,712<br>
560,254<br>
shp_alllayers_47        1       20      2779,133        2778,823        32,119  2779,009<br>
2810,943        2709,285        2854,557<br>
shp_alllayers_47        2       40      3743,255        3745,111        83,027  3746,031<br>
3828,138        3549,364        3866,612<br>
shp_alllayers_47        4       80      6960,23         6960,948        189,75  6963,533        7150,698<br>
6432,945        7431,541<br>
<br>
<br>
Linux 64 server vm<br>
JVM: -Xms128m -Xmx128m (low mem)<br>
<br>
Laurent<br>
<br>
2013/4/14 Andrea Aime <<a href="mailto:andrea.aime@geo-solutions.it" target="_blank">andrea.aime@geo-solutions.it</a><br></div></div>
<mailto:<a href="mailto:andrea.aime@geo-solutions.it" target="_blank">andrea.aime@geo-<u></u>solutions.it</a>>><br>
<br>
    On Tue, Apr 9, 2013 at 3:02 PM, Laurent Bourgčs<div class="im"><br>
    <<a href="mailto:bourges.laurent@gmail.com" target="_blank">bourges.laurent@gmail.com</a> <mailto:<a href="mailto:bourges.laurent@gmail.com" target="_blank">bourges.laurent@gmail.<u></u>com</a>>> wrote:<br>

<br>
        Dear Java2D members,<br>
<br>
        Could someone review the following webrev concerning Java2D<br>
        Pisces to enhance its performance and reduce its memory<br>
        footprint (RendererContext stored in thread local or concurrent<br>
        queue):<br>
        <a href="http://jmmc.fr/%7Ebourgesl/share/java2d-pisces/webrev-1/" target="_blank">http://jmmc.fr/~bourgesl/<u></u>share/java2d-pisces/webrev-1/</a><br></div>
        <<a href="http://jmmc.fr/%7Ebourgesl/share/java2d-pisces/webrev-1/" target="_blank">http://jmmc.fr/%7Ebourgesl/<u></u>share/java2d-pisces/webrev-1/</a>><div><div class="h5"><br>
<br>
        FYI I fixed file headers in this patch and signed my OCA 3 weeks<br>
        ago.<br>
<br>
        Remaining work:<br>
        - cleanup (comments ...)<br>
        - statistics to perform auto-tuning<br>
        - cache / memory cleanup (SoftReference ?): use hints or System<br>
        properties to adapt it to use cases<br>
        - another problem: fix clipping performance in Dasher / Stroker<br>
        for segments out of bounds<br>
<br>
        Could somebody support me ? ie help me working on these tasks or<br>
        just to discuss on Pisces algorithm / implementation ?<br>
<br>
<br>
    Hi,<br>
    I would like to express my support for this patch.<br>
    Given that micro-benchmarks have already been run, I took the patch<br>
    for a spin in a large, real world benchmark instead,<br>
    the OSGeo WMS Shootout 2010 benchmark, for which you can see the<br>
    results here:<br>
    <a href="http://www.slideshare.net/gatewaygeomatics.com/wms-performance-shootout-2010" target="_blank">http://www.slideshare.net/<u></u>gatewaygeomatics.com/wms-<u></u>performance-shootout-2010</a><br>
<br>
    The presentation is long, but suffice it to say all Java based<br>
    implementations took quite the beating due to the<br>
    poor scalability of Ductus with antialiased rendering of vector data<br>
    (for an executive summary just look<br>
    at slide 27 and slide 66, where GeoServer, Oracle MapViewer and<br>
    Constellation SDI were the<br>
    Java based ones)<br>
<br>
    I took the same tests and run them again on my machine (different<br>
    hardware than the tests, don't try to compare<br>
    the absolute values), using Oracle JDK 1.7.0_17, OpenJDK 8 (a<br>
    checkout a couple of weeks old) and the<br>
    same, but with Laurent's patches applied.<br>
    Here are the results, throughput (in maps generated per second) with<br>
    the load generator (JMeter) going<br>
    up from one client to 64 concurrent clients:<br>
<br></div></div>
    *Threads*   *JDK 1.7.0_17*  *OpenJDK 8, vanilla*    *OpenJDK 8 + pisces<br>
    renderer improvements*      *Pisces renderer performance gain, %*<div><div class="h5"><br>
    1   13,97   12,43   13,03   4,75%<br>
    2   22,08   20,60   20,77   0,81%<br>
    4   34,36   33,15   33,36   0,62%<br>
    8   39,39   40,51   41,71   2,96%<br>
    16  40,61   44,57   46,98   5,39%<br>
    32  41,41   44,73   48,16   7,66%<br>
    64  37,09   42,19   45,28   7,32%<br>
<br>
<br>
    Well, first of all, congratulations to the JDK developers, don't<br>
    know what changed in JDK 8, but<br>
    GeoServer seems to like it quite a bit :-).<br>
    That said, Laurent's patch also gives a visible boost, especially<br>
    when several concurrent clients are<br>
    asking for the maps.<br>
<br>
    Mind, as I said, this is no micro-benchmark, it is a real<br>
    application loading doing a lot of I/O<br>
    (from the operating system file cache), other processing before the<br>
    data reaches the rendering<br>
    pipeline, and then has to PNG encode the output BufferedImage (PNG<br>
    encoding being rather<br>
    expensive), so getting this speedup from just a change in the<br>
    rendering pipeline is significant.<br>
<br>
    Long story short... personally I'd be very happy if this patch was<br>
    going to be integrated in Java 8 :-)<br>
<br>
    Cheers<br>
    Andrea<br>
<br>
    --<br>
    ==<br>
    GeoServer training in Milan, 6th & 7th June 2013!  Visit<br>
    <a href="http://geoserver.geo-solutions.it" target="_blank">http://geoserver.geo-<u></u>solutions.it</a><br></div></div>
    <<a href="http://geoserver.geo-solutions.it/" target="_blank">http://geoserver.geo-<u></u>solutions.it/</a>> for more information.<div class="im"><br>
    ==<br>
<br>
    Ing. Andrea Aime<br>
    @geowolf<br>
    Technical Lead<br>
<br>
    GeoSolutions S.A.S.<br>
    Via Poggio alle Viti 1187<br>
    55054  Massarosa (LU)<br>
    Italy<br>
    phone: +39 0584 962313<br>
    fax: +39 0584 1660272<br>
    mob: +39  339 8844549<br>
<br>
    <a href="http://www.geo-solutions.it" target="_blank">http://www.geo-solutions.it</a><br>
    <a href="http://twitter.com/geosolutions_it" target="_blank">http://twitter.com/<u></u>geosolutions_it</a><br>
<br>
    ------------------------------<u></u>-------------------------<br>
<br>
<br>
</div></blockquote>
</blockquote></div><br>