Java Forum / General / December 2005
Implementing Complex Numbers operation in bytecode
oulan bator - 01 Dec 2005 13:03 GMT hi,
does somebody know how to correctly(efficiently) implement complex numbers multiplication and division (I will handle for addition and substraction ;-) ) of complex numbers directly in bytecode (in double precision of course).
I'm also looking for some reference on how to convert such instructions into efficient stack operation (with limitation due to the JVM).
thanks
Roedy Green - 01 Dec 2005 19:13 GMT >does somebody know how to correctly(efficiently) implement complex >numbers multiplication and division (I will handle for addition and >substraction ;-) ) of complex numbers directly in bytecode (in double >precision of course). see http://mindprod.com/jgloss/complex.html
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Chris Smith - 01 Dec 2005 19:31 GMT > does somebody know how to correctly(efficiently) implement complex > numbers multiplication and division (I will handle for addition and [quoted text clipped - 3 lines] > I'm also looking for some reference on how to convert such instructions > into efficient stack operation (with limitation due to the JVM). I'm unsure what you're asking. Do you mean:
1. How to do it in Java that compiles to bytecode (as opposed to native code)?
2. How to get the fastest possible bytecode for that set of operations?
3. How to write and build software in a bytecode assembly-ish language?
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Roedy Green - 01 Dec 2005 19:44 GMT >(I will handle for addition and >> substraction ;-) ) of complex numbers directly in bytecode (in double >> precision of course). If you follow the link I gave you, you can see the calculations you want to do are pretty simple -- just a fat arithmetic expression.
The compiler should generate that optimally. There is not much that could be optimised.
Just use Javap or other disassembler to see the byte codes.
See http://mindprod.com/jgloss/jasm.html http://mindprod.com/jgloss/disassembler.html
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
oulan bator - 02 Dec 2005 08:28 GMT hi,
sorry for answering so late (I was out of office yesterday)...
I'm looking for an efficient way to perform operations over complex numbers on a JVM. If it is possible to do it directly in Java, it's all right, but I don't think so.
Roedy, which is the link you gave me ?
What's strikes me is that there are specific instructions in nowaday's processors for complex numbers operations. There aren't such instructions in JVM bytecode, how then can I have efficient complex number operations in JVM ?
IchBin - 02 Dec 2005 08:39 GMT > hi, [snip]
> Roedy, which is the link you gave me ? [snip] He gave you..
http://mindprod.com/jgloss/complex.html http://mindprod.com/jgloss/jasm.html http://mindprod.com/jgloss/disassembler.html
 Signature Thanks in Advance... IchBin, Pocono Lake, Pa, USA http://weconsultants.servebeer.com/JHackerAppManager __________________________________________________________________________
'If there is one, Knowledge is the "Fountain of Youth"' -William E. Taylor, Regular Guy (1952-)
oulan bator - 02 Dec 2005 09:06 GMT thank's, I did'nt see the first (and most interesting) one !
but this is exactly what I don't want a do ! This is known to be unefficient ! (see Peng Wu, Sam Midkiff etal "Efficient Support for Complex Numbers in Java") they have changed the JIT to reach "correct" performance for Complex Numbers Operations (CNO)
Roedy Green - 02 Dec 2005 19:18 GMT >they have changed the JIT to reach "correct" >performance for Complex Numbers Operations the problem with Java is not in the calculation with complex, but with the use of separate objects for every complex value. An array of 1000 complex requires 1000 separate little objects like bubbles hanging off it.
An efficient complex implementation treats complex like primitives, so you can have arrays of complex without needing any objects.
That could be done by adding a complex primitive to Java, or by something more far-reaching, allowing you to inline any small object.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Thomas Weidenfeller - 02 Dec 2005 12:29 GMT > What's strikes me is that there are specific instructions in nowaday's > processors for complex numbers operations. There aren't such > instructions in JVM bytecode, how then can I have efficient complex > number operations in JVM ? You assume that we all know and share your definition of "efficient", and you are surprised that we can't read your mind and guess your problem.
Apparently, your definition of "efficient" requires the existence of special byte code instructions for complex numbers in the JVM. And as you noted, there are no such bytecodes in the JVM. So you answered your own question. By your standards it is apparently impossible to have efficient operations for complex numbers in Java.
By other people's standards, a typical implementation of complex arithmetic using normal floating point operations in Java is efficient enough for these people's tasks and purposes.
We don't know your purpose, but by your standards you apparently want a FORTRAN compiler with a highly optimized implementation of the complex data type.
/Thomas
 Signature The comp.lang.java.gui FAQ: ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/
oulan bator - 02 Dec 2005 14:03 GMT sorry, if I sound a bit agressive, but I'm really not ...
I'm just looking around for a solution to have "efficient" complex numbers computation. I don't know yet how much efficient it must be. Indeed, the best still a good FORTRAN compiler. The worst beeing IMO a classical Complex class in java ( that lead to a lot of object instanciation).
In the middle I'm wondering : how much it costs to used normal floating point operation to perform complex number operations versus hardware call ?
Is there a hope that JIT could "recognize" coupled floating point operations ?
and last interogation: which the best algorithm to perform complex multiplication and division using usual floating point operation only ? (this was my initial question)
Thomas Weidenfeller - 02 Dec 2005 17:03 GMT > I don't know yet how much efficient it must be. Why not find that out first instead of thinking about premature optimization?
> The worst beeing IMO a classical Complex class in java ( that lead to a > lot of object instanciation). If you want to do it in standard Java, then you are faced with what you just qualified as "the worst". So why do you go for Java at all, if you think it doesn't work for you?
> In the middle I'm wondering : > how much it costs to used normal floating point operation to perform > complex number operations versus hardware call ? Count the number of floating point operations needed per complex number arithmetic operation and you have a good indication. I don't think anyone here is inclined to do the counting for you.
> Is there a hope that JIT could "recognize" coupled floating point > operations ? What do you want to hear? Some probability like "a 0.0003% chance"? What would that help you? If you want to rely on such behavior you have to study different VMs and settle on one VM which does it all the time - if you manage to find one at all.
> and last interogation: which the best algorithm to perform complex > multiplication and division using usual floating point operation only ? > (this was my initial question) Which actually has been answered. But in more detail, It depends on the format in which you store your numbers. The math is different if you make the unusual decision to model your numbers in goniometric form instead of arithmetic form. But in all cases, there are no huge algorithms involved. Any math textbook will give you the formulas. Did you even look up the formulas before asking about an algorithm?
/Thomas
 Signature The comp.lang.java.gui FAQ: ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/
Chris Smith - 02 Dec 2005 17:36 GMT > and last interogation: which the best algorithm to perform complex > multiplication and division using usual floating point operation only ? > (this was my initial question) The word "best" has no definition in that sentence. Best for what? For some kinds of calculations, it's best to represent floating point numbers in polar coordinates, for example; and for others, in cartesian coordinates. Obviously, the implementations will differ greatly depending on the underlying representation.
Assuming cartesian coordinates (since they are fairly normal), complex number arithmetic is just an algebraic problem. You end up with:
(a + ib) * (c + id) = (ac - bd) + i(bc + ad) (a + ib) / (c + id) = ((ac + bd) + i(bc - ad)) / (c^2 + d^2)
Even division involves only 11 floating point operations. It's a bit too straight-forward to use the word "algorithm" as you do above.
Incidentally, if the underlying processor has the capability to perform these calculations in fewer instructions, then it is possible that the JIT will recognize this during optimization and generate the more efficient code. It depends on the compiler, of course.
As for object instantiation, *if* this becomes a problem then you can tweak the design... for example by adding operate-and-replace operations that place the results of a calculation directly into one of the operands and avoid any object instantiation. However, keep in mind that short-lived object instantiation in a garbage collected language is cheap. This may not be a concern.
 Signature www.designacourse.com The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation
Chris Uppal - 02 Dec 2005 18:30 GMT > As for object instantiation, *if* this becomes a problem then you can > tweak the design... Or wait to see how well the new stuff in 1.6 works. If the claims I've seen that 1.6 will have escape analysis in the JIT, with a concomitant ability to avoid heap-allocation of "very temporary" objects, turn out to be correct, then I'd guess that could have quite a significant effect on some complex-heavy applications written in "natural" (for Java) style.
-- chris
Roedy Green - 02 Dec 2005 19:25 GMT >(a + ib) / (c + id) = ((ac + bd) + i(bc - ad)) / (c^2 + d^2) c^2 can be replaced by c*c, but other than that, there is simply no wiggle room in there for optimisation. If there were something simpler, mathematicians would likely have found it since 1572 when the rules for manipulating complex numbers were first published.
In java doing complex arithmetic with just double primitives is inconvenient but in principle just as fast an any other language. If you bundle them up into Complex object pairs, you will take a big performance hit.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 02 Dec 2005 19:19 GMT >and last interogation: which the best algorithm to perform complex >multiplication and division using usual floating point operation only ? >(this was my initial question) and it has already been answered. Please read the materials given to you.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 02 Dec 2005 19:12 GMT >Roedy, which is the link you gave me ? the one in my first answer http://mindprod.com/jgloss/complex.html
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 02 Dec 2005 19:13 GMT >What's strikes me is that there are specific instructions in nowaday's >processors for complex numbers operations. What machine are you thinking of? I have never encountered hardware complex. It is just built up out of ordinary floating point arithmetic.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
oulan bator - 02 Dec 2005 22:55 GMT I've read that SSE3 instructions set, extends the x86 architecture...and contains complex numbers instructions. see (http://www.intel.com/technology/itj/2004/volume08issue01/art01_microarchitecture /p06_sse.htm) I'm not a specialist, but it seems that in P4 at least there are complex number support (I migh be wrong )
I've read (not the first time since I still can't see the link to complex.html in the first answer) all the materials, but this is not what this is all about.
I'm almost building a FORTRAN compiler for JVM/bytecode (it's not exactly a FORTRAN compiler, but in the concern of complex numbers, and the four operations, it's not different ), It must be in bytecode ( otherwise I would use an existing one), and the most efficient it is the richer I'll get (;-) it's a joke, the better my app will be)
I was wondering if the best implementation in bytecode will still 10 times slower than FORTRAN ? (and which was this best implementation ...)
((ac + bd) + i(bc - ad)) / (c*c + d*d), is not enough (for me) to define the right algorithm.
first it's more correct to write : ans_re = (ac + bd)/ (c*c + d*d) ; ans_im = (bc - ad) / (c*c + d*d) ; and obviously (c*c + d*d) is duplicated (that is easy ... but it was just z1/z2) what about (z1*z2*z3) /( (z1+z2)(z2+z3)) (for instance) ??
I know I was'nt clear in my question (but it's hard to be clear in this case)
Roedy Green - 02 Dec 2005 23:51 GMT >I've read that SSE3 instructions set, extends the x86 >architecture...and contains complex numbers instructions. This is the SIMD extension -- the Intel floating point co-processor for vector operations.
I don't know if Java currently uses this at all.
the instructions added: Complex arithmetic (addsubps, addsubpd, movsldup, movshdup, movddup)
are apparently useful in complex arithmetic even if they don't implement mult/div directly.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 02 Dec 2005 23:52 GMT >I've read (not the first time since I still can't see the link to >complex.html what is happening when you try http://mindprod.com/jgloss/complex.html ?
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 03 Dec 2005 00:00 GMT >ans_re = (ac + bd)/ (c*c + d*d) ; >ans_im = (bc - ad) / (c*c + d*d) ; >and obviously (c*c + d*d) is duplicated (that is easy ... but it was >just z1/z2) >what about (z1*z2*z3) /( (z1+z2)(z2+z3)) (for instance) ?? It seems to me that actual computation is obvious, posted at http://mindprod.com/jgloss/complex.html
(a + ib) / (c + id) = ((ac + bd) + i(bc - ad)) / (c*c + d*d)
// or in practice: double bottom = 1.d / (c*c + d*d); double real = (ac + bd) * bottom; double imaginary = (bc - ad) * bottom;
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
P.Hill - 03 Dec 2005 02:08 GMT > I was wondering if the best implementation in bytecode will still 10 > times slower than FORTRAN ? (and which was this best implementation > ...) Sounds like premature optimization to me.
If you are optimizing because of that concern, I think you need to run some tests, the object allocation stuff is very fast (many times faster that in earlier versions).
-Paul
Roedy Green - 03 Dec 2005 03:27 GMT On Fri, 02 Dec 2005 18:08:19 -0800, "P.Hill" <goodhillREMOVE@xmissionREMOVE.com> wrote, quoted or indirectly quoted someone who said :
>Sounds like premature optimization to me. > >If you are optimizing because of that concern, I think you need to run >some tests, the object allocation stuff is very fast (many times faster >that in earlier versions). Bill Joy talked about the problem and the possible solutions to it when he spoke at the Colorado Software Summit. Granted that was in 1999.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
oulan bator - 03 Dec 2005 08:37 GMT My question was to feed a preliminary though about this topic. My next steps will be to benchmark naive complex implementation (acknowledging that instantiation is not that slow, and that in 1.6 will improve that) , less naive one, and finally find some optimization rules for mathematical expression involving complex numbers...
I'll look for Bill Joy speech (and papers about it)
thanks all
Roedy Green - 03 Dec 2005 14:59 GMT On Sat, 03 Dec 2005 03:27:18 GMT, Roedy Green <my_email_is_posted_on_my_website@munged.invalid> wrote, quoted or indirectly quoted someone who said :
>Bill Joy talked about the problem and the possible solutions to it >when he spoke at the Colorado Software Summit. Granted that was in >1999. Unfortunately I doubt it was transcribed. It was one of the high points of my life.
It was so interesting to learn about the battles within Sun and all the compromises, and how Joy himself was as keen as I am to do things correctly.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Chris Uppal - 03 Dec 2005 11:35 GMT > I'm almost building a FORTRAN compiler for JVM/bytecode (it's not > exactly a FORTRAN compiler, but in the concern of complex numbers, and > the four operations, it's not different I would be tempted to go for an approach where the generated bytecodes contained no Complex objects at all -- or rather, as few as possible. So an array of complex number would be implemented (as far as the JVM could tell from the code it was executing) just as an array of floats or doubles. Complex-values variables would be represented by two float/double variables at the JVM level. Similarly for parameters to methods/functions. The big problem is returning a complex value from a function; that can't be done in any straightforward way, so you would have to use a temporary full object -- either an instance of Complex or a double[2]. Using a real class, Complex, for these purposes might make interoperation with "normal" Java code easier, in which case your compiler would be considered to be just "very aggressive" about autoboxing Complex data.
One important question to consider is /which/ calculations you are worried about the performance of. If the biggest issue is about the creation of many temporary "objects" whilst doing complex arithmetic then the escape-analysis in 1.6 may help (so don't do anything complicated until you've tried 1.6 ;-) OTOH the issue may be the performance of big complex array calculations, where the space overheads of representing each value as a full object may kill you, or where the time overhead of a cache miss for accessing each object (via at least one more level of indirection) may kill you. In such cases representing the complex values in-line (as above) would be a good option, but you might also want to think about making complex array operations into a language primitive, implemented (via JNI) in C/Fortran/Assembler. There would be costs associated with crossing the JNI barrier (which might involve copying the data), but it might still be a useful design option.
There's no straightforward way to persuade the JIT to use Intel's SSE extensions -- not least because the code might not be running on Intel, or even Intel-compatible, hardware.
(BTW, on a side-note, if you had mentioned what you are trying to do in your earlier post then I doubt if you would have received quite so many dismissive or hostile responses. People around here get conditioned to expect stupid questions, but showing that you are embarking on a challenging and ambitious project is likely to preempt that.)
-- chris
oulan bator - 03 Dec 2005 12:03 GMT ok for the tip, next time I'll try to be more explicit about my programming skills !
My first "naive" implementation was to perform symbolic "inlining" of complex operation. But that's too much expensive. for instance : z3=z1*z2/(z1+z2) leads to two assignation: z3_re= a real expression ; z3_im = another real expression;
I had no opportunity to create local var like (c²+b²) in simple division (due to internal constraints, that i 'm trying to break).
prior to all, I'll have a look at 1.6 current version (if they have alerady implemented those features) but I'm still looking for scientific papers on benchmarking complex numbers support in Java ... does anybody know why IBM hs stopped the ninja project ?
Chris Uppal - 04 Dec 2005 12:51 GMT > My first "naive" implementation was to perform symbolic "inlining" of > complex operation. But that's too much expensive. for instance : > z3=z1*z2/(z1+z2) leads to two assignation: > z3_re= a real expression ; > z3_im = another real expression; I doubt whether you'll ever be able to avoid that; in fact I don't see how you could /expect/ to avoid that. If the Intel SIMD extensions can express that kind of thing in one "instruction" (I'm not familiar with SSE/SSE2) then the only way you'll be able to use them is either if the JIT is "clever" enough to spot the opportunity to use them (which I very much doubt[*]) or if you write your own JIT (I believe that the Sun JVM has hooks for providing a custom JIT, but I've only ever read of one research group attempting to use it).
([*] The 1.5.0 Sun JVM source appears to have no provision for even emitting the SIMD instructions except MOVSD/MOVSS)
> [...] I'm still looking for > scientific papers on benchmarking complex numbers support in Java ... Best thing I can suggest is to start with the papers you already have (such as the Ninja and Java Grande papers) and use Citeseer, and the like, to look for papers that refer to them.
> does anybody know why IBM hs stopped the ninja project ? I have a vague feeling that I remember IBM saying that they were folding their efforts into the Java Grande project. But then, Java Grande seems to have gone quiet too. I don't know whether that impression is correct, but it is at least conceivable that the big names have largely lost interest in making Java a replacement for Fortran. (/I/ could never see the point, anyway.)
-- chris
Roedy Green - 03 Dec 2005 15:01 GMT On Sat, 3 Dec 2005 11:35:53 -0000, "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly quoted someone who said :
>the code it was executing) just as an array of floats or doubles. >Complex-values variables would be represented by two float/double variables at >the JVM level. you might use a pair of arrays, or real/imaginary pairs at odd/even slots which I suspect should generate faster code mainly because of CPU caching.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Roedy Green - 03 Dec 2005 15:07 GMT On Sat, 3 Dec 2005 11:35:53 -0000, "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly quoted someone who said :
>Intel's SSE >extensions What you would do here is write a native vector method in MASM and a Java implementation for other platforms. The instructions I doubt will buy you much until you get a pipeline going to parallel process. It would be difficult for a compiler to utilize such special purpose hardware for general java code. You would use SSE to code your FFT or similar matrix/vector algorithm.
Unfortunately, Java syntax has no means to implement the code for some platform's native classes is C and some in Java.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|