
Tue, 01/14/2020 - 02:28
Forums:
Hello,
I'm trying to concurrently display many custom AIS objects but I get crash at some point in AIS_InteractiveContext::Display() at line 491 "myObjects.Bind(theIObj, aStatus);" because this method doesn't seem to be thread-safe.
What's the correct way to run concurrent computation of the 3D graphics with AIS_InteractiveContext ?
Tue, 01/14/2020 - 04:09
The class or method should never be considered thread-safe, as long as it is not explicitly documented to be so (which is pretty unusual).
Mutex at application level should be used for concurrent access to AIS_InteractiveContext instance and calling any of it's methods.
If your AIS_InteractiveObject::Compute() is computationally intensive - try moving out presentation computation to dedicated method (which would flush result into object itself).
You may also consider improving AIS_InteractiveContext itself by adding a method displaying the list of interactive objects with (optional) multi-threaded compute, which would care about concurrent access to things like AIS_InteractiveContext::myObjects and others in scope of a single function - which would more clear, robust and efficient than trying to make the whole AIS thing thread-safe for every other method.
Wed, 01/15/2020 - 03:31
Hello Kirill,
Thanks very much for helping, what do you mean by "try moving out presentation computation to dedicated method" ?
About the second solution is there any plan to have this multi-threaded version of the AIS_InteractiveContext::Display() function ?
Wed, 01/15/2020 - 09:48
In case of displaying TopoDS_Shape, generation of triangulation takes most of the time, so that this step can be performed by application before displaying.
In case of a custom presentation - you may profile what takes most of the time and consider moving this outside of ::Compute(), so that this method will only fill presentation strutures, and not perform any expensive algorithms.
Alternatively, when custom ::Compute() does expensive algorithm on big data, the parallelization can be put directly to your ::Compute().
This will be likely less efficient than parallelization for a big number of small objects, but still can be profitable (most optimal balancing depends on data structures).
For instance, StdPrs_WFShape::Add() has IsParallel flag for computing IsoLines in parallel for different Faces in the Shape.
This is currently not within the closest plans. You may contribute to OCCT project, or consider using Open Cascade support services:
https://www.opencascade.com/content/technology-support
Thu, 01/23/2020 - 00:49
Hello Kirill,
I applied what you suggested about preparing graphics outside Compute(). It works well, this "preparation" step is done concurrently and then the Compute() function just adds the "pre-created" graphics entities to a Graphic3d_Group object.
What I found error-prone with this solution though is that anytime graphics have to be recomputed/redisplayed you have to make sure to execute first that "preparation" step before any call to eg AIS_InteractiveObject::Redisplay().
Anyway thanks for your help, it solved the problem.