Re: JAI optimizing..
Warming up the test seems to make a huge difference. The first
RenderedOp takes about 6 times longer than the whole pojo processing,
but each additional RenderedOp takes only fractions of the total time,
leading me to believe the set-up of JAI is slow, but processing is
extremely fast once you have all the system resources set-up. I
achieved almost a 100 fold speed increase for processing 5 million
coordinates, compared to pojo.
I dived a little deeper in the JAI docs, and essentially tried to
rewrite the setup using RenderableOp and ParameterBlock's instead of
RenderedOp. I got it to compile correctly, but during runtime, I get
an exception that got me rather puzzled:
Exception in thread "main" com.sun.medialib.mlib.mediaLibException:
mediaLib: exception in a native method.
at com.sun.medialib.mlib.Image.ExtremaLocations(Native Method)
at
com.sun.media.jai.mlib.MlibExtremaOpImage.accumulateStatistics(MlibExtremaOpImage.java:
170)
at
javax.media.jai.StatisticsOpImage.getProperty(StatisticsOpImage.java:
292)
at
com.sun.media.jai.opimage.ExtremaOpImage.getProperty(ExtremaOpImage.java:
100)
at javax.media.jai.RenderedOp$1.getProperty(RenderedOp.java:1808)
at
javax.media.jai.PropertyEnvironment.getProperty(PropertyEnvironment.java:
197)
at
javax.media.jai.PropertySourceImpl.getProperty(PropertySourceImpl.java:
277)
at
javax.media.jai.WritablePropertySourceImpl.getProperty(WritablePropertySourceImpl.java:
130)
at javax.media.jai.RenderedOp.getProperty(RenderedOp.java:1982)
at JAIDistanceTest.testDistances2(JAIDistanceTest.java:180)
at JAIDistanceTest.<init>(JAIDistanceTest.java:71)
at JAITest.main(JAITest.java:40)
------------------------------------------------
And here is the code I used, maybe someone can spot the obvious
mistake? Thanks!
------------------------------------------------
int bits[] = new int[] {32};
ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorModel colorModel = new ComponentColorModel(colorSpace, bits,
false, false, Transparency.OPAQUE, DataBuffer.TYPE_INT);
SampleModel sampleModel =
colorModel.createCompatibleSampleModel(25,25);;
DataBufferInt dataBufferX = new DataBufferInt(xvalues,
xvalues.length);
WritableRaster rasterX =
WritableRaster.createWritableRaster(sampleModel, dataBufferX, new
Point(0,0));
BufferedImage imageX = new BufferedImage(colorModel, rasterX,
false, null);
DataBufferInt dataBufferY = new DataBufferInt(yvalues,
yvalues.length);
WritableRaster rasterY =
WritableRaster.createWritableRaster(sampleModel, dataBufferY, new
Point(0,0));
BufferedImage imageY = new BufferedImage(colorModel, rasterY,
false, null);
PlanarImage planarImageX = new RenderedImageAdapter(imageX);
PlanarImage planarImageY = new RenderedImageAdapter(imageY);
RenderingHints renderingHints = new
RenderingHints(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
renderingHints.put(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
renderingHints.put(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_DISABLE);
renderingHints.put(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
// create a renderable image with no downsampled piramid
ParameterBlock parameterBlockX = new ParameterBlock();
parameterBlockX.addSource(planarImageX);
parameterBlockX.add(null).add(null).add(null).add(null).add(null);
RenderableImage renderableImageX = JAI.createRenderable("renderable",
parameterBlockX);
// create a renderable image with no downsampled piramid
ParameterBlock parameterBlockY = new ParameterBlock();
parameterBlockY.addSource(planarImageY);
parameterBlockY.add(null).add(null).add(null).add(null).add(null);
RenderableImage renderableImageY = JAI.createRenderable("renderable",
parameterBlockY);
double[] xSub = new double[]{x};
double[] ySub = new double[]{y};
long nanoStart = System.nanoTime();
ParameterBlock parameterBlockSub1 = new ParameterBlock();
parameterBlockSub1.addSource(renderableImageX);
parameterBlockSub1.add(xSub);
RenderableOp renderableOpXSubXRef =
JAI.createRenderable("subtractconst", parameterBlockSub1);
ParameterBlock parameterBlockSub2 = new ParameterBlock();
parameterBlockSub2.addSource(renderableImageY);
parameterBlockSub2.add(ySub);
RenderableOp renderableOpYSubYRef =
JAI.createRenderable("subtractconst", parameterBlockSub2);
ParameterBlock parameterBlockPow1 = new ParameterBlock();
parameterBlockPow1.addSource(renderableOpXSubXRef);
parameterBlockPow1.addSource(renderableOpXSubXRef);
RenderableOp renderableOpXDiff2 = JAI.createRenderable("multiply",
parameterBlockPow1);
ParameterBlock parameterBlockPow2 = new ParameterBlock();
parameterBlockPow2.addSource(renderableOpYSubYRef);
parameterBlockPow2.addSource(renderableOpYSubYRef);
RenderableOp renderableOpYDiff2 = JAI.createRenderable("multiply",
parameterBlockPow2);
ParameterBlock parameterBlockSum = new ParameterBlock();
parameterBlockSum.addSource(renderableOpXDiff2);
parameterBlockSum.addSource(renderableOpYDiff2);
RenderableOp renderableOpSum = JAI.createRenderable("add",
parameterBlockSum);
AffineTransform screenResolution = new AffineTransform();
RenderContext renderContext = new
RenderContext(screenResolution);
RenderedOp renderedOpExtrema =
ExtremaDescriptor.create(renderableOpSum.createRendering(renderContext),
null, 1, 1, true, 1, renderingHints);
long nanoEnd = System.nanoTime();
List minLocations =
((List[])renderedOpExtrema.getProperty("minLocations"))[0];
some good references in case you are interested:
http://72.5.124.55/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Programming-environ.doc.html#55932
http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Image-manipulation.doc.html#56366
http://java.sun.com/j2se/1.3/docs/api/java/awt/image/renderable/RenderableImage.html
(JAI API docs)
http://www.geocities.com/larryhr/samplecode/samplecode.html (sample
code)
http://forums.java.net/jive/thread.jspa?messageID=235530&tstart=0
(chained calls)
http://java.sun.com/products/java-media/jai/forDevelopers/jaifaq.html
(sun tutorials)
On 24 sep, 20:15, a0a <ignace.sae...@gmail.com> wrote:
Hi everyone,
I did a little benchmark on the speedup thatJAIcan bring in
computing the point with minimum distance from a given source point
(x,y) out of an array of x,y coordinates.
I did this both withJAIand by brute-forcing it using a simple
distance check. Although theJAIis very elegant in that it
automatically returns ALL minimum distance points, it is also 6 times
slower than the brute-force method.
I am guessing that I may have gotten something wrong in the set-up,
but since the information onJAIand tutorials are rather scarce or
not working at all, I thought maybe someone here could take a look at
this:
------ this is what I want to do ------
ArrayList<Integer> indexes = new ArrayList<Integer> ();
int closestPoint = Integer.MAX_VALUE;
for (int i = 0; i < xvalues.length; i++)
{
int xdiff = xvalues[i] - x;
int ydiff = yvalues[i] - y;
int sqr = xdiff* xdiff + ydiff*ydiff;
if ( sqr == closestPoint )
{
indexes.add(i);
}
if ( sqr < closestPoint )
{
closestPoint = sqr;
indexes.clear();
indexes.add(i);
}
}
------ this is what does it, but 6 times slower, inJAI------
double[] xSub = new double[]{x};
double[] ySub = new double[]{y};
RenderedOp renderedOpXSubXRef = SubtractConstDescriptor.create(imageX,
xSub, rh);
RenderedOp renderedOpYSubYRef = SubtractConstDescriptor.create(imageY,
ySub, rh);
RenderedOp renderedOpXDiff2 =
MultiplyDescriptor.create(renderedOpXSubXRef, renderedOpXSubXRef, rh);
RenderedOp renderedOpYDiff2 =
MultiplyDescriptor.create(renderedOpYSubYRef, renderedOpYSubYRef, rh);
RenderedOp renderedOpSum = AddDescriptor.create(renderedOpXDiff2,
renderedOpYDiff2, rh);
RenderedOp renderedOpExtrema = ExtremaDescriptor.create(renderedOpSum,
null, 1, 1, true, 1, rh);
List minLocations =
((List[])renderedOpExtrema.getProperty("minLocations"))[0];
------------------------------------------------------------------------------------
Of course, right before this code I convert the 2 int[] arrays
containing x values and y values into BufferedImages using a GrayScale
colorspace, 32 bit colorModel with no alpha, no transparency, no
premultiplication. I do not alter the rasters during computation, I
merely fetch the min values from the list "minLocations" afterwards.
Timing it indicates that processing is extremely slow, however, I
still have to rewrite the benchmark to warm up first and redo the test
a number of times, maybe the test may show improvement. However, if
anyone has ideas how to speed up the operation pipe, I am all ears!