quad-core processor limited utilization. performance issue

View: New views
16 Messages — Rating Filter:   Alert me  

quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I'm using JAI for the WikiSky project. The code is running on quad core systems. I noticed that JAI functions utilize only two cores at a time. In other words, no matter how many threads are running, the quad-core CPU utilization is balancing at 50%.
Is there any settings in JAI to use all available cores in parallel?

JAI operations I'm using are:
- jpeg compression/decompression
- scaling down images
- table warping for non-linear projection transformations
- cutting tiles
and so on

I'm manipulating with terrabytes of images and I really need to utilize all available resources.

Thanks,
Sergei
[Message sent by forum member 'klink' (klink)]

http://forums.java.net/jive/thread.jspa?messageID=269873

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by Bob Deen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sounds like a cool usage!  Do you have a URL?

> I'm using JAI for the WikiSky project. The code is running on quad  
> core systems. I noticed that JAI functions utilize only two cores  
> at a time. In other words, no matter how many threads are running,  
> the quad-core CPU utilization is balancing at 50%.
> Is there any settings in JAI to use all available cores in parallel?

The TileScheduler has setParallelism() and setPrefetchParallelism(),  
the default for which (interestingly enough) is 2.

Now, you may have to schedule tiles rather than simply requesting  
them to get the parallelism to work, but it definitely does.  That's  
how JadeDisplay works... it schedules tiles for background  
computation, then renders them as they become available.

Hope that helps...

-Bob


---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Bob,

Looks like exactly what I need. I'll play with those parameters tonight. Thanks.
The URL of the project is http://www.wikisky.org

I have few more questions regarding tiled and multiple scale levels processing optimization. I'll post it bit later.

Sergei
[Message sent by forum member 'klink' (klink)]

http://forums.java.net/jive/thread.jspa?messageID=269969

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I tried to use setParallelism() with different values from 0 to 4. I didn't notice any difference.
Most of the threads sitting at lock somewhere at Jpeg encoding/decoding codec. Here's what I see when running 7 threads:


Running threads
http-80-1 [BLOCKED; waiting to lock java.lang.Object@8aca5e]
com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:106)
com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.FileLoadRIF.create(FileLoadRIF.java:144)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)


http-80-2 [BLOCKED; waiting to lock java.lang.Object@8aca5e]
com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:106)
com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.FileLoadRIF.create(FileLoadRIF.java:144)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)



http-80-3 [RUNNABLE]
sun.awt.image.ByteInterleavedRaster.setPixels(unknown source)
java.awt.image.WritableRaster.setRect(unknown source)
sun.awt.image.SunWritableRaster.setRect(unknown source)
sun.awt.image.ByteInterleavedRaster.setRect(unknown source)
java.awt.image.WritableRaster.setRect(unknown source)
sun.awt.image.SunWritableRaster.setRect(unknown source)
com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:148)
com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.FileLoadRIF.create(FileLoadRIF.java:144)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:799)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getSampleModel(RenderedOp.java:2233)
com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:133)



http-80-4 [BLOCKED; waiting to lock java.lang.Object@8aca5e]
com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:106)
com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.FileLoadRIF.create(FileLoadRIF.java:144)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:799)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getSampleModel(RenderedOp.java:2233)
com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:133)



http-80-5 [RUNNABLE]
sun.awt.image.codec.JPEGImageEncoderImpl.writeJPEGStream(native method)
sun.awt.image.codec.JPEGImageEncoderImpl.encode(unknown source)
sun.awt.image.codec.JPEGImageEncoderImpl.encode(unknown source)
com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:277)



http-80-6 [BLOCKED; waiting to lock java.lang.Object@8aca5e]
com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:106)
com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.FileLoadRIF.create(FileLoadRIF.java:144)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:799)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getSampleModel(RenderedOp.java:2233)
com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:133)



http-80-7 [RUNNABLE]
sun.awt.image.codec.JPEGImageDecoderImpl.readJPEGStream(native method)
sun.awt.image.codec.JPEGImageDecoderImpl.decodeAsBufferedImage(unknown source)
com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:110)
com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
com.sun.media.jai.opimage.FileLoadRIF.create(FileLoadRIF.java:144)
sun.reflect.GeneratedMethodAccessor33.invoke(unknown source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(unknown source)
java.lang.reflect.Method.invoke(unknown source)
javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getRendering(RenderedOp.java:888)
javax.media.jai.RenderedOp.createInstance(RenderedOp.java:799)
javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
javax.media.jai.RenderedOp.getSampleModel(RenderedOp.java:2233)
com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:133)
[Message sent by forum member 'klink' (klink)]

http://forums.java.net/jive/thread.jspa?messageID=270053

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by Bob Deen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Apr 18, 2008, at 10:01 PM, jai-interest@... wrote:
> I tried to use setParallelism() with different values from 0 to 4.  
> I didn't notice any difference.
> Most of the threads sitting at lock somewhere at Jpeg encoding/
> decoding codec. Here's what I see when running 7 threads:

How are you asking for data to be computed?

Also, it looks like they're all blocked trying to read the JPEG  
image.  It's quite possible (likely, in fact) that the file I/O  
readers in general do not support multithreading.  Hopefully they  
will if reading different images (!).

I don't know what your operator chain looks like but you might try  
putting a format operator after the read to re-tile the image and  
decouple everything else from the reader.  If that format has  
sufficient cache space, all subsequent operations should come from  
memory and not touch the file again.

-Bob


---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I looked at JpegImageDecoder.java
What I found is that the class JpegImageDecoder.JPEGImage has static lock object (LOCK) that prevents simultaneous jpeg decoding operations, no matter if it's same file of different files:

class JPEGImage extends SimpleRenderedImage {

    /**
     * Mutex for the entire class to circumvent thread unsafety of
     * com.sun.image.codec.jpeg.JPEGImageDecoder implementation.
     */
    private static final Object LOCK = new Object();

    private Raster theTile = null;

    /**
     * Construct a JPEGmage.
     *
     * @param stream The JPEG InputStream.
     * @param param The decoding parameters.
     */
    public JPEGImage(InputStream stream, ImageDecodeParam param) {
        // If the supplied InputStream supports mark/reset wrap it so
        // it does not.
        if(stream.markSupported()) {
            stream = new NoMarkStream(stream);
        }

        // Lock the entire class to work around lack of thread safety
        // in com.sun.image.codec.jpeg.JPEGImageDecoder implementation.
        BufferedImage image = null;
        synchronized(LOCK) {
            com.sun.image.codec.jpeg.JPEGImageDecoder decoder =
                com.sun.image.codec.jpeg.JPEGCodec.createJPEGDecoder(stream);
            try {
                // decodeAsBufferedImage performs default color conversions
                image = decoder.decodeAsBufferedImage();
            } catch (ImageFormatException e) {
                String message = JaiI18N.getString("JPEGImageDecoder1");
                sendExceptionToListener(message, (Exception)e);
//                throw new RuntimeException(JaiI18N.getString("JPEGImageDecoder1"));
            } catch (IOException e) {
                String message = JaiI18N.getString("JPEGImageDecoder1");
                sendExceptionToListener(message, (Exception)e);
//                throw new RuntimeException(JaiI18N.getString("JPEGImageDecoder2"));
            }
        }


Looks like there's no way around in this codec.
The question is is there other jpeg codecs that are thread safe and can be used in JAI?
[Message sent by forum member 'wikisky' (wikisky)]

http://forums.java.net/jive/thread.jspa?messageID=270237

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by Bob Deen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ohhhh... that's nasty!!!

There are several other jpeg implementations floating about that you  
might look into.  It looks like you're using the older JAI codec  
mechanism.  There are at least two more jpeg's for the newer Image I/
O mechanism (imageread instead of fileload operator).  I have no idea  
if they do the same (really quite horrid) locking things but it's  
worth looking into.  You have to download the imageio tools package  
(same place as JAI) though.


-Bob


On Apr 19, 2008, at 7:31 PM, jai-interest@... wrote:

> I looked at JpegImageDecoder.java
> What I found is that the class JpegImageDecoder.JPEGImage has  
> static lock object (LOCK) that prevents simultaneous jpeg decoding  
> operations, no matter if it's same file of different files:
>
> class JPEGImage extends SimpleRenderedImage {
>
>     /**
>      * Mutex for the entire class to circumvent thread unsafety of
>      * com.sun.image.codec.jpeg.JPEGImageDecoder implementation.
>      */
>     private static final Object LOCK = new Object();
>
>     private Raster theTile = null;
>
>     /**
>      * Construct a JPEGmage.
>      *
>      * @param stream The JPEG InputStream.
>      * @param param The decoding parameters.
>      */
>     public JPEGImage(InputStream stream, ImageDecodeParam param) {
>         // If the supplied InputStream supports mark/reset wrap it so
>         // it does not.
>         if(stream.markSupported()) {
>             stream = new NoMarkStream(stream);
>         }
>
>         // Lock the entire class to work around lack of thread safety
>         // in com.sun.image.codec.jpeg.JPEGImageDecoder  
> implementation.
>         BufferedImage image = null;
>         synchronized(LOCK) {
>             com.sun.image.codec.jpeg.JPEGImageDecoder decoder =
>                 com.sun.image.codec.jpeg.JPEGCodec.createJPEGDecoder
> (stream);
>             try {
>                 // decodeAsBufferedImage performs default color  
> conversions
>                 image = decoder.decodeAsBufferedImage();
>             } catch (ImageFormatException e) {
>                 String message = JaiI18N.getString
> ("JPEGImageDecoder1");
>                 sendExceptionToListener(message, (Exception)e);
> //                throw new RuntimeException(JaiI18N.getString
> ("JPEGImageDecoder1"));
>             } catch (IOException e) {
>                 String message = JaiI18N.getString
> ("JPEGImageDecoder1");
>                 sendExceptionToListener(message, (Exception)e);
> //                throw new RuntimeException(JaiI18N.getString
> ("JPEGImageDecoder2"));
>             }
>         }
>
>
> Looks like there's no way around in this codec.
> The question is is there other jpeg codecs that are thread safe and  
> can be used in JAI?
> [Message sent by forum member 'wikisky' (wikisky)]
>
> http://forums.java.net/jive/thread.jspa?messageID=270237
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@...
> For additional commands, e-mail: interest-help@...
>


---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I didn't know that imageread is newer than fileload. I'll try it out.Hope it'll better handle multithreading.

Thanks,
Sergei
[Message sent by forum member 'wikisky' (wikisky)]

http://forums.java.net/jive/thread.jspa?messageID=270299

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by Simone.Giannecchini :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ciao,
I can report what is the result of my investigations on this matter.
Unfortunately ImageReader implementations are not required to be
thread safe. This affect the JAI ImageIO ImageRead operation since
multiple tiles "could" be loaded in mutlithreading
but in reality there is a nick synchornization that does serialize all
the access to the underlying ImageReader used to load single tiles
(well, moreover I am not sure that any of the availabole
implementations of JPEG ImageReaders does tiling). For the Imageio-ext
project (https://imageio-ext.dev.java.net/) we have tried to implement
a partial multithreaded ImageRead which we called ImageReadMT which
assumes that multiple reads performed on the same ImageReader are safe
(this does nto mean in general that the ImageReader has to be thread
safe, which  is a morestrict requiremrnt).

What one could do could be reusing the ImageReadMT operation and
create a specific ImageReader decorator that makes use of a pool of
thread-unsafe image reader and pass this to the ImageReadMT to do
actual multithreading. Of course this is just an idea and it also has
quite some limitations, but it would be quite easy to implement and in
some conditions it could provide a huge performance gain.


Simone.

On Mon, Apr 21, 2008 at 7:45 AM,  <jai-interest@...> wrote:

> I didn't know that imageread is newer than fileload. I'll try it out.Hope it'll better handle multithreading.
>
> Thanks,
> Sergei
> [Message sent by forum member 'wikisky' (wikisky)]
>
> http://forums.java.net/jive/thread.jspa?messageID=270299
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@...
> For additional commands, e-mail: interest-help@...
>
>



--
-------------------------------------------------------
Eng. Simone Giannecchini
President /CEO GeoSolutions S.A.S.
Via Carignoni 51
55041 Camaiore (LU)
Italy

phone: +39 0584983027
fax: +39 0584983027
mob: +39 333 8128928


http://www.geo-solutions.it

-------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Are there any updates on this?  We're running into a very similar problem- users upload photos to our site and we scale them down, but we're running into a lot of contention in the scaling cluster during load testing.  We can only push our CPU (we're using Sun Fire T1000s)  usage to about 30% and it looks like it's all because of blocking in JAI.  

I guess I can try out the imageio-ext change described above and see if that helps at all, but any help would be great.
[Message sent by forum member 'atomly' (atomly)]

http://forums.java.net/jive/thread.jspa?messageID=274348

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by Brian Burkhalter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 From the code comments the locking is apparently due to the wrapped  
class over which JAI had no control:

     /**
      * Mutex for the entire class to circumvent thread unsafety of
      * com.sun.image.codec.jpeg.JPEGImageDecoder implementation.
      */
     private static final Object LOCK = new Object();

Reference: https://jai-core.dev.java.net/source/browse/jai-core/src/share/classes/com/sun/media/jai/codecimpl/JPEGImageDecoder.java?rev=1.3&view=markup

This means that JPEGs may be read only one at a time within the VM in  
which the class is instantiated. This is not the same as the Image I/O  
Framework's stated non-goal of thread safety which is worked around by  
the imageio-ext project. In that case what I think is dealt with - I  
have not looked into that project's details - is lack of thread safety  
when using the *same* ImageReader "simultaneously" on different  
threads, e.g., to read different tiles of the same image.

Note that the "ImageRead" JAI operation included in JAI Image I/O  
Tools is AFAIK thread-safe: the computeTile() method synchronizes on  
the ImageReader being used. If you are using the JAI "FileLoad"  
operation a simple change would be to use "ImageRead" instead. I think  
this would work just by changing that one string and of course  
installing JAI Image I/O Tools.

Presumably all the uploaded source images are JPEGs? What are the  
typical dimensions?

There are a number of factors which could be at play here:

* the JPEG reader lock you mention;
* re-reading the same JPEG due to a cache flush;
* if tiling is used, contention for the same tile in different  
scheduler threads.

This last problem is due to scaling (or other area or geometric  
operations which require context) needing a "corona" around the  
backward mapped destination region in order to compute the latter.  
Fixing it would be non-trivial.

On May 14, 2008, at 10:34 AM, jai-interest@... wrote:

> Are there any updates on this?  We're running into a very similar  
> problem- users upload photos to our site and we scale them down, but  
> we're running into a lot of contention in the scaling cluster during  
> load testing.  We can only push our CPU (we're using Sun Fire  
> T1000s)  usage to about 30% and it looks like it's all because of  
> blocking in JAI.
>
> I guess I can try out the imageio-ext change described above and see  
> if that helps at all, but any help would be great.
> [Message sent by forum member 'atomly' (atomly)]
>
> http://forums.java.net/jive/thread.jspa?messageID=274348

 >^..^<    >^..^<

Brian Burkhalter
Java Imaging and Video
Sun Microsystems, Inc.

This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.


---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks for your help.  I'll try out your suggestions.

Also, in my profiling, I'm finding that I'm spending a huge amount of my time in PlanarImage.getWidth(), which looks like it's all coming down to RenderedOp having a ton of synchronized methods:

https://jai-core.dev.java.net/source/browse/jai-core/src/share/classes/javax/media/jai/RenderableOp.java?rev=1.1&view=markup

I'll post here for posterity if I find good workarounds.
[Message sent by forum member 'atomly' (atomly)]

http://forums.java.net/jive/thread.jspa?messageID=274720

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by Brian Burkhalter :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On May 15, 2008, at 3:45 PM, jai-interest@... wrote:

> Thanks for your help.  I'll try out your suggestions.
>
> Also, in my profiling, I'm finding that I'm spending a huge amount  
> of my time in PlanarImage.getWidth(), which looks like it's all  
> coming down to RenderedOp having a ton of synchronized methods:

I suspect it is more an artifact of deferred execution.

Brian

> https://jai-core.dev.java.net/source/browse/jai-core/src/share/classes/javax/media/jai/RenderableOp.java?rev=1.1&view=markup
>
> I'll post here for posterity if I find good workarounds.
> [Message sent by forum member 'atomly' (atomly)]
>
> http://forums.java.net/jive/thread.jspa?messageID=274720
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: interest-unsubscribe@...
> For additional commands, e-mail: interest-help@...
>

 >^..^<    >^..^<

Brian Burkhalter
Java Imaging and Video
Sun Microsystems, Inc.

This email message is for the sole use of the intended recipient(s)
and may contain confidential and privileged information. Any
unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.


---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm not entirely sure what you mean by "artifact of deferred execution."

In my load testing, about 27% of the time is spent in

com.sun.media.jai.codec.ImageEncoder.encode

and about 16% is taken in

javax.media.jai.PlanarImage.getWidth


If you're saying that there is some prep-work on PlanarImage that doesn't get executed until the first call into the instance and that happens to be getWidth, I'd believe that, but that's still a huge amount of time spent in there.  Especially considering the fact that we can't push our CPU past about 30% no matter how many machines/threads we throw at it.
[Message sent by forum member 'atomly' (atomly)]

http://forums.java.net/jive/thread.jspa?messageID=275596

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue

by jai-interest-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I am just curios, are you using by any chance Solaris?
I asking because I memorize as we has similar problem. The OS seem to think that our java process had nothing to do - jvm just din't get processor time. It worked for a while, then it slept for about one minute and so on. On cheap Win XP system our programm worked all the time with 100% CPU.
[Message sent by forum member 'imagero' (imagero)]

http://forums.java.net/jive/thread.jspa?messageID=275602

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: quad-core processor limited utilization. performance issue