Update physics World in another Thread

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
AntonioModer
Party member
Posts: 202
Joined: Fri Jun 15, 2012 5:31 pm
Location: Belarus
Contact:

Update physics World in another Thread

Post by AntonioModer » Mon Aug 29, 2016 6:23 pm

Explanation:
in the main Thread we create physics World, and update his in another Thread, to increase game performance using a multi-core processor.
Because the main Thread uses maximum 35% of my 4-core processor.

This is possible to do?
Has anyone done this?
I try, but have error with "locked" World:

Code: Select all

Box2D assertion failed: m_world->IsLocked() == false
As I understand it, this error happens when we change anything in World (create new Body, ...)
Check the world:IsLocked() every time, when need do something with physics - it's not the best solution.

Update -------------------------------------------------------------------------------------------------------------------
Box2d API World have Step() function, which fully controlled world update.
I found this tutorials for pausing world:
http://box2d.org/forum/viewtopic.php?t=6049
http://www.iforce2d.net/b2dtut/worlds
Found multithreading C++ Box2d library: https://github.com/skitzoid/Box2D-MT
Maybe need update LOVE2d physics world API, adding step() function for manual update world?

Demo.
version 0.0.3
[FIX] error with "locked" World still be if press 'up' (body:setPosition())
version 0.0.2
Ok, physics work in Thread, but error with "locked" World still be if press 'up' (body:setPosition()), like s-ol say.
Thanks s-ol for help.
Attachments
threadPhysics.love
Demo version 0.0.3 for LOVE 0.10.1
(3.1 KiB) Downloaded 88 times
threadPhysics.love
Demo version 0.0.2 for LOVE 0.10.1
(2.97 KiB) Downloaded 84 times
Last edited by AntonioModer on Sun Sep 04, 2016 2:07 pm, edited 14 times in total.

User avatar
Positive07
Party member
Posts: 1006
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Update physics World in another Thread

Post by Positive07 » Tue Aug 30, 2016 4:25 am

You can't send userdata nor nested tables through thread channels, unless somehow you used LuaJIT FFI and got the pointer and did some horrible hackish things.

Creating a physic world in a thread should be entirely possible, and sending basic commands from one to the other should be possible too, but you can't share it, that is you can't work with the same world in both threads

You should also find a way to update it with the right dt, or else your threads may get out of sync at some point
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(Github.com/Positive07)

User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Update physics World in another Thread

Post by raidho36 » Tue Aug 30, 2016 5:25 am

You can do it by using high resolution timer instead of provided dt.

User avatar
Positive07
Party member
Posts: 1006
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Update physics World in another Thread

Post by Positive07 » Tue Aug 30, 2016 6:31 am

Yeah that is an option, it will take more time though, the other is fixed step and interpolation, but that can get complex... The easiest is to use the last dt value, an average dt value or assume constant 60FPS
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(Github.com/Positive07)

User avatar
AntonioModer
Party member
Posts: 202
Joined: Fri Jun 15, 2012 5:31 pm
Location: Belarus
Contact:

Re: Update physics World in another Thread

Post by AntonioModer » Tue Aug 30, 2016 9:18 am

Positive07 wrote:You can't send userdata nor nested tables through thread channels
I can do it, i tested it.
I get debug print(world) from another Thread:

Code: Select all

World: 0x018d661202d0
From https://love2d.org/wiki/love.thread:
All LOVE objects (userdata) are shared among threads so you'll only have to send their references across threads.
From https://love2d.org/wiki/Channel:push:
The value of the message can be a boolean, string, number, LÖVE userdata, or a simple flat table.
Last edited by AntonioModer on Tue Aug 30, 2016 9:36 am, edited 2 times in total.

User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Update physics World in another Thread

Post by s-ol » Tue Aug 30, 2016 9:20 am

AntonioModer wrote:
Positive07 wrote:You can't send userdata nor nested tables through thread channels
I can do it, i tested it.
I get debug print(world) from another Thread:

Code: Select all

World: 0x018d661202d0
From https://love2d.org/wiki/love.thread:
All LOVE objects (userdata) are shared among threads so you'll only have to send their references across threads.
From https://love2d.org/wiki/Channel:push:
The value of the message can be a boolean, string, number, LÖVE userdata, or a simple flat table.
The problem is that checking "isLocked" is not enough, as right after you "ask" whether it is locked, the other thread may also check and then both are still attempting to do stuff at the same time.

You will need to use Channel:supply/demand to actually lock threads while working on the world.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end

User avatar
AntonioModer
Party member
Posts: 202
Joined: Fri Jun 15, 2012 5:31 pm
Location: Belarus
Contact:

Re: Update physics World in another Thread

Post by AntonioModer » Tue Aug 30, 2016 9:48 am

s-ol wrote: The problem is that checking "isLocked" is not enough, as right after you "ask" whether it is locked, the other thread may also check and then both are still attempting to do stuff at the same time.

You will need to use Channel:supply/demand to actually lock threads while working on the world.
Yes i know, but it maybe make unstable update world with jerks, this is not the right solution.
I can stop the update only when the world is completely updated in other thread.
Need to test this solution.

Box2d API World have Step() function, which fully controlled world update.
I found this tutorials for pausing world:
http://box2d.org/forum/viewtopic.php?t=6049
http://www.iforce2d.net/b2dtut/worlds

Maybe need update LOVE2d physics world API, adding step() function for manual update world?

Today i will make demo for testing solutions and releases here.

User avatar
pgimeno
Party member
Posts: 2338
Joined: Sun Oct 18, 2015 2:58 pm

Re: Update physics World in another Thread

Post by pgimeno » Tue Aug 30, 2016 6:48 pm

Thread synchronization is an old problem. The solution is to use mutexes.

Slime has a mutex library:
https://github.com/slime73/love-mutex


User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Update physics World in another Thread

Post by raidho36 » Sun Sep 04, 2016 2:27 pm

A better solution to synchronization is to split up processing so that threads don't have to interact. You'd need a good mapping function though, such that can estimate how much time it'd take to compute the whole thing. But other than that, the only things that need to be aware of one another are interacting objects, i.e. the ones that are colliding and the ones that are held together via joints, so it's fairly simple.

Post Reply

Who is online

Users browsing this forum: No registered users and 49 guests