Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (524)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (592)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Native sqrt() faster than Math.sqrt() ?  (Read 4297 times)
0 Members and 1 Guest are viewing this topic.
Offline matheus23

JGO Kernel


Medals: 113
Projects: 3


You think about my Avatar right now!


« Posted 2012-05-29 08:18:39 »

So... I always wondered, whether Java's Math.sqrt() would be faster than a call to the JNI, calling <math.h>'s/C's sqrt().

If anyone else wondered, here is the result, printed by my program:
Quote
Starting to initialize values.
Initializing finished. Starting Java's Math.sqrt():
Time taken with Math.sqrt(): 8767
Starting native C++'s sqrt():
Time taken with native sqrt(): 77396

The Java code is the following (REALLY trivial):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
package org.matheusdev.jni;

import java.util.Random;

public class SQRTNative {
   
   static {
      System.loadLibrary("SQRTNative");
   }
   
   private native static double sqrt(double d);
   
   public static void main(String[] args) {
      final long repeat = 2330000000L; // 2.330.000.000 times sqrt().
      final int values = 1000000;  //  1.000.000 a.k.a. 4 MB of doubles.
      long time; // local for measuring time.
     
      // Initialize random values:
      System.out.println("Starting to initialize values.");
      double[] vals = new double[values];
      Random rand = new Random();
      for (int i = 0; i < values; i++) {
         vals[i] = rand.nextDouble()*1000;
      }
     
      // Java's Math.sqrt:
      System.out.println("Initializing finished. Starting Java's Math.sqrt():");
      time = System.currentTimeMillis();
      for (long i = 0; i < repeat; i++) {
         Math.sqrt(vals[(int)(i%values)]);
      }
      System.out.println("Time taken with Math.sqrt(): " + (System.currentTimeMillis()-time));
     
      // Native sqrt() from C++:
      System.out.println("Starting native C++'s sqrt():");
      time = System.currentTimeMillis();
      for (long i = 0; i < repeat; i++) {
         sqrt(vals[(int)(i%values)]);
      }
      System.out.println("Time taken with native sqrt(): " + (System.currentTimeMillis()-time));
   }

}


And the code inside the "libSQRTNative.so" (running linux 64 bit here Wink ) is simple too:
1  
2  
3  
4  
5  
6  
7  
8  
9  
#include "jni.h"
#include <math.h>
#include "SQRTNative.h"

JNIEXPORT jdouble JNICALL
Java_org_matheusdev_jni_SQRTNative_sqrt(JNIEnv *env, jclass cls, jdouble d)
{
    return sqrt(d);
}


Built with "QtCreator's build lib for release", aka GCC. Haven't messed around with any build flags Wink

One thing more to add: I use "only" 1 MIO values, cause I can't even create an Array of the size of 2.330.000.000 doubles, and besides, it would crash with an OutOfMemoryException anyways.

I used exactly 2.330.000.000, cause I have a running 2.33 GHz cpu at that point, so you can easily see, that Java's sqrt takes about 8-9 clock ticks per computation, and the C++'s one takes aabout 77 cpu clock ticks.
These values are not perfect, because of the system needing resources, the Chromium running with 13 Tabs, the Eclipse running, one Dolphin running and a QtCreator running.

I assume that most time spent in the native version is the JNI overhead.

Also, this was a JNI-learing-and-have-fun-with-performance-tests-test-project, keep that in mind, and correct me, if I could do something better Wink

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #1 - Posted 2012-05-29 08:27:22 »

This is because the JVM inlines the call to Math.sqrt. Also, the assumption that 1 call to sqrt = 1 clock tick is ludicrous Wink

Offline matheus23

JGO Kernel


Medals: 113
Projects: 3


You think about my Avatar right now!


« Reply #2 - Posted 2012-05-29 08:29:13 »

Also, the assumption that 1 call to sqrt = 1 clock tick is ludicrous Wink

I didn't assume something like that  Huh

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2012-05-29 08:33:09 »

You did, by assuming that it takes 8-9 clock ticks per computation if it took 8-9 seconds to compute your CPU's clock rate in values. There are numerous other variables involved, including stepping through that for loop and also the FLOPS of your CPU Wink

Offline matheus23

JGO Kernel


Medals: 113
Projects: 3


You think about my Avatar right now!


« Reply #4 - Posted 2012-05-29 08:38:25 »

I run my calculation 2.330.000.000 times, which is the number of ticks, my cpu does in 1 second (2.33 GHz).
So if the program takes 8.7 seconds, it takes 8-9 CLOCK TICKS per computation. I said 8-9 clock ticks.. I never said anything about 1 tick Huh

Also, lets assume, it takes 1 clock tick:
Then the time, the program runs, would be 1 * 2.330.000.000 / 2.33GHz = 1 sec.

You're right about the flops, but this is not really precise anyways.

EDIT:
if it took 8-9 seconds to compute your CPU's clock rate in values.

computing the clock rate?

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline princec

« JGO Spiffy Duke »


Medals: 422
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #5 - Posted 2012-05-29 08:59:42 »

This is a bit of a worrying microbenchmark because on the server VM for example that entire Java sqrt loop should be optimised away to nothing. I'd at least change both loops to sum the result of the sqrt and output it to stdout or you risk getting totally random looking results running this elsewhere.

Cas Smiley

Offline matheus23

JGO Kernel


Medals: 113
Projects: 3


You think about my Avatar right now!


« Reply #6 - Posted 2012-05-29 09:04:45 »

This is a bit of a worrying microbenchmark because on the server VM for example that entire Java sqrt loop should be optimised away to nothing. I'd at least change both loops to sum the result of the sqrt and output it to stdout or you risk getting totally random looking results running this elsewhere.

Cas Smiley

Oh crap!... You're right Grin

results:
Quote
Starting to initialize values.
Initializing finished. Starting Java's Math.sqrt():
Time taken with Math.sqrt(): 24905
Sum... : 4.909987867259176E10
Starting native C++'s sqrt():
Time taken with native sqrt(): 59444
Sum... : 4.909987867259176E10

That really looks like it got optimized away... I wonder, why didn't it just optimize away the whole loop? So it acctually does... nothing? Cheesy
Anyways, java seems to be about 2 times faster, than C++ with JNI.

EDIT: To the sum: they either share the exactly same algorithm, or java inlines the Math.sqrt() function with C++'s sqrt() func :DD

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #7 - Posted 2012-05-29 09:04:57 »

This is a bit of a worrying microbenchmark because on the server VM for example that entire Java sqrt loop should be optimised away to nothing. I'd at least change both loops to sum the result of the sqrt and output it to stdout or you risk getting totally random looking results running this elsewhere.

Cas Smiley
I was thinking that too. I originally wrote that in my first post, but quickly edited it because I noticed that it took 8 whole seconds for the first loop!

I run my calculation 2.330.000.000 times, which is the number of ticks, my cpu does in 1 second (2.33 GHz).
So if the program takes 8.7 seconds, it takes 8-9 CLOCK TICKS per computation. I said 8-9 clock ticks.. I never said anything about 1 tick Huh

Also, lets assume, it takes 1 clock tick:
Then the time, the program runs, would be 1 * 2.330.000.000 / 2.33GHz = 1 sec.

You're right about the flops, but this is not really precise anyways.

EDIT:
if it took 8-9 seconds to compute your CPU's clock rate in values.

computing the clock rate?
Ah you're not a native English speaker then huh? Wink (unless I can't explain myself persecutioncomplex)

Offline matheus23

JGO Kernel


Medals: 113
Projects: 3


You think about my Avatar right now!


« Reply #8 - Posted 2012-05-29 09:07:54 »

This is a bit of a worrying microbenchmark because on the server VM for example that entire Java sqrt loop should be optimised away to nothing. I'd at least change both loops to sum the result of the sqrt and output it to stdout or you risk getting totally random looking results running this elsewhere.

Cas Smiley
I was thinking that too. I originally wrote that in my first post, but quickly edited it because I noticed that it took 8 whole seconds for the first loop!

I run my calculation 2.330.000.000 times, which is the number of ticks, my cpu does in 1 second (2.33 GHz).
So if the program takes 8.7 seconds, it takes 8-9 CLOCK TICKS per computation. I said 8-9 clock ticks.. I never said anything about 1 tick Huh

Also, lets assume, it takes 1 clock tick:
Then the time, the program runs, would be 1 * 2.330.000.000 / 2.33GHz = 1 sec.

You're right about the flops, but this is not really precise anyways.

EDIT:
if it took 8-9 seconds to compute your CPU's clock rate in values.

computing the clock rate?
Ah you're not a native English speaker then huh? Wink

The 8 seconds might be due to the JVM not optimizing that piece of code the first time, it gets called... Just the about... 1.000.000.000. time...

Nope, I'm not native speaker, but I don't compute any clock rate anywhere, so I don't understand what you wanted to say Wink

See my:
    My development Blog:     | Or look at my RPG | Or simply my coding
http://matheusdev.tumblr.comRuins of Revenge  |      On Github
Offline princec

« JGO Spiffy Duke »


Medals: 422
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #9 - Posted 2012-05-29 09:19:49 »

matheus simply knows how fast the clock speed is on his CPU. Or at least the speed it claims to be running out out of the box which may not quite match what it is currently doing at the time depending on power saving tech that may be interfering...

Cas Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Roquen
« Reply #10 - Posted 2012-05-29 09:27:46 »

The whole reason for my HotSpot optimization list post is so that people don't need to experiment to determine known features.  Look in the intrinsic list and you'll see that Math.sqrt is indeed an intrinsic.  So no function is ever called..a native SSE instruction will be issued and scheduled with surrounding code.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

toopeicgaming1999 (57 views)
2014-11-26 15:22:04

toopeicgaming1999 (50 views)
2014-11-26 15:20:36

toopeicgaming1999 (10 views)
2014-11-26 15:20:08

SHC (24 views)
2014-11-25 12:00:59

SHC (24 views)
2014-11-25 11:53:45

Norakomi (26 views)
2014-11-25 11:26:43

Gibbo3771 (24 views)
2014-11-24 19:59:16

trollwarrior1 (36 views)
2014-11-22 12:13:56

xFryIx (75 views)
2014-11-13 12:34:49

digdugdiggy (52 views)
2014-11-12 21:11:50
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!