Xith contributions

Hi,

I start this thread to gather some constructive comments on xith.

So here’s my first contribution :

REDUCING GC OVERHEAD

I’ve profiled the CubeTest application to gather some stats on xith memory usage, and here’s where most of the time is spent (gc-wise) :

  • RenderBin. sortByShaders() (and other sort methods if used) : uses Arrays.sort() and thus allocates a new RenderBucket[3000] every frame.

Here’s the quicksort (copyright sir Gosling, and me :wink: ) I’ve added in RenderBin to stop it :


/** This is a generic version of C.A.R Hoare's Quick Sort 
    * algorithm.  This will handle arrays that are already
    * sorted, and arrays with duplicate keys.

    *
    * If you think of a one dimensional array as going from
    * the lowest index on the left to the highest index on the right
    * then the parameters to this function are lowest index or
    * left and highest index or right.  The first time you call
    * this function it will be with the parameters 0, a.length - 1.
    *
    * @param a       an object array
    * @param lo0     left boundary of array partition
    * @param hi0     right boundary of array partition
    * @param comp    the comparator used
    */
   private static void quickSort(Object a[], int lo0, int hi0, Comparator comp) {
      int lo = lo0;
      int hi = hi0;
      Object mid;

      if ( hi0 > lo0)  {

         /* Arbitrarily establishing partition element as the midpoint of
          * the array.
          */
         mid = a[ ( lo0 + hi0 ) / 2 ];

         // loop through the array until indices cross
         while( lo <= hi ){
            /* find the first element that is greater than or equal to 
             * the partition element starting from the left Index.
             */
            while( ( lo < hi0 ) && ( comp.compare(a[lo],mid) < 0 ) ){
              ++lo;
            }

            /* find an element that is smaller than or equal to 
             * the partition element starting from the right Index.
             */
            while( ( hi > lo0 ) && ( comp.compare(a[hi], mid)>0 ) ){
              --hi;
            }

            // if the indexes have not crossed, swap
            if( lo <= hi )  {
               swap(a, lo, hi);

               ++lo;
               --hi;
            }
         }

         /* If the right index has not reached the left side of array
          * must now sort the left partition.
          */
         if( lo0 < hi )
            quickSort( a, lo0, hi , comp);

         /* If the left index has not reached the right side of array
          * must now sort the right partition.
          */
         if( lo < hi0 )
            quickSort( a, lo, hi0 , comp);

      }
   }

   private static void swap(Object a[], int i, int j)
   {
      Object T;
      T = a[i]; 
      a[i] = a[j];
      a[j] = T;

   }

    

Then just update the sort methods …


    public void sortByShaders() {
      quickSort(buckets, 0, curSize-1, stateComparator);
    //  Arrays.sort(buckets,0,curSize,stateComparator);
    }

Lilian

edited : typos

Second and more important update related to GC : the vecmaths ilbrary is creating a lot of garbage (millions of double[] per second)

Here’s the patch :

Matrix3d : move the scratch array creation out of the compute_qr and compute_svd methods


 static double[]   cosl  = new double[2];
	static double[]   cosr  = new double[2];
	static double[]   sinl  = new double[2];
	static double[]   sinr  = new double[2];
	static double[]   m = new double[9];

    static  int compute_qr( double[] s, double[] e, double[] u, double[] v) {

and


         static double[] u1 = new double[9];
	static double[] v1 = new double[9];
	static double[] t1 = new double[9];
	static double[] t2 = new double[9];
	static double[] rot = new double[9];
	static double[] e = new double[3];
	static double[] scales = new double[3];

    static void compute_svd( double[] m, double[] outScale, double[] outRot) {


In Matrix4f, same thing for getScale() and getScaleRotate() (two arrays)

With that patch and the previous one, I’ve reduced the time spent in GC from 60 * 0.4ms to 1*0.3ms per second in the CubeTest demo… not too bad !

Regards,

Lilian

Great !!

What’s next ? I would be glad to help but I haven’t took a look to the core code for now.

coming soon : I’ll have a deeper look at the pipeline… may be try to batch (display list) the state initialisation between VBO calls, to reduce the JNI overhead when many state changes are involved in a scene… don’t know yet if it would be useful or not.

but first is the jsr231 port…

Lilian

All right.

About the vecmaths code update : it’s not thread safe, so we’d better add new methods in Matrix4f and call them from xith instead of simply updating the thread safe ones.

Lilian

Yes, you’re right. Do you plan to commit these to the vecmath CVS ?

No : not enough time right now to properly join this project (used by other applications) and convice the committers to include the patched classes.

May be we could just add theses classes to the Xith jar, like it’s been done to the MatrixExt4f

Lilian

OK, seems fine.

Looks great!

With patches, the best way to submit them is to join the Xith3D project as a “BetaTester” (really what that means is that you can add and modify issues) and submit the issues to IssueZilla for tracking (include links to the forum discussions). Using the “Bugs” link on http://xith.org I can easily see what patches need to be committed. I’ll be sure to commit your patch in, I can file the Issue for your if you would prefer.

With vecmath I assume your patched ones are API compatable to vecmath. We could put them in the Xith-TK CVS but as a seperate compiled .jar allowing people to choose implementations. I agree that the correct place for any vecmath API extensions (as opposed to internal changes) is the Xith3D core like MatrixExt4f (as Xith3D isn’t and shouldn’t be dependant on the Xith-TK itself).

Will.

Interested in what you used to measure this. I have messed with a number of profilers/debuggers and have had minimal success in finding probs within xith

Ok I should file the patches next week.

about profiling :

  • I started profiling simply with the jvm switch -verbose:gc and as it showned many small pauses, I’ve continued with the nb profiler.
  • The netbeans 5 profiler with “record object allocation and deallocation” mode shows statistics about the most often created object (I reset the recording in the middle of the test to avoid recording the swint/awt startup), then you just have to backtace to the methods used to create such objects. in that case in was many arrays of doubles.

I’ve used the Cube demo as it was a convenient scene with many object and movements, although not representative of a real-world case.

I’ll try it also next week with the Q3 loader to see how well in performs in the gc side. results should be very different as it’s a static world with a moving camera.

Lilian

I have committed in the quicksort change. CVS log here: https://xith3d.dev.java.net/servlets/ReadMsg?list=cvs&msgNo=470

I will commit in your patch for the other changes when you submit it.

How do you plan to do the Matrix3d and Matrix4f changes? Similar to com.xith3d.datatypes.MatrixExt4f by just overriding them and changing what you need?

Will.

Yes, that should be enough.

About the vecmaths, I don’t know, may be just create an vecmaths_nts.jar (“not thread safe”) and distribute it optionally

I’ll file an RFE next week.

Lilian

Hi,

As of VecMath and GC, this topic was discuseed 1-1.5 years ago (I think it should be possible to find it in forum archives).

Yes, standard version of vecmath from Sun produces a lot of garbage, but there is another one version of vecmath originally developed (published) by Kenji Hiranabe (I hope I spelled his name right from my head), and that library works pretty fine and produces nearly no garbage (or even no garbage at all). Artur Besiadovski (aka abies) pointed me to this library long time ago.

This lib is 100% compatible with javax.vecmath, (even from the naming) so I only made few modifications with it and just use another jar file instead of original vecmath.jar.

You should consider using this library I think. (actually, last time I pointed to some licensing issues, but to say truth I did not dig deep enough to this topic).

Yuri