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

Author Topic: Thread separation  (Read 1227 times)

0 Members and 1 Guest are viewing this topic.

Refros

  • Newbie
  • *
  • Posts: 1
    • View Profile
Thread separation
« on: November 11, 2019, 11:57:07 pm »
Hello,
I want to separate the game logic and rendering in two individual threads. Essentially the game logic will be responsible for modifying the SFML drawables (like changing position or color) and the rendering thread will of course perform the rendering. I will  guard against thread collisions through an immutable facility (i.e. the render thread will be reading objects that provably cannot change).

I browsed the sources and this seems feasible because it seems to me that when for example setting the position of a shape, SFML does not perform any opengl calls.

Hence my question is: is this separation guaranteed by the SFML design or this just applies to certain functions only?

Edit: To phrase it differently in case it helps: does SFML invoke opengl calls on objects on the draw call only, or also when modifying the objects properties also( like position, color, etc). I am interested both about shapes and views.
« Last Edit: November 12, 2019, 12:17:33 am by Refros »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10800
    • View Profile
    • development blog
    • Email
Re: Thread separation
« Reply #1 on: November 13, 2019, 01:01:34 am »
The general advice that you'll also find in similar topics is: don't do it.

It might seem like a great idea when you have little insight on multi-thread programming and how OpenGL works, but once you do realize that running in multiple threads requires you to sync shared objects (e.g. a shape: updating position vs drawing), thus requiring some sort of lock/mutex, thus making the logic and rendering thread pretty much synchronous again, you'll start to understand that this approach won't give you any gains, instead it will add a lot more complexity and overhead, most likely making your application slower.
Additionally, OpenGL is not multi-thread capable, so you'll have to switch context a lot and then OpenGL calls will be queued on one thread anyways, again making this whole setup cost more than it actually helps.

There are enough similar posts on the forum if you search a bit, you'll find more detailed answers as well.

Finally, SFML does not guarantee anything with regards to multiple threads, i.e. SFML is neither thread-safe, nor does it handle OpenGL context activation with multiple threads for you.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Refros

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: Thread separation
« Reply #2 on: November 13, 2019, 12:03:41 pm »
Thank you for the response!

I have more than extended experience in multithreading programming and I am fully aware of the issues. I agree with your assessment that people should not jump into it if they are just getting started.

For my purpose it means that I will have to investigate  the details of SFML implementation (which is very clean and easy to follow as a matter of fact) and wrap it around the multithreading facilities I have in mind.
 
My understanding on the context implementation in SFML though is different than yours. It seems that there is a global shared context, that threads can use and access the state without the need of switching. All you need is an active SFML context on each thread. Please let me know if this is incorrect. I plan proper measures that guarantee no opengl location is written by two threads at the same time.

Your answer gives me a very clear path.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10800
    • View Profile
    • development blog
    • Email
Re: Thread separation
« Reply #3 on: November 13, 2019, 12:18:32 pm »
It seems that there is a global shared context, that threads can use and access the state without the need of switching. All you need is an active SFML context on each thread. Please let me know if this is incorrect. I plan proper measures that guarantee no opengl location is written by two threads at the same time.
As far as my understanding goes from past conversations this is mostly a correct assessment. My point was mainly with regards to the SFML context per thread. You will have to handle the activation of said context in each thread yourself and AFAIK this still causes context switches.

My personal recommendation still remains that it's okay to do CPU-bound work with multiple threads (or potentially std::async or some task pool implementation), while keeping all OpenGL operations in one thread, given that the OpenGL commands will be added into a single queue anyways.

For example, if you want to load an image from disk in the background without blocking the application, you'd do the whole disk access and image decompression with sf::Image, so you end up with the pixel information in memory and do the slow disk operations in a separate thread, but then on the main thread, you create an sf::Texture from the image, which will load the data into the VRAM, this operation isn't the fastest, but should in most cases not cause any performance issues.

Or another example, if you're trying to render a fractal, you can split the calculation of the image data into multiple threads and serve the final image (or chunks of it) to the main thread to be rendered. (Then again that would probably best done in a shader anyways).
« Last Edit: November 13, 2019, 12:20:25 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/