Multithread Development with Open Inventor

Reference

There are many books available on multithreaded programming and we don't claim these are the only good ones, but we can recommend:
  • "Programming with POSIX Threads", Butenhof, Addison-Wesley.
  • "Win32 Multithreaded Programming", Cohen & Woodring, O'Reilly Press.

System Dependencies

On Windows:

Open Inventor uses native Win32 thread and thread control functions. Windows itself is multithreaded and uses these functions, so no additional libraries need to be linked. Open Inventor applications should already be using the "MultiThreaded DLL" version of the C/C++ runtime library (msvcrt and msvcrtd).

On UNIX/Linux:

There are several specific issues, including:

  • On most systems, you must explicitly link your program with the POSIX threads library. For example, add "-lpthreads" to your Make file.

  • On most systems, you must call XThreadInit before making any other X Windows calls (including Xt, Motif, GLX, etc). SoXt::threadInit will make this call automatically, but if you don't use SoXt, you must call it yourself.

Performance

Note that the performance of your application will not automatically improve by using multithreaded Open Inventor. The capability to use multiple threads allows an application to potentially improve performance, even (but not necessarily) on a single processor machine. This is because one thread may become blocked waiting for a resource, such as a disk access, and because one thread may not be able to keep the graphics pipe busy.
In fact an unmodified program might experience slightly lower performance with multithread support enabled. This is because there is overhead for locking and unlocking mutexes while traversing or modifying the scene graph. For this reason, multithread support is not enabled by default. If you don't need multithread support, don't enable it (continue to use the classic SoXt::init or SoDB::init).

When multithread support is enabled, it is even more important to use the usual optimization techniques for Open Inventor. For example, one of the benefits of render caching is that it avoids the overhead of scene graph traversal for the cached subgraph. In the multithread case, render caching also avoids the overhead of locking and unlocking mutexes in the cached subgraph.At the same time, there is some additional overhead in using render caches (checking if possible to use a render cache and if possible to build a render cache).
So ideally render caches should contain as large a subgraph as possible (as opposed to caching individual Separators at the "leaf" nodes of the scene graph). Also try to identify cases where caching will never be possible, for example Separators above a camera or 2D text, and make Open Inventor aware of this by disabling render caching at those nodes. There is no caching overhead for a node where caching is explicitly disabled.

There is additional overhead for Open Inventor "notification". It's always a good idea to minimize this overhead, but even more important when multithread support is enabled. By default notification happens every time a field or child list is modified. If a scene graph update requires modification of multiple fields (or child lists), it is usually unnecessary and inefficient to do notification on every individual change. It is better to disable notification on the affected nodes, make the changes, then trigger notification explicitly. You can do this by calling touch() on a node that has notification enabled. NOTE: Disabling notification may not be appropriate if the node has fields connected to other fields and/or engines.

Multithread Programming with Open Inventor

Be sure to read the "System Dependencies" section for notes about compiling and linking multithread programs.

Open Inventor's multithread support is designed to work with different application architectures and with other software tools.

How can I use threads with Open Inventor?

There are many possibilities. Here are some ideas to get you started:

  1. One thread for rendering, another thread for computation
  2. Multiple threads rendering different scene graphs
  3. Multiple threads rendering the same scene graph