Multithreaded physics

Multithreaded physics

Trying to run the no-charge version (5.5.0) of physics using multithreaded, all threads stuck trying to acquire a semaphore after calling stepProcessMt. I followed or at least tried to follow the user guide's examples "6.2 Basic threading and synchronization" and "6.4 Fine-grained multithreading".

7 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hi MADoarodrig,

Do the demos run for you or is it your own integration that's not working?

Daniel

The demos run fine. We were using version 5.1.0 of Havok in our project and it worked fine. After integrating version 5.5.0, Havok threads don't return after calling stepProcessMt. Everything works in single threaded mode. The demos (at least the multithreaded demos) use the hkpMultithreadingUtil and we're using something similar to what is presented in the section 6.4 "Fine-grained multithreading" of the user guide. According to the user guide that came with version 5.5.0, hkpMultithreadingUtil will be deprecated in version 6.0. Were there significant changes between versions in the multithreading section that we should be aware of in order to run Havok in multithreaded mode?

-Omar

Hi Omar,

Could you see if disabling multithreaded processing of TOIs fixes this problem? This is done by setting hkpWorldCinfo::m_processToisMultithreaded to false.

Also, would it be possible to get callstacks for all your threads when you get the hang?

Thanks,
Daniel

Thanks Daniel,

I set hkpWorldCinfo::m_processToisMultithreaded to false and it works now. Let me know if the call stack would be helpful and I can remove the one line of code I added and post the call stack.

-Omar

Hi Omar,

Performance
should be better with m_processToisMultithreaded enabled, if you can make that
work. Good to know where the problem is though and that we have a workaround
in case you cant get this to work.

Heres some
explanation of how 5.5 with multithreaded TOIs disabled (which is the same as 5.1) handles multithreading, and how
thats different to 5.5 with multithreaded TOIs enabled.

// Step multithreaded simulation (5.5 - multithreaded TOIs
disabled/5.1)
{

// Initialize
multithreaded step by priming physics job queue with start jobs. These
jobs

// will be
taken off of the job queue by worker threads when we release them. The
jobs

// will also
produce other jobs that the worker threads will operate on.

m_world->stepBeginSt( deltaTime );

// Release
worker threads (see worker thread function below)

m_physicsWorkerThreadSemaphore.release( m_numWorkerThreads );

// Use main
thread to process jobs on job queue in addition to the worker threads we
already

//
started. This method will return when the job queue is empty.
Eventually the queue will

// become
empty and this method will return.

m_world->stepProcessMt( HK_TOKEN_PRIMARY );

// At this
point there are no longer any jobs to process so we want to acquire all worker
threads.

// This will
free them up to do other tasks. We should do this because we don't need
the worker

// threads for
TOI solving in hk510.
&nb
sp; for( int i = 0; i < m_numWorkerThreads; ++i )

{

m_physicsWorkerThreadSemaphore.aquire();

}

// Finally
process TOIs and finish the world step in the main thread. This is single
threaded.
m_world->stepEndSt();

}

// Worker thread (5.5 - both multithreaded TOIs enabled or
disabled/5.1)
{

while( true )

{

// Block the physics worker
thread from processing until the main thread tells us to start.
data.m_physicsWorkerThreadSemaphore.aquire();

// After the main thread
releases the worker thread process until there are non-longer any

// jobs on the queue.
m_world->stepProcessMt(
HK_TOKEN_SECONDARY );

// After we finish stepping loop
back to the top and block until the main thread tells us

// to start again.
continue;

}

}

Havok 5.5
with multithreaded TOI
s enabled is a little different to 5.5 with multithreaded
TOIs disabled or 5.1.

// Step multithreaded simulation (5.5 - multithreaded TOIs
enabled)
{

// Initialize
multithreaded step by priming physics job queue with start jobs. These
jobs

// will be
taken off of the job queue by worker threads when we release them. The
jobs

// will also
produce other jobs that the worker threads will operate on.
m_world->stepBeginSt( deltaTime );

// Release
worker threads (see worker thread function above)
m_physicsWorkerThreadSemaphore.release( m_numWorkerThreads );

// Use main
thread to process jobs on job queue in addition to the worker threads we already

//
started. This method will return when the job queue is empty.
Eventually the queue will

// become
empty and this method will return.
m_world->stepProcessMt(
HK_TOKEN_PRIMARY );

// What is
different here, with multithreaded TOIs enabled, is that the hkJobQueue uses
the m_cpuWaitSemaphore

// to hold
onto worker threads until m_world->stepEndSt is called. This is
required because

// TOI
processing may add collision detection jobs to the job queue. If they are
added there

// then the
worker threads take them off and process them as needed. So the
difference between

// the two
methods is t
hat we should not acquire the worker threads until the job queue is
completely

// finished
with them. Effectively the change is simple: acquire the worker threads
after the

//
m_world->stepEndSt call.

// Process
TOIs and finish the world step in the main thread. If multithreaded TOIs
are enabled

// collision
detection jobs will be added to job queue and worker threads will take them off

// and
process them.
m_world->stepEndSt();

// Acquire
all worker threads
for( int i = 0; i < m_numWorkerThreads; ++i )

{

m_physicsWorkerThreadSemaphore.aquire();

}

}

Hope this helps you get
your semaphores sorted out so you can take advantage of the multithreaded TOIs.

Daniel

Adding a zipped version of an HTML file of the contents of that previous message to make it readable.

Daniel

Attachments: 

AttachmentSize
Download MultithreadedTois.zip2.57 KB

Leave a Comment

Please sign in to add a comment. Not a member? Join today