Multithreading Minie

In addition to the multithreaded dynamics world, Bullet also provides a multithreaded collision dispatcher. When I used it, however, I encountered a variety of strange crashes. If the dispatcher is the key to MT performance, it’s out of reach for now.

One more thing to try before giving up on mulithreading: tune the grain sizes in the dynamics world.

I think I know why the MT dispatcher was crashing: its worker threads were using contact callbacks to invoke (Java) collision listeners. Disabling both contact callbacks avoided the crashes I encountered yesterday:

    gContactProcessedCallback = NULL;
    gContactStartedCallback = NULL;

The OpenMP worker threads weren’t created by the JVM. To invoke Java methods (such as the collision listeners) they used the JNIEnv struct belonging to the Physics Thread. Multiple threads sharing a single JNIEnv may have confused the JVM. Also, there may have been some thread initialization (required by the JVM) that was missing.

Not sure how useful multithreaded Minie will be if its collision listeners don’t work. A lot of apps would fail. In the tower test, for example, the BombControl fails to detect the projectile striking the bricks, so the explosion never happens and the tower doesn’t collapse. Pretty sure it would be possible to rewrite the app to use a sweep test in place of the collision listener, though…

Any opinions? Do you foresee a need for a faster version of Minie that doesn’t support collision listeners?

4 Likes

well it would be really nice to have physics MT.

But games use more threads anyway for other things, not just for physics.

Looking at future it would be nice, but myself i would no need this currently that much.(tho i use all possible cores if can, trying to leave main game thread core (it is physics too) working faster)

But still, collision listeners is like must have.

3 Likes

Is it possible to enqueue those events and publish them from a single thread over the native side?

Edit:
And by the way, is the MT dispatcher impact significant?

Edit2:
In my case, I use collision listeners. I am using Minie at the server side (no soft body) and it is independent from the client (motion is interpolated). I may also assign a specific thread on the server just for physics if I ever need it.

2 Likes

I think it’s possible, and it might even have acceptable performance. Biggest concern is that my C++ coding skills might not stretch that far…

I’ll pursue your suggestion. Thanks!

For some workloads, it is. For instance, in the tower app, about 1/3 of the physics time is spent on collision dispatch.

2 Likes

I do not have experience with JNI, but probably there should be a solution for multi-threading via JNI without needing to enqueue.

See here for an example:

It uses something called AttachCurrentThread() & DetachCurrentThread()

But not sure if it will block the worker threads or not and how it may affect the performance.

2 Likes

That is POSIX Threads or PThreads for short, Pthreads may be a good option for Java as it exists independently from a language, as well as a parallel execution model, but it would need to be rewritten for windows systems if implementation code of pthreads-win32(runs on top of Win32Api) is different from pthread of Unix based systems, its a very low level api but can guarantee good performance.

i think if OpenMP doesn’t do the job, then pthreads is worth trying.

(I have used POSIX threads (pthread_t) on C before to populate some threads asynchronously(Parallelism), also it supports mutex events, and thread join/tryToJoin…but haven’t shared that with JNI, Full docs on IBM).
https://www.ibm.com/docs/en/i/7.2?topic=category-pthread-apis

My Test files repo :

1 Like

The solution from Stack Overflow involves a mutex that prevents a worker thread from invoking the Java method while another is doing so. That’s likely to have a performance impact, but less impact than queuing would’ve had.

Minie was already invoking AttachCurrentThread(). Simply adding a mutex seems to resolve the “strange crashes” I reported on Tuesday.

1 Like

I guess that depends on what you mean by performance.

For example, a C++ thread-safe queue that Java reads through JNI should be fast enough (better than a stop-the-world mutex I guess) but would have different memory performance.

…but I’m also spoiled by Java’s thread-safe data structures and maybe good concurrent queues are not so common in C++ land.

1 Like

Hmm…I was expecting otherwise! :thinking:

Version 12 of the native libraries has been released: Release 12.0.0 · stephengold/Libbulletjme · GitHub

  • New performance gains by skipping contact callbacks when there’s no listener on the Java side. These gains are application-dependent but apply across all platforms, with or without multithreading.
  • Testing on the Windows 10 laptop (with CPU clock at top speed) showed a 10% speedup due to MT. Performance peaked at 2 worker threads. When downclocked by the power saver, speedup rose to 46% (from a lower baseline).
  • Additional worker threads seemed to reduce performance slightly, but the differences could’ve been noise. In the release, the number of worker threads is fixed at 2.
  • Profiling showed that the “updateAabbs” phase is a serious performance bottleneck for multithreading. It consumes about 19% of the physics time in non-MT builds, and it’s not parallelized in Bullet. I wrote a parallel version, but it performed worse than the Bullet version. The bottleneck, I believe, was the broadphase pair cache update, which was mutexed.
  • Multithreaded dispatch didn’t provide any performance benefit for the test workload, so I didn’t enable it in the release.

Getting ready to wrap this up with the release of Minie v4.3.0. Multithreading will be disabled by default, but there’ll be a new build qualifier (similar to “+big3”) to enable it.

9 Likes

Version 4.3.0 of Minie has been released. It’s available from MavenCentral and GitHub.

Minie v4.3 boosts performance, fixes a few bugs, and adds support for multithreaded physics spaces. For more details, see the release page at GitHub. For even more details, see the release log.

The v4.3.0 release consists of 7 libraries:

  1. Minie-4.3.0
  2. Minie-4.3.0+bare (compact library without ANY native libraries, for projects that provide their own natives)
  3. Minie-4.3.0+big3 (compact library that supports ONLY Linux64, MacOSX64, and Windows64 platforms)
  4. Minie-4.3.0+debug
  5. Minie-4.3.0+debugdp
  6. Minie-4.3.0+dp
  7. Minie-4.3.0+mt (for multithreaded physics spaces, only for Linux64 and Windows64 platforms)

Key to library naming:

  • Libraries with “+debug” in their names include native assertions and support native debugging.
  • Libraries with “dp” in their names use double-precision arithmetic.
11 Likes