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

Author Topic: A correct way to multithread OGL context?  (Read 16097 times)

0 Members and 3 Guests are viewing this topic.

Ceylo

  • Hero Member
  • *****
  • Posts: 2325
    • View Profile
    • http://sfemovie.yalir.org/
    • Email
Re: A correct way to multithread OGL context?
« Reply #15 on: April 19, 2012, 03:12:31 pm »
This is a known problem indeed, but since the code is not realistic, is it worth providing a (potentially ugly) solution to it?
I don't know what to say :D . It's indeed probably not a high priority.
It's just that it reminds me of this issue : https://github.com/SFML/SFML/issues/120
Which is a real and realistic use case as I launch a new thread each time I start playing with sfeMovie, and let the thread die each time I stop playing. But these are different issues.
Want to play movies in your SFML application? Check out sfeMovie!

Beta_Ravener

  • Jr. Member
  • **
  • Posts: 51
    • ICQ Messenger - 271426715
    • View Profile
Re: A correct way to multithread OGL context?
« Reply #16 on: April 19, 2012, 09:14:39 pm »
Quote
What kind of pitfalls?

Imagine a situation where you run same thread from 2 places in program. Voila - as the variable is static, it is common for all the launches and thus it can be corrupted easily. One way to solve this is using mutexes but I try to avoid static variables in threads in first place ;)

Quote
A good strategy is to allocate a pool of worker threads (size depending on the underlying hardware capabilities), and dispatch work to them on demand.

I don't think so, but why is it a problem if your thread is not destroyed and recreated thousands times? Like I said, it should ultimately be done only once.

Ahh I see what you are trying to tell me. I should've created and launch my threads at start of program and just signalize them to work when needed, right? This way everything's created and destroyed on start/end of program. Not a bad approach.  It's still better to have a thread sitting in my memory whole time than to get my memory occupied by OGL contexts. Only problem I see would be that when there are more and more threads added to program, things can get messy (Delphi's make everything global approach).

Background you asked for and I tried to avoid due details:
Take a look at my library www.unishader.g6.cz. In short, it makes working with shaders in OGL much easier. I'm now benchmarking CPU vs GPU in parallel computing contest. For that I've built GUI with SFGUI that is quite neat and I would like to keep that GUI somehow responsive (to break computations, etc.) although due benchmarking it will be slowed down ofc.

The threads are used for both CPU and GPU computing. I need to stress my CPU, so I compute in parallel on as many threads as user inputs (this way multicore CPUs can be fully benchmarked). For GPU only one thread with it's own context is created where my library gets initialized and does its job but as I said, this has to be different thread to keep GUI responsive. And as we already noticed in this test case, the lag and memory leaks are so bad that my real code is currently unusable.. I believe that was the same approach as Ceylo here mentioned (substitute playing movie with running computations).

In the past I've already used combination my library + SFML and I have to say they're working nicely together but those threads got me to dead end. I'm now thinking about reading some pages on traditional ways of multithreading so I get more familiar with the whole concept.

PS: you may notice on my web page that I'm talking about small SFML problem connected with creating pure OGL context on Linux, but I didn't try the new release so I won't start a topic for it now ..
« Last Edit: April 19, 2012, 09:16:56 pm by Beta_Ravener »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: A correct way to multithread OGL context?
« Reply #17 on: April 19, 2012, 09:30:51 pm »
Quote
Imagine a situation where you run same thread from 2 places in program. Voila - as the variable is static, it is common for all the launches and thus it can be corrupted easily. One way to solve this is using mutexes but I try to avoid static variables in threads in first place
Ah, I thought you were talking about thread-local variables.
So why are we talking about static variables?

Quote
Only problem I see would be that when there are more and more threads added to program, things can get messy
Why would you have so many threads? The strategy that I describe allocates the optimal amount of threads and then only uses them -- if there are more tasks to be performed then they are queued, since the hardware couldn't make them run in parallel efficiently anyway.
(remember, this is only (a very generic) one of the possible approches to multi-threading, I'm not telling you do it this way)
Laurent Gomila - SFML developer

Beta_Ravener

  • Jr. Member
  • **
  • Posts: 51
    • ICQ Messenger - 271426715
    • View Profile
Re: A correct way to multithread OGL context?
« Reply #18 on: April 19, 2012, 10:42:18 pm »
Quote
Ah, I thought you were talking about thread-local variables.
Actually they're thread-local.. Let me clarify:

fun(){
   static int i;
   for(int j = 0; j < 10; j++)
      i++;
}

Now, it is very unlikely that when this thread would be run from 2 places, the i++ would begin to be incremented while it is already incremented in other launch but you can't deny the fact that it can happen. This is simplified and you can imagine how many bad things could've happened if I used whole context instead of simple int. As I said one approach is to lock mutex before incrementing but in the end, it's better to pass by parameter (that static won't be going anywhere even if you'll destroy all the threads, so if that was a big resource you get a lot of memory lost). But that is for another discussion and varies with what you want to actually implement, and actually I realized that also passed variable would have need guards so it's irrelevant for this topic.

Quote
Why would you have so many threads?
Well later in development I could have a lot of functions with different purpose - loading, processing, ... So I would run all these threads on program start and most of them would be just sitting there because loading scene is infrequent, big space battles are infrequent,.. I hope you get my point. Anyway I would be left with many threads, most of them unused most of the time and signalizer (variable responsible for "awaking" the thread) would need to be passed around. I don't know if I would ever do such thing as there is always more ways to do the same, some of them much less complicated.. But I got a feeling from your message that you would make e.g. 5 threads (optimal) and make universal function for all the threads with big switch for loading, processing, .. ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: A correct way to multithread OGL context?
« Reply #19 on: April 20, 2012, 08:10:18 am »
Quote
Actually they're thread-local.. Let me clarify
No, I'm really talking about thread-local storage.
Laurent Gomila - SFML developer

Beta_Ravener

  • Jr. Member
  • **
  • Posts: 51
    • ICQ Messenger - 271426715
    • View Profile
Re: A correct way to multithread OGL context?
« Reply #20 on: April 20, 2012, 03:58:30 pm »
Thanks for link, I didn't know about such variable type before. One learns something new every day.. ;)

I'm already rewriting my app to use thread poll as you proposed, however there will be still a vector of threads for CPU parallel computing created (because of dynamic number of threads that can be input) and those threads will be launched and terminated on each benchmark start. It is not a big deal though as I don't need OGL context in those threads and therefore rerunning them shouldn't be so expensive.