Collision module and performance

About Monkey 2 Forums Monkey 2 Development Collision module and performance

This topic contains 43 replies, has 8 voices, and was last updated by  peterigz 2 years, 8 months ago.

Viewing 15 posts - 16 through 30 (of 44 total)
  • Author
    Posts
  • #1119

    peterigz
    Participant

    I like the sound of the incremental garbage collection, hopefully it eliminates the odd stutter that bmx was prone to.

    Why is MX2 so much faster? Is it just that c++ compilers have come a long way and BMX compiler hasn’t updated to take advantage of any additional CPU trickery?

    Next think I would suggest looking into is perhaps using a struct for vector2d instead of a class.

    Yeah, that’s exactly where I was going next, I was looking at possibly using the structs already there in the std/geom module but I’ll probably just convert my own as they have a couple of extra methods I use (assuming they’ll work with structs).

    #1120

    abakobo
    Participant

    This article can be interesting in those CPU consumption thoughts… though tests are made in C# so it’s maybe not comparable to C++

    http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.308.7825&rep=rep1&type=pdf

    One astonishing thing is that static is slower than dynamic in some situation and that class looks faster than struct! (see Table 1)

    #1121

    peterigz
    Participant

    New update just pushed. Getting silly now, I’ve converted tlVector2 to a struct, result:

    Collisions done in 1 second: 5138002

    Will do matrix next, but that won’t make much difference as they’re not used to detect collisions but obviously might help with the tform stuff. I’ll have to check if there’s anything else I can convert to struct! The quadtree sample has dropped to 6-7 ms now which is also nice to see!

    @abakobo: Thanks, i find optimisation very interesting. Looks like Structs in MX2 will provide some nice advantages in this case 🙂

    #1122

    wiebow
    Participant

    Interesting. It would be really nice if we can compile some guidelines when structs are preferred over classes and when not. I’m struggling with that kind of stuff.

    #1123

    dmaz
    Participant

    now this kind of news is pretty awesome! especially if we can show people still on bmx that MX2 is much faster and smoother.

    #1124

    dmaz
    Participant

    that pdf is quite interesting… especially the part that dynamic (non anonymous) methods are generally 50% faster than static. too bad they don’t explain or speculate why that is.

    #1125

    nobuyuki
    Participant

    wiebow:  I’ve used this as my general rule of thumb… If you tried to avoid using a class type in Monkey1 when targeting Android because it would trip the GC (convenience classes like vectors, shapes, colors, custom strings etc), then that’s probably something that could benefit from having some of it changed into using Structs instead because of the way it’s allocated.

    There’s probably more advantages…

    #1127

    Danilo
    Participant

    It would be really nice if we can compile some guidelines when structs are preferred over classes and when not. I’m struggling with that kind of stuff.

    For flexibility, you can duplicate everything. CPoint/SPoint, etc.

    Sometimes you want to use a specific type as Struct on stack,
    other times as garbage-collected Class-Pointer.

    #1128

    Mark Sibly
    Keymaster

    Why is MX2 so much faster? Is it just that c++ compilers have come a long way and BMX compiler hasn’t updated to take advantage of any additional CPU trickery?

    More or less. C++ has been under development for much longer than bmx, and has had many extremely clever people working on it! It would have been faster than bmx even back when bmx first came out…

    After looking through a bunch of ASM the other day, I’d guess the biggest factor is function inlining. C++ does this amazing well, to the point where trying to read ‘-O3’ generated code is almost impossible! Even stuff like internal string and array constructors are inlined – that silly cstring->bbstring conversion was inlined too (shouldn’t be really – that’s going a bit too far), which initially made the ASM code look like complete garbage.

    And mx2 can help out even more here. Currently, all generated code ends up in the cpp file which means it can’t be inlined so only ‘system’ code is currently inlined. But eventually, I’ll be moving some of the generated code to the .h file so it can be inlined too.

    > This article can be interesting in those CPU consumption thoughts… though tests are made in C# so it’s maybe not comparable to C++

    That article looks incredibly dodgy to me. Without seeing the actual code they’re testing, there’s no way of telling it’s not just the authors doing some stupid. Some of the results sound highly suspect to me, but then again, I don’t know much about the inner workings of C#. Not much of it would apply to c++ though.

    It would be really nice if we can compile some guidelines when structs are preferred over classes and when not. I’m struggling with that kind of stuff.

    Google for more advice, but I generally only use them for simple, often ‘mathsy’  types that are more or less immutable (ie: once they’re created, their fields don’t change). Things like vectors, matrices, complex numbers etc. are all pretty good candidates for structification.

    Structs also have some limitations that will help you decide…

    • They can’t be extended.
    • They can’t have virtual methods.
    • They are copied ‘by value’ so can be expensive to pass to functions or to assign to (although inling will ultimately help here).
    • They can’t (easily) be referred to indirectly.

    The last can be solved in a number of ways – you can create a ‘pointer’ class that contains a struct and pass that around, effectively passing a ‘reference’ to a struct around. But I think if you end up having to do this, you’re probably misusing struct and should just use a class instead.

    You can also create an array of structs and use an int index as the ‘reference’, giving you a form of indirection.

    You can also use Varptr – nasty/dangerous!

    The builtin types like int, float, string are effectively structs, so you have much the same choices for indirection as you do for the builtin types.

    #1129

    peterigz
    Participant

    The immutable part threw me a little bit because obviously vectors are going to change if you use them to store coordinates for game objects and whatnot, but I guess that the majority of the time the vectors you create will be temporary and only used to do calculations before being discarded straight away, so overall a struct works out a lot better.

    So if in the majority of cases the data will not change in its lifetime then a struct is probably a good idea, but for objects that will persist for a while and contain data that changes overtime then classes are the way to go. And of course if you need to extend/inherit then you don’t have a choice but use classes.

    I was looking at my particle engine and wondering where I can use structs, but I don’t think there’s many other places other then the vectors/matrices (which will still make a big difference). I thought about the particles themselves being structs but they are basically objects that will persist for a while and have plenty of data that changes overtime. Plus they have hierarchy and such.

    I did make the tlCollisionResult a struct though as it’s basically filled with the results of the collision and then discarded once used so it made sense there. That got me another 100k collisions per second so up to 5.2mill now, I think that’ll do for now! 😉

    #1131

    Mark Sibly
    Keymaster

    > The immutable part threw me a little bit because obviously vectors are going to change if you use them to store coordinates for game objects and whatnot,

    Terms like immutable, const etc aren’t very clearly defined in general, and the definitions of lots of stuff changes from language to language, so yes, that statement was probably a bit confusing!

    By immutable, I mean the ‘value’ of something doesn’t change once it’s constructed – and in the case of structs, by ‘value’ I mean the value of any of it’s fields. So a ‘New Vec2(10,20)’ will always have x=10 and y=20. Therefore, any methods will not modify ‘self’ – if necessary, they will return a ‘New Vec2’ instead.

    But a variable is not a value – it contains a value – so you can do something like ‘p=p+v’  where the types involved are all immutable. In fact, ints, floats, strings etc are all effectively immutable…

    You don’t have to make structs immutable in mx2 of course, but IMO if something ‘looks’ like it could be implemented as immutable, it’s a possible candidate for structification.

    Probably just confused things even more!

    I was looking at my particle engine and wondering where I can use structs,

    Depending on how your particles work, there’s actually a really good use case for structs, and that’s to use a circular queue.

    This only works if your particles have a ‘fixed’ timeout, in which case you’ll always be adding N particles to the front of the queue and removing N particles from the end.

    In this case a ‘particle buffer’ can be implemented using a simple array of structs, with ‘put’ and ‘get’ pointers (ie: indicies).

    You can use canvas.DrawPrimtives to draw the particles in one ‘hit’ too. You’ll have to do this twice, as the buffer will be ‘wrapped around’.

    Did this myself in c++ a while back on the Ouya and got 30,000 odd particles flying around at 60FPS – not bad for the Ouya!

    #1155

    peterigz
    Participant

    That’s interesting, so if I have a method in a struct it shouldn’t modify the field values I should create a new struct with updated values and return that? It’s making more sense now, I still have it in my head that creating things puts load on the GC but of course that doesn’t happen with structs because they’re on the stack. It seems kind of the other way round with structs in that it’s cheaper to create and let them go rather then change their values.

    Thanks for the info on particles I’ll look into that 🙂

    #1158

    abakobo
    Participant

    That article looks incredibly dodgy to me. Without seeing the actual code they’re testing, there’s no way of telling it’s not just the authors doing some stupid. Some of the results sound highly suspect to me, but then again, I don’t know much about the inner workings of C#. Not much of it would apply to c++ though.

    lol!

    That’s true the guy seems to have had a hard time finishing his paper. And I was astonished by their results.

    This one has probably done a better job.. but then you have to read. Probably accessible to computer sciences addicts only.(not me, I tend to be on the end-user side)

    http://www.ru.nl/publish/pages/769526/z_stein_keijzers_thesis_-_final.pdf

    #1165

    Mark Sibly
    Keymaster

    That’s interesting, so if I have a method in a struct it shouldn’t modify the field values I should create a new struct with updated values and return that?

    It’s up to you! I was really just trying to think up a good example for ‘when should something be a struct’, and I think if a type can be implemented as an immutable type it’s possibly a good candidate. On the other hand, if a field of a type needs to be modified independently in some way, maybe it’s not a good candidate. It’s sounding like a crapper example each time I explain it…

    I do prefer to make as much stuff as immutable as possible myself though. Having methods return a ‘new’ value is more flexible and safer than methods that modify ‘Self’ IMO, as you don’t have to think about what a method or operator might be modifying (ie: nothing!), but that’s more a stylistic thing than a speed thing. But it’s also true that structs do make immutable types easier/more efficient to write, so rock on structs!

    And with immutable types and operator loading, math can look completely ‘natural’, eg:

    e->Position=matrix * pos * u.Cross( v ) + offset…etc

    …and just like int/float math, you don’t have to worried about anything be inadvertantly modified along the way.

    There likely *is* some cost overhead for this amount of simplicity/flexibility, but c++ deals incredibly well with most of it, esp. with structs, so IMO it’s worth it.

    #1166

    peterigz
    Participant

    I think I’ll aim towards the immutable approach as that seems to make more sense to me, and it helps to make structs stand out more in my head. I’m happy that just using them as they are is enough for a big speed boost 🙂

    I looked at circular queues for particles; they look interesting but unfortunately my particles are quite complex with variable lifetimes, so will just have to use a normal stack I guess.

Viewing 15 posts - 16 through 30 (of 44 total)

You must be logged in to reply to this topic.