Is there a way to run a loop in a second 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.
Post Reply
psemo
Prole
Posts: 6
Joined: Sun Mar 05, 2023 11:42 am

Is there a way to run a loop in a second thread?

Post by psemo »

I really googled a lot and couldn't find a sensible way to do this

I want the below code to work every frame except "local particles = ..."

Code: Select all

local ParticleManager = [[
    local Particles = ...
    local dt = love.timer.getDelta()

    for pIndex, Particle in pairs(Particles)
    do
        if Particle.timer > Particle.dissappearTime then

            table.remove(Particles, pIndex)
            Particle = nil
        else
            Particle.PosX = Particle.PosX + (Particle.directionX * Particle.speed * (1 - (Particle.timer / Particle.dissappearTime))) * dt
            Particle.PosY = Particle.PosY + (Particle.directionY * Particle.speed * (1 - (Particle.timer / Particle.dissappearTime))) * dt
            Particle.timer = Particle.timer + dt
        end
    end
]]
this code below starts the code upper.

Code: Select all

function CreateThread(Particles)

    -- Creates a new thread and start it
    local Manager = love.thread.newThread(ParticleManager)
    Manager:start(Particles)--gotta run this every frame and pass the table of particles
    --And this needs dt    
end
I don't know how to call from the main too
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Re: Is there a way to run a loop in a second thread?

Post by Bigfoot71 »

I don't really understand the problem you are facing but löve2d already has a particle system: https://love2d.org/wiki/ParticleSystem

And something that has nothing to do but your loop may cause errors, if you iterate an array in which you are removing elements you have to iterate upside down, ie:

Code: Select all

for i = #tbl, 1, -1 do
    table.remove(tbl, i)
end
My avatar code for the curious :D V1, V2, V3.
psemo
Prole
Posts: 6
Joined: Sun Mar 05, 2023 11:42 am

Re: Is there a way to run a loop in a second thread?

Post by psemo »

Bigfoot71 wrote: Sun Mar 05, 2023 2:05 pm I don't really understand the problem you are facing but löve2d already has a particle system: https://love2d.org/wiki/ParticleSystem

And something that has nothing to do but your loop may cause errors, if you iterate an array in which you are removing elements you have to iterate upside down, ie:

Code: Select all

for i = #tbl, 1, -1 do
    table.remove(tbl, i)
end
I know that but I wanna use the one I created myself. I just wanna run it on my second thread every frame. How can I do that?
Andlac028
Party member
Posts: 174
Joined: Fri Dec 14, 2018 2:27 pm
Location: Slovakia

Re: Is there a way to run a loop in a second thread?

Post by Andlac028 »

Create thread at the game start and send partickes to it and use channel:supply to push data to main thread. Also meassure time since last supply (or alternatively, just use :push and take delta time from another channel where you push it from main thread).

In main thread, pop particles positions and do the work. But always store last particles positions, in case, the particles thread would be slow and wouldn’t push particles positions yet to main thread.

(not tested, let me know, if you need example code, or something)

Also apart from removing elements from array and using pairs, if you have numerical indexes, use ipairs, as it can be faster.

And one microoptimalization: division is a lot slower than multiplication. If you divide frequently (something/value) with same value, consider using precomputed reciprocal value (rValue=1/value) and then do multiplication instead (something*rValue)

And also you compite timer/disappertime twice (once for x and once for y), consider saving frequently computed value in temp variable instead of compiting them more times.
kuinashi101
Prole
Posts: 7
Joined: Tue Feb 21, 2023 9:47 am

Re: Is there a way to run a loop in a second thread?

Post by kuinashi101 »

I'm making an 2d-array based particle system these days which could do more fancy things on the particles, like tween scale and color, wavy movement, apply shaders..etc.

My process flow is pre-spawn particle data for say 5000 times and store then in a table 'masterPool'. declare and iterate another table named 'pSleep' which stores numbers as index from 1 to 5000. each time you spawn particles, you get and remove the number from last index of 'pSleep' and store it to another table 'pActive'. now you can deal with activated particles by taking numbers in 'pActive' as reference to 'masterPool'. pass them to the thread. set the pushed back data to original ones for draw().

Suggestion is using frame call instead of calculating delta time and it's not necessary to update it each frame. you just have to run the thread again after the it is completed, so that will truly take advantage of threading which is doing stuffs by occupy lesser resource from main thread. the influence of a slightly latency of updating particles' graphic should be tolerable.
User avatar
Sasha264
Party member
Posts: 131
Joined: Mon Sep 08, 2014 7:57 am

Re: Is there a way to run a loop in a second thread?

Post by Sasha264 »

One day I tried to do my own particle system that way, with the threads. But no luck, because for me necessity to copy (push / supply or whatever) data from separate thread turned out to be a bottleneck. And there is not so much calculation for every particle every frame. Basically its just x = x + v * dt with some similar additions, so, I got no real benefit from running it in separate thread.

Maybe there is a way to make some benefit with love 2d byte object that can be shared between threads love.data.newByteData, but I newer did that.

Instead now I am using vertex shaders and instanced drawings for my own particles. So, in separate vertex buffer I store all particle params: position, velocity, color, angle, fade, sprite index, etc... and in vertex shader gpu calculates actual particle position and appearance based on that. And on cpu side each particle consumes only one-time calls of Mesh:setVertexAttribute, and after that particle is all set, and for consequent frames cpu do literally nothing for that particle, while it keeps moving, fading, rotating... and do what it meant to do.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest