Simple JNI performance question

C

cppaddict

I have a java program that needs to work with raw pixel data captured
from the screen. Currently I have the code that captures and processes
the data on the native side (in C++) -- and the results of the
processing, which are small amounts of data, are passed back to Java.

How big of a performance hit would my program take if I only used C++
to capture the data, and then passed the raw pixel data back to my
Java program as an int[][] array?

Each int[][] would probably contain about 1.5MB of data, and I would
be returning arrays back to my Java program fairly frequently, say
once every ten seconds or so. Would this be a viable option, or should
I keep everything on the native side?

TIA,
cpp
 
R

Roedy Green

I have a java program that needs to work with raw pixel data captured
from the screen. Currently I have the code that captures and processes
the data on the native side (in C++) -- and the results of the
processing, which are small amounts of data, are passed back to Java.

To answer that question you could write a little simulation program
that just transfers random gibberish around.

--
Bush crime family lost/embezzled $3 trillion from Pentagon.
Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm

Canadian Mind Products, Roedy Green.
See http://mindprod.com/iraq.html photos of Bush's war crimes
 
S

Stefan Schulz

Roedy,

I just realized that I could have my native method return a pointer to
the raw data. Do you know if this possible? If so, how can you do
it? I can't find any examples in sun's JNI tutorial:

http://java.sun.com/docs/books/tutorial/native1.1/index.html

Thanks...

You can't use raw pointers in java. This is one of the safety features of
the language. You will always have to wrap some kind of object around the
data. However, you could get away with murder if you create a pinned
array, and then only update its contents.
 
C

Chris Uppal

cppaddict said:
How big of a performance hit would my program take if I only used C++
to capture the data, and then passed the raw pixel data back to my
Java program as an int[][] array?

It's not immediately clear what you would gain by doing so -- since you already
have the working C++ code (I assume), and since the change wouldn't allow you
to eliminate JNI/C++ completely, it's not obvious to me that there's a net
gain.

Anyway...

Some things to be aware of.
Each int[][] would probably contain about 1.5MB of data, and I would
be returning arrays back to my Java program fairly frequently, say
once every ten seconds or so.

There should be no problem at all with transferring such relatively small
amounts of data across the Java/C++ interface. JNI has a relatively high
overhead per call, but you wouldn't be making a JNI call for each int, but only
a small number per /array/.

A C++ int[][] array does not have the same layout as a Java int[][] array --
the former is a single contiguous chunk of memory where each access is compiled
into a combination of multiply and add to find the corresponding index. In
Java 2d array is actually an array of arrays, so accessing an item requires an
array lookup, an indirection, and another array lookup. There are two
problems with that; the first is that you would have to transform the C++
layout into Java layout (not difficult, but it does add mess to the code since
you'd have to create and populate each sub-array separately); the second is
that the Java code would take a (fairly small, but possibly still significant)
performance hit. You could avoid both problems by treating the data as a
single large int[] array in Java, but that would complicate your Java code,
since you'd have to write the multiply-and-add stuff yourself rather than
having the compiler do it for you.

So the question doesn't really have as lot to do with JNI -- it's more a
question of whether the gains (whatever they are to you) of (re)writing the
data-manipulation code in Java are worth either a performance hit or added
complexity.

-- chris
 
C

Chris Uppal

cppaddict said:
I just realized that I could have my native method return a pointer to
the raw data. Do you know if this possible?

There are ways to hack it, but it's probably a bad idea since you'd then end up
with the overhead of a JNI call to access each int, rather than just a few JNI
calls to create and populate Java arrays.

-- chris
 
C

cppaddict

So the question doesn't really have as lot to do with JNI -- it's more a
question of whether the gains (whatever they are to you) of (re)writing the
data-manipulation code in Java are worth either a performance hit or added
complexity.

Hey Chris,

Thanks for your helpful explanation.

Essentially, the gains to me are that I could develop in Java, which
means I'll write new code faster and it will be easier to maintain.
It's not really a question of migrating the old processing code over
-- which I won't actually do -- but instead one of being able to write
new processing code in Java.

Basically, from what you said, it sounds like it is very doable. I'll
write fill up the Java array in C++ (which is where the messy
add/multiply code will go) and then I'll have my array in Java.

I'll try it and see how it goes.....

Thanks,
cpp
 
M

Manuel J. Goyenchea

You may want to take a look at Jenie,
http://www.servertec.com/products/jenie/jenie.html. Among other things it
will allow you to efficiently access, update and manage native resources,
like your large native array from Java without having to copy it up to Java.
Using Jenie you can also directly access native libraries without having to
use JNI and without having to write C/C++ code. No more JNI nightmares or
worries. Internally it is doing all the JNI stuff for you.
 
J

Joan

cppaddict said:
I have a java program that needs to work with raw pixel data captured
from the screen. Currently I have the code that captures and processes
the data on the native side (in C++) -- and the results of the
processing, which are small amounts of data, are passed back to Java.

How big of a performance hit would my program take if I only used C++
to capture the data, and then passed the raw pixel data back to my
Java program as an int[][] array?

Can you allocate the space on the java side and pass a reference to it
to your C++ pgm and have the C++ pgm put the data into the java array?
Each int[][] would probably contain about 1.5MB of data, and I would
be returning arrays back to my Java program fairly frequently, say
once every ten seconds or so. Would this be a viable option, or should
I keep everything on the native side?

TIA,
cpp
 
M

Manuel J. Goyenchea

I think that the problem is having Java manage that kind of data. I've done
a lot of work with having Java manage relatively large number of objects
that are very small and Java eventually chokes because of the garbage
collector. Don't get me wrong it's gotten a lot better with new releases of
Java in comparision to how it was with JDK 1.1.x, but it's still a problem
for the types of programs that I have writte. Plus doing it from Java has
the added overhead of accessing Java managed data which is usually greater
than Java accessing native managed data. Think of all the parameter checking
that Java is doing and all the stack trace stuff that goes on when you do an
value = array[offset] or array[offset] = value. Plus their is the cost of
conversion or moving the data generated from native to Java. That is why I
made an earlier posting about Jenie, which I wrote, to help me deal with
such cases. I basically let the native layer manage the data which is coming
from C/C++ that is causing me problem. I don't have to worry about all the
stuff that Java does to throw me nice exceptions, which I don't need to
repeatedly do. I can check my parameters once and then read/write the native
data directly from Java without having to do any type of marshalling. An
added benefit is that I don't have to write JNI code which can be
troublesome, tedious and time consuming.

Joan said:
cppaddict said:
I have a java program that needs to work with raw pixel data captured
from the screen. Currently I have the code that captures and processes
the data on the native side (in C++) -- and the results of the
processing, which are small amounts of data, are passed back to Java.

How big of a performance hit would my program take if I only used C++
to capture the data, and then passed the raw pixel data back to my
Java program as an int[][] array?

Can you allocate the space on the java side and pass a reference to it
to your C++ pgm and have the C++ pgm put the data into the java array?
Each int[][] would probably contain about 1.5MB of data, and I would
be returning arrays back to my Java program fairly frequently, say
once every ten seconds or so. Would this be a viable option, or should
I keep everything on the native side?

TIA,
cpp
 
A

AWieminer

I have a java program that needs to work with raw pixel data captured
from the screen. Currently I have the code that captures and processes
the data on the native side (in C++) -- and the results of the
processing, which are small amounts of data, are passed back to Java.

How big of a performance hit would my program take if I only used C++
to capture the data, and then passed the raw pixel data back to my
Java program as an int[][] array?

Each int[][] would probably contain about 1.5MB of data, and I would
be returning arrays back to my Java program fairly frequently, say
once every ten seconds or so. Would this be a viable option, or should
I keep everything on the native side?

Use direct ByteBuffer/IntBuffers and you dont need to copy the actual
data, just pointer to a table.
 
M

Manuel J. Goyenchea

Yeap, if he can use direct java.nio.ByteBuffer/IntBuffer, that may noticably
improve his performance. Sadly for me, I work on mostly embedded systems
that barely support Java 1.1.x and don't have support for java.nio, which
was added in Java 1.4.x.

AWieminer said:
I have a java program that needs to work with raw pixel data captured
from the screen. Currently I have the code that captures and processes
the data on the native side (in C++) -- and the results of the
processing, which are small amounts of data, are passed back to Java.

How big of a performance hit would my program take if I only used C++
to capture the data, and then passed the raw pixel data back to my
Java program as an int[][] array?

Each int[][] would probably contain about 1.5MB of data, and I would
be returning arrays back to my Java program fairly frequently, say
once every ten seconds or so. Would this be a viable option, or should
I keep everything on the native side?

Use direct ByteBuffer/IntBuffers and you dont need to copy the actual
data, just pointer to a table.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top