Wednesday, June 6, 2007

Editing and threading

Recently I've implemented threading in Step. This is (still) not parallel computation, but doing all calculations in one dedicated thread to keep GUI responsive and allow the user to abort calculations at any time.

In Step the user can edit the scene while simulation is running but this can't be done in the middle of timestep. So I need to use mutex to serialize access to the scene: the mutex is locked by calculating thread while performing timestep and by GUI thread while altering objects. The problem arises when calculation of one timestep becomes too long (for example if user sets too low tolerance): if GUI tries to lock the mutex it becomes unresponsive till the end of the timestep and the user can't abort the calculation !

The obvious solution is to abort current timestep as soon as the user starts altering the scene and restart it later. But this can slow down the simulation and make it not smooth. My solution is to first try locking with timeout and abort the timestep only if locking fails:

// Try to lock but do not wait mode than one frame
if(!mutex->tryLock(1000/_simulationFps)) {
abortCurrentFrame();
mutex->lock();
}

With such approach simulation will be slowed down only if it is already slow (i.e. when simulation of one frame simulation takes longer then 1/FPS). In the other case simulation will proceed smoothly and user actions will be delayed only slightly.

2 comments:

Anonymous said...

Hmm, I don't even see the need to do locking at all here.

If I understand it correctly, you have one thread who can write and the calculating thread never writes this 'aborted' state, it just reads.

If that is the case; then you don't need locking.

Thomas

Vladimir Kuznetsov said...

Mutex is used not to protect 'aborted' variable, but to protect the world state. Calculating threads does not aborts immediately after setting 'abort' variable and GUI thread needs to wait for it. I've implemented this waiting using mutex. May be there are better ways...