Select to view content in your preferred language

JMap Multi-Threading

2988
8
Jump to solution
10-07-2013 08:00 AM
StephenBaier
Occasional Contributor
I recently noticed that the JMap doesn't require rendering to occur on any particular thread (as opposed to SWT, which requires display updates to happen on the Display thread). Following from that I realized I could have multiple threads rendering symbols on the JMap at the same time. However, I also noticed that rendering intermittently fails when rendering with "too many" threads.

Doing some reading on OpenGL this seems to be a synchronization issue between the rendering threads. Does anyone have experience doing multi-threaded rendering for JMap layers?

Note: I am using GraphicsLayers on an ArcGISLocalTiledLayer map. Runtime Java SDK 10.1.1 on RHEL 6.4.
0 Kudos
1 Solution

Accepted Solutions
ColinAnderson1
Esri Contributor
If you are adding a large number of graphics to a layer the recommended way would be to use the bulk add method public int[] addGraphics(Graphic[] graphics) rather than repeatedly calling addGraphic. If possible it is better to collect up batches of graphics and add them in one call. Internally only one thread can be adding a graphic to a layer at a time so your threads will effectively become synchronised so a large number of threads will not necessarily improve performance.

If you can provide more detail on the failures you are seeing we might be able to help further.

View solution in original post

0 Kudos
8 Replies
StephenBaier
Occasional Contributor
I just realized I see this in my application's log file:

Rendering engine : OpenGL
Info: XInitThreads() called for concurrent Thread support

Apparently it is properly initializing for concurrent rendering... anyone know what the maximum numbers of threads is?
0 Kudos
ColinAnderson1
Esri Contributor
Actual rendering of a JMap takes place on only one thread. Do you mean updating graphics layers from multiple threads? Are you able to provide some sample code that shows your problem?

Thanks.

Colin
0 Kudos
StephenBaier
Occasional Contributor
Sorry for the confusion, I am in fact talking about multiple threads concurrently drawing to multiple graphics layers (or multiple threads to a single graphics layer). When I only had two threads going, one for each of two different layers, I didn't see any problems. When I ramped it up to 10-20 threads (each data chunk having its own thread), I saw lots of rendering issues.

I was just wondering if there is a "safe" number of threads so I can render faster without loss... My average case is about half a million data points on a single layer and likely more on another layer.

A code snippet really would just be multiple threads doing addGraphic on the same layer and/or multiple layers.
0 Kudos
ColinAnderson1
Esri Contributor
If you are adding a large number of graphics to a layer the recommended way would be to use the bulk add method public int[] addGraphics(Graphic[] graphics) rather than repeatedly calling addGraphic. If possible it is better to collect up batches of graphics and add them in one call. Internally only one thread can be adding a graphic to a layer at a time so your threads will effectively become synchronised so a large number of threads will not necessarily improve performance.

If you can provide more detail on the failures you are seeing we might be able to help further.
0 Kudos
CarlosColón-Maldonado
Frequent Contributor
If you are adding a large number of graphics to a layer the recommended way would be to use the bulk add method public int[] addGraphics(Graphic[] graphics) rather than repeatedly calling addGraphic.


How can that be achieved with the MessageProcessor of the advanced symbol component? Only a single Message can be processed per call. I have near real-time requirements.
0 Kudos
MarkBaird
Esri Regular Contributor
Carlos,

The message procesor is supposed to work one message at a time.  It needs to be serialized so your position updates come through in the right order.  Imagine the following messages coming across the wire:

- Vehicle #1 at location A
- Vehicle #2 at location B
- Vehicle #1 at location C
- vehicle #2 at location D

The final position for vehicle #1 should be at C.  Vehicle #2 should be at D

If you put this through a thread pool your final vehicle positions might be wrong!

However I'm not justifying poor performance 🙂

Under the covers after we have processed the message the core C++ code uses multiple threads to perform the actual rendering.  The code dynamically decides on the number of threads to use depending on the processing capabilities of the host machine.

So I guess I'm interested in if you are experiencing an issue with processing large numbers of messages on application startup?  Are you looking to bulk process a large number of messages where you don't care about what order they are processed?  This isn't somethine we support, but it could considered... 

Mark
0 Kudos
CarlosColón-Maldonado
Frequent Contributor
I'm interested in if you are experiencing an issue with processing large numbers of messages on application startup?  Are you looking to bulk process a large number of messages where you don't care about what order they are processed?


Thanks for your explanation; it makes perfect sense. I didn't realize time synchronization was an integral part of your framework, i.e., thought you let the SDK consumers worry about that (it's what we do since we must update symbols' state based on currency settings). By the way, how's the symbol frame fill/color property suggestion coming?  I've bench-tested it with large amounts of symbols (upwards of 40,000 to 60,000) before noticing minor flickering or not-refreshing occurring, but that scenario is fortunately rare in our case. All things considered, including it being stacked up against other mapping solutions I've experienced, I can't be more pleased with its performance, so far.
0 Kudos
StephenBaier
Occasional Contributor
If you are adding a large number of graphics to a layer the recommended way would be to use the bulk add method public int[] addGraphics(Graphic[] graphics) rather than repeatedly calling addGraphic. If possible it is better to collect up batches of graphics and add them in one call. Internally only one thread can be adding a graphic to a layer at a time so your threads will effectively become synchronised so a large number of threads will not necessarily improve performance.

If you can provide more detail on the failures you are seeing we might be able to help further.


Thanks Colin, this helps my hundreds of thousands of data points render much faster.
0 Kudos