[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orekit Developers] Implementation of a CIRF 2000 Frame using a time stamped cache


Here is a summary of what we did recently, trying to use the TimeStampedCache to solve some of our issues.
First we tried to solve the problem of data corruption, and then, time calculation by using TimeStampedCache instances.

We introduced a small change in the getTransformTo method from the Frame class, adding synchronized blocks, as shown below :

        // transform from common to instance
        Transform commonToInstance = Transform.IDENTITY;
        for (Frame frame = this; frame != common; frame = frame.parent) {
            synchronized (frame) {
                commonToInstance =
                    new Transform(frame.transform, commonToInstance);

        // transform from destination up to common
        Transform commonToDestination = Transform.IDENTITY;
        for (Frame frame = destination; frame != common; frame = frame.parent) {
            synchronized (frame) {
                commonToDestination =
                    new Transform(frame.transform, commonToDestination);

These changes were made for some of our multithreaded use cases that performed better in this case. But two propagations running each on one thread performed badly (extremely slow). Through profiling we found the cause of the slowdown to be constant cache swaps in the CIRF2000Frame class. 

So we prototyped a variant of the CIRF2000Frame class, called TimeStampedCIRF2000Frame. It replaces the cache arrays for pole coordinates with an instance of TimeStampedCache. The TimeStampedGenerator implementation and the class provided by the cache (PoleCoordinates) are inner classes for TimeStampedCIRF2000Frame.  The code is attached below.
We found this variant produces the same computational results as CIRF2000Frame, without apparent slowdown in a monothreaded environment. In a multithreaded environment, it performs reasonably well (i.e. two computations running in parallel take a combined time shorter than the same two running one after the other - but not by much.)

The test we made is to use several threads that run frame computations on different time spans. Each thread calculates PV coordinates in ITRF from an initial orbit in GCRF (an orbit every hour during one month). Then we compare frame computations in non-parallel and parallel threads, called ThreadOrbitShift. This program shows in a "vanilla" Orekit that parallel computations are very slow and (on close inspection of the files written to TEMP) produce corrupted data.
But then, changing getTransformTo as shown above solves the data corruption issue; replacing CIRF2000Frame by TimeStampedCIRF2000Frame (in FramesFactory.getCIRF2000() ) solves the performance issue for parallel computations.
For example, two threads launched one after the other take 8 s to calculate the coordinates. The initial OREKIT implementation could take up to 4 minutes with parallel threads and give wrong results. With the new implementation, a parallel calculation take a bit more than 4s and give exactly the same results.

We propose to use this implementation instead of the initial CIRF2000. We are going to attach the source code of TimeStampedCIRF2000Frame and the use case to the JIRA ticket.

Can you have a look at this source code ? 

Best regards,

Yannick TANGUY, Pierre CARDOSO