Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualHodgman

Posted 24 April 2013 - 11:15 PM

Yeah you shouldn't be creating and destroying the threads every loop iteration; you should be able to create/destroy them just once and re-use them.
 
You can move your while(1) loop into the thread's main function, so that the thread will continue to loop.
To synchronize the threads, so that they all loop together, you can use a mutex to control some kind of "command" structure. Each thread has it's own command/task, with it's own mutex, which ensures either the worker is doing the task, or the main thread is generating the task (but never both at once). Because each thread has their own task/mutex, they can all be doing work at the same time.
Something like:
struct RenderTask
{
   Mutex lock;
   int threadId;
   int numThreads;
   Scene* input;
   Window* output;
   bool complete;
};
 
main thread:
  //make one job per thread
  RenderTask* tasks = new RenderTask[numThreads];
  fill in task with parameters
  create one thread per task, passing (void*)tasks[threadIndex] as the argument
  while(1)
  {
    int numComplete = 0;
    for each thread
    {
      lock threads task
        if task is complete
          ++numComplete
      unlock threads task
    }

    if( numComplete == numThreads )//all jobs are done
    {
      lock each threads task
        fill in all tasks with data for next frame (including setting complete to false)
        display results to screen
      unlock each threads task
    }
  }

worker thread:
  while(1)
  {
    lock task
      if task isnt complete
      {
        do task
        task.complete = true
      }
    unlock task
  }

#2Hodgman

Posted 24 April 2013 - 11:13 PM

Yeah you shouldn't be creating and destroying the threads every loop iteration; you should be able to create/destroy them just once and re-use them.
 
You can move your while(1) loop into the thread's main function, so that the thread will continue to loop.
To synchronize the threads, so that they all loop together, you can use a mutex to control some kind of "command" structure.
Something like:
struct RenderTask
{
   int threadId;
   int numThreads;
   Scene* input;
   Window* output;
   bool complete;
};
 
main thread:
  //make one job per thread
  RenderTask* tasks = new RenderTask[numThreads];
  fill in task with parameters
  create one thread per task, passing (void*)tasks[threadIndex] as the argument
  while(1)
  {
    int numComplete = 0;
    for each thread
    {
      lock thread's task
        if task is complete
          ++numComplete
      unlock thread's task
    }

    if( numComplete == numThreads )//all jobs are done
    {
      lock each thread's task
        fill in all tasks with data for next frame (including setting complete to false)
        display results to screen
      unlock each thread's task
    }
  }

worker thread:
  while(1)
  {
    lock task
      if task isn't complete
      {
        do task
        task.complete = true
      }
    unlock task
  }

#1Hodgman

Posted 24 April 2013 - 11:12 PM

Yeah you shouldn't be creating and destroying the threads every loop iteration; you should be able to create/destroy them just once and re-use them.
 
You can move your while(1) loop into the thread's main function, so that the thread will continue to loop.
To synchronize the threads, so that they all loop together, you can use a mutex to control some kind of "command" structure.
Something like:
struct RenderTask
{
   int threadId;
   int numThreads;
   Scene* input;
   Window* output;
   bool complete;
};
 
main thread:
  //make one job per thread
  RenderTask* tasks = new RenderTask[numThreads];
  //fill in task with parameters
  //create one thread per task, passing (void*)tasks[threadIndex] as the argument
  while(1)
  {
    int numComplete = 0;
    for each thread
    {
      lock thread's task
        if task is complete
          ++numComplete
      unlock thread's task
    }

    if( numComplete == numThreads )//all jobs are done
    {
      lock each thread's task
        fill in all tasks with data for next frame (including setting complete to false)
      unlock each thread's task
    }
  }

worker thread:
  while(1)
  {
    lock task
      if task isn't complete
      {
        do task
        task.complete = true
      }
    unlock task
  }

PARTNERS