ID:2092281
 
Ok so I'm not exactly sure as to what's going on here. I have a whole lot of particles running. This is the code
                rfx()
var/fir1 = 10
for(var/fi = 1 to fir1)
var/obj/fx/flame_thrower/f
if(flame_thrower_fx_grave2.len) {f = flame_thrower_fx_grave2[1];flame_thrower_fx_grave2 -= f}
else
f = new()

f.start()

//var/list/fIl = list('fire_s_1.dmi','fire_s_2.dmi','fire_s_3.dmi','fire_s_4.dmi','fire_s_5.dmi')
var/fIr = rand(1,5)
if(fIr == 1){f.icon = 'fire_s_1.dmi'};if(fIr == 2){f.icon = 'fire_s_2.dmi'};if(fIr == 3){f.icon = 'fire_s_3.dmi'};if(fIr == 4){f.icon = 'fire_s_4.dmi'};if(fIr == 5){f.icon = 'fire_s_5.dmi'}

//var/icon/fI = new(fIl[fIr])

f.icon_state = pick(icon_states(f.icon))

if(fIr == 4) f.icon_state = "[rand(5,8)]"

var/rr = 1

f.color = pick(rgb(255,213/(rand(10,30)/10),75/(rand(10,30)/10)),rgb(255,166/(rand(10,30)/10),57/(rand(10,30)/10)),rgb(227,123/(rand(10,30)/10),85/(rand(10,30)/10)),rgb(213,103/(rand(10,30)/10),62/(rand(10,30)/10)),rgb(188,80/(rand(10,30)/10),40/(rand(10,30)/10)))
f.alpha = 100
f.layer = layer+10
f.plane = plane
f.loc = loc
f.pixel_x = 0;f.pixel_y = 0
f.pixel_x += step_x-32 + rand(-rr,rr)
f.pixel_y += step_y+pixel_y + rand(-rr,rr)

if(fIr != 2 && fIr != 5)
f.pixel_x += 16
f.pixel_y -= 16
if(fIr == 4)
f.pixel_x -= 16
f.pixel_y -= 16

var/fc = pick(rgb(153,65,33),rgb(104,44,22),rgb(69,24,21))

var/obj/g
if(flame_thrower_fx_grave2_glow.len) {g = flame_thrower_fx_grave2_glow[1];flame_thrower_fx_grave2_glow -= g}
else
g = new()

f.g_obj = g

g.icon = 'fire_g_glow.dmi'
g.blend_mode = BLEND_ADD
g.pixel_x = 0;g.pixel_y = 0
g.pixel_x -= 16
g.pixel_y -= 16
g.transform = matrix()*1

g.layer = f.layer
g.plane = f.plane
//g.alpha = 100

if(fIr != 2 && fIr != 5)
g.pixel_x -= 16
g.pixel_y += 16
if(fIr == 4)
g.pixel_x += 16
g.pixel_y += 16

f.underlays += g

f.transform = turn(matrix()*(size*0.5),rand(0,360))

var/aa = 0//f.alpha/2

var/tt = 5//rand(3,5)

animate(f,time=tt,alpha = aa,transform = turn(matrix()*0.1,rand(0,360)),color=fc,easing=SINE_EASING)
//spawn(tt)

//if(fi > 1)
// f.deleter(0)
//else
//f.loc = null
f.deleter(tt)


Mind the mess and the comments. The main problem here, is that the code runs on almost no cpu, when I set f.loc = null, right before f.deleter(tt), which you can see is currently commented out. This places me to believe the renderer is what's choking up here. This is running on an update loop. With f.loc = null disabled, the particles cause a complete slowdown running at 30%~+ cpu and tick_usage.
f.loc = null is probably deleting your particles outright, not even giving them a chance to render, so the only overhead is the appearance churn and object creation/deletion churn. But left on the map, they'll definitely render.

How many of these particles are there?

The rendering code for each particle will do the following things that all use the CPU:

- The obj will have to generate an icon or set of icons, which
- checks the current state of the animation and interpolates, and
- has to build the icon based on the interpolated appearance.
- The resulting icons have to be put into the finalized MapIcon format.
- The resulting icons get sorted.

Rendering will use some CPU time, but I imagine the bulk of it will come in the earlier routines, with interpolation and sorting possibly taking the most time. Matrix interpolation in particular is likely to take a little bit of time for each obj, so a whole crapload of those particles could end up being a drag. (Linear matrix interpolation is faster, but it doesn't handle rotation correctly. However in a particle system I have doubts that you need to worry about perfection, and could use that as a shortcut.)
I tried disabling all transforms and animates and it still behaves the same with no change to cpu. I'm using a graveyard for the particles and placing them back into the graveyard list before setting their loc to null. I debugged to make sure the graveyard is behaving correctly.

Assigning no icon to the particles causes the CPU to remain the same as well. CPU is 30%~

Assigning no icon and disabling transforms causes the CPU to remain as well. CPU is 30%~

Disabling obj/g entirely (which also has it's own graveyard) lowers the CPU by about 10%~
But how many particles are we talking about, here?

I'm actually moving this out of Bug Reports because it sounds like at worst this is an area for future improvement, but not actually a bug.
In response to Lummox JR
Lummox JR wrote:
But how many particles are we talking about, here?

I'm actually moving this out of Bug Reports because it sounds like at worst this is an area for future improvement, but not actually a bug.

10 particles per 0.3 tick.
Particles last 5 ticks.

Roughly 166 particles active at once.
166 particles doesn't seem like a lot. Although I believe you're going with a higher FPS, and that probably factors in here.

Do you by any chance have a simple demo of this that I can take a look at? I'm curious if there's any insight I can draw from profiling that might be useful.
Out of curiosity, are you using Move() during the lifetime of these particles?

What might be happening is a lot of particles whose bounding areas are in close proximity to one another jostling about calling Entered()/Exited()/etc. calls.

There was a thread a few years back that showed that bunched up physical particles absolutely murdered DM because all objects in DM are inherently physical and therefore interact by default with bounds-based functions.
Oh dang, that could be it. I still want to find a way to improve on the Move() behavior.
Perhaps we could include a flag/var to make them ignore things like bounds/entered/etc as well?

Basically a way to make any mob/obj/etc psuedo-visual only?
http://www.byond.com/forum/?post=1813265

Oh man, it's like I'm on that spice. Prescience. Say hello to the Ter gom jabbar, LummoxJR.
They don't use Move() or entered or exited. I'll try to set up a demo.
I'm seeing memory slowly rising. Possible leak?
I don't think so. Even so it shouldn't jump to 30% so soon.
I'm not exactly sure how the profiler works (I understand the general idea of it). I found an "Average" check box and ticking that kept the numbers constant and low. I'm not sure if that means there is no leak or what but yea.
On my end I see it jumping to 50%-60% aswell
I'm proceeding from the assumption that this isn't a proc overhead thing, so I'll run a regular profiler over it (after giving it a test myself) and see what's what.
Dreamseeker ended up crashing at 1.7gb after I let it run at length.

Seems like a small memory leak, regardless as to the cpu issues.
In response to Bravo1
Bravo1 wrote:
Dreamseeker ended up crashing at 1.7gb after I let it run at length.

Seems like a small memory leak, regardless as to the cpu issues.

Hm, I'll see what I can fix.
I'm thinking it may be an internal BYOND issue, if there's nothing obvious that pops out at you.
Page: 1 2