Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: about performance ...  (Read 6350 times)

0 Members and 1 Guest are viewing this topic.

Breakfaster

  • Newbie
  • *
  • Posts: 6
    • View Profile
about performance ...
« on: June 02, 2015, 05:05:28 pm »
Hey Guys

first a big praise to the dev's. Great work. In the beginning i got fuzzheaded reading through all the stuff that is written about SFML, especially the "SFML is very slow"-alike rants. Finally this benchmark (http://en.sfml-dev.org/forums/index.php?topic=43.0) test is incredibly ridiculous and cheap, made me almost trash SFML and start over with SDL, but i got over that. I am confident that SFML will fit my needs, i just have to use it the right way and expect that you guys did something the right way here.

  :)

So im actually trying and measuring out a lot of things to find the way to get most performance out of SFML. Started a quick performance test with 5000 sprites per frame at first, realizing that sf::Sprites aren't made up for that. So what now? I will need to throw _hell_a_lot_of_ small textures/tiles and animations on screen ...

The only solution i found until now is using the VertexArray - to set up something like the TileMap class from the tutorial (www.sfml-dev.org/tutorials/2.3/graphics-vertex-array.php#example-tile-map) and put all my tiles, objects and animation-images into one big texture and have it all thrown on display by one single sf::VertexArray::draw call every frame.

But before i go on i wanna make sure - i'm asking myself: "is this really the only useful way to do this?!"  :o it feels like a weird approach to me. And it is quite a lot stuff to prog for this quite simple task of displaying texture-rectangles.

I need as much CPU as possible for all the other stuff i'm going to calculate in parallel to the graphics rendering. Having called such a big virtual function like RenderTarget::draw for every single tile/object i need on screen is no option for me.

So my question to you guys: Is it really helpful for GPUs to find all their stuff in one single BIG texture - is it worth the effort constructing my own TileMap for everything? Or is there something like a lightweight fastSprite class somewhere out there, which - for instance - lacks for a chubby draw function, but has something like show() and hide() to add/remove it from a batch-list, which draws 1000 small sf::Textures quickly in one draw-call?

which way to go?

thanks in advance for any guidepost :-)


shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: about performance ...
« Reply #1 on: June 02, 2015, 05:17:41 pm »
It is far more efficient to use vertex arrays as a single draw call is faster that several draw calls, but why do you need so many sprites? You make it sound like 5000 sprites at a time is common, and you aren't giving each one its own texture are you?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: about performance ...
« Reply #2 on: June 02, 2015, 05:18:57 pm »
Looking at a benchmark test written 8 years ago, do you really expect it to be representative in any way today? ::)

Are your "I need"-statements all just theoretical or do you actually have already something up and running?
Have you previously written a game in the scope you're vaguely describing? If not, then I suggest you start small and don't worry about performance, because in that case performance will be your last issue to worry about. ;)

An OpenGL draw call is "expensive" and as such one usually tries to reduce them. This can be done by using vertex arrays and batch all the quads. However having to sort the vertices in the right order for displaying also costs processing power, so in the end you'll have to find a balance between CPU and GPU utilization. Also note that having a few (hundred) draw calls has not that big of an impact on performance.

As usual when it comes to performance, all I can say is: Only start worrying about performance when you actually have a performance issue.
Also see this article.
« Last Edit: June 02, 2015, 05:33:17 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Breakfaster

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: about performance ...
« Reply #3 on: June 02, 2015, 05:45:30 pm »
Quote
Looking at a benchmark test written 8 years ago, do you really expect it to be representative in any way today? ::)
of course not, but it was a funny strange thing to encounter.  ;D

ok, 5000 sprites are unrealistic of course, took it only as a theoretical worst case scenario. But i may hit the 1000 mark - my game will be tower-defense-ish - and i don't want to find it creeping when it gets close to that mark, so ... regarding C++ : i know what i'm doing - and if i wouldn't worry about performance, i could go java or unity. I just want to make sure that i go in the right direction and will finish what i started. My concept is finished - and i will implement it - one or another way.

Quote
... in the end you'll have to find a balance between CPU and GPU utilization. Also note that having a few (hundred) draw calls has not that big of an impact on performance.

As usual when it comes to performance, all I can say is: Only start worrying about performance when you actually have a performance issue.
Also see this article.

Thx a lot :)

but i'm aware of this stuff already. My question is still: Do i have to put my stuff into BIG textures, or is there a faster Sprite way out there?

« Last Edit: June 02, 2015, 06:02:49 pm by Breakfaster »

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: about performance ...
« Reply #4 on: June 02, 2015, 06:44:29 pm »
Yes merging sprites can increase speed, but unless you've been using loads of sprites where you can be using one, it's not going to make a huge difference.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: about performance ...
« Reply #5 on: June 03, 2015, 01:56:38 am »
I remember seeing a sprite batcher on the Wiki. Ah, here it is.
I don't know how up-to-date it is but I'm sure it'll give you something to build upon, if not inspiration on what to create instead.

As usual when it comes to performance, all I can say is: Only start worrying about performance when you actually have a performance issue.
Also see this article.
I like this philosophy. You tend to get more things working sooner so you get an earlier visualisation of the direction of the final product.
Also, I liked that article. I just skimmed through it but I'm sure to read it more fully at later time. Thank you  :)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Breakfaster

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: about performance ...
« Reply #6 on: June 03, 2015, 12:59:33 pm »
hey

my concept / direction of product already stands. Next step for me is to find the right way to get most performance out of SFML - to assure that i will find my swarms of minions walk, act and fight smoothly, even when there are 100s of them _visible_. Bethink of all the AI calculations behind them - i simply can't afford wasting CPU time for unnecessary draw calls.

so ...

i looked through the AltSpriteHolder class - not bad - found that it must be faster than the original. However, in the end it still hikes through the RenderTarget::draw for _every_ single Texture displayed - not really what i am looking for.

Looking through the original sf::Sprite source, i ended up going through RenderTarget::draw. Seeing how it works and how Texture::bind works almost gives me the answer that it _is_ advantageous to have the GPU find all textures gathered in one big texture. The SFML sources actually telling me that. But is it really that way?

So i went looking for a place where Textures are changed fast and efficient - and got stuck in Texture:bind() - what's the point about m_pixelsFlipped ? Is it a graphics-card thing that it flips pixels vertically so we are forced to check this flag at _every_ Texture::bind call, which is called in every RenderTarget::draw call? Otherwise this could be done earlier in the loadFrom* functions.

Same with the GLfloat matrix - it could be precalculated outside of Texture::bind and only changed when m_actualSize changes. The whole check for (coordinateType == Pixels) could probably be moved outside bind().

However - Texture::bind should only be used in precalculation/pre-render phase. Pre-render as much as possible !

oh, in the Texture::bind - Texture.cpp Line 487 - i found this
    if (texture && texture->m_texture)
when texture is NULL this will crash anyway. Would change it to
    if(texture) if(texture->m_texture)
or even better just go
   if(texture->m_texture)
   
maybe i'll find more later. Possible conclusion: Better answer my questions to stop me looking through your code  ;D :P

NO! I don't want to consider rewriting RenderTarget::draw() - that goes too far - i would like to skip caring about openGL issues and just enjoy SFML.

Or should i  :o ?

i think i will now write my own TileMap class for big Textures full of small ones and see how fast it can become. Or are any suggestions left for me out there ?

regards
Breakfaster

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: about performance ...
« Reply #7 on: June 03, 2015, 05:15:08 pm »
I may be saying things you already know but I just wanted to clarify a few things just in case. Textures are heavy expensive objects. Using as few textures as possible is a good idea because changing the texture is an expensive operation for the graphics card. You can only use one texture per draw call.

Sprites are simply views into a texture and don't use up much memory. Drawing many sprites that use the same texture will have better performance than using a different texture every time. It is a very common strategy to have large textures with many pictures on them to be used by many different sprites (sprite sheet).

As the other posters mentioned, you can even go a step farther and instead of using sprites you can batch many objects into one draw call if the objects use the same texture (again, you can only have one texture per draw call). You can do this with vertex arrays and is especially ideal for background tiles.

Also, you don't have to commit to only using one of these strategies. You can use a vertex array for the background tiles and sprites (or sprite batches, which likely get turned into vertex arrays under the hood) for your objects, for example.
« Last Edit: June 03, 2015, 05:45:18 pm by Arcade »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: about performance ...
« Reply #8 on: June 03, 2015, 05:52:38 pm »
Sound like you didn't read the linked article...

As for the texture bit, there's a limit on texture size, especially slightly older hardware doesn't have support for very large textures. Just something to keep in mind.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Breakfaster

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: about performance ...
« Reply #9 on: June 03, 2015, 06:26:35 pm »
Allrighti 8)

thanks for the clear words @arcade - exactly what i needed to know. You know, i have plenty of experience with C++, but i'm a newbie on openGL and how to handle graphic-cards correctly.

Will go the sprite sheet way. Already have a plan how i will organize and group all my stuff - VertexArrays are great -

@eXp: sorry i can't find anything about openGL and graphics in your linked article ??? maybe you meant another one? - or i have bananas on my eyes.

one question about the maximum size of textures - are they any serious graphic-cards in use out there today with a maximum of 512x512 ? I plan to pre-render rooms that may get bigger than that ... and i don't think i will need to support such exotic things and just require 2048x2048, otherwise throw a Messagebox and exit.




eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: about performance ...
« Reply #10 on: June 03, 2015, 08:45:50 pm »
No, the article is about pre-mature optimization and over engineering which is what you're doing.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Breakfaster

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: about performance ...
« Reply #11 on: June 04, 2015, 10:36:59 pm »
ahm ...

... forgot to mention that the article is indeed very good - just recognized that it is just 2 weeks old - all important points to thing through - remembering my own intense lesson in over-engineering 5 years ago.

What i actually do is a lot of evaluating. I evaluate my possibilities and limitations before i write an application. I think everyone should do that, just to start implementing something into the blue without asking other people how to do it right, thats what i call pre-mature.

So this is my actual approach here
 - i think ahead a lot.
 - i hack in and test all kinds off stuff looking at results/speed/stability
 - understand other people's code before making myself think that i use it right
 - thus i ask a lot of questions not bothering if people may get annoyed by that

maybe i'm just too enthusiastic. I don't care, i like to be like that. ok the way i ask questions may be a little relentless here and there - but sometimes its hard to find answering people.

btw.
graphic-cards with maximum Texturesize of 512x512 are almost not existent anymore. 1024 is save. 2048 is still good to go.
http://feedback.wildfiregames.com/report/opengl/feature/GL_MAX_TEXTURE_SIZE