Thursday, June 26, 2008

Introduction to OpenMP - Easy multi-threading for C/C++

As well as other compilers, Visual Studio 05 and 08 (Professional and Team System editions) support the OpenMP v2 standard. It’s a collection of language extensions which make it easier to create multi-threaded code. Here I’ll give a quick taster of two of the OpenMP ‘directives’ – ‘Parallel’ and ‘For’.
Parallel allows you to specify a block of code which executes multiple times in parallel:

void ParallelTest() 
{  
   #pragma omp parallel num_threads(4)  
  {  
      int i = omp_get_thread_num();  
      printf_s("ParallelTest: Hello from thread %d\n", i);  
  }  
}
Results in the output:
ParallelTest: Hello from thread 0
ParallelTest: Hello from thread 3
ParallelTest: Hello from thread 1
ParallelTest: Hello from thread 2

The ‘for’ directive allows a for loop to be split up and executed in several threads:
void ForTest() 
{  
  #pragma omp parallel for  
   for (int j=0; j<=4; ++j)   
   {  
       int threadNum = omp_get_thread_num();  
       printf_s("ForTest: Hello from thread %d            - loop iteration %d\n", threadNum, j);  
   }  
}
Results in the output:
ForTest: Hello from thread 0 - loop iteration 0
ForTest: Hello from thread 2 - loop iteration 3
ForTest: Hello from thread 1 - loop iteration 2
ForTest: Hello from thread 3 - loop iteration 4
ForTest: Hello from thread 0 - loop iteration 1




The thing which I find really cool about OpenMP is that it requires such little change to the code. Normally you’d need to write a lot of lines of code to accomplish the same results we see above, but with OpenMP it’s often as little as a single line – which you can comment out to go back to a single threaded approach. So if you find an inner loop which is hogging performance, and lends itself to parallelization, you can quickly make it multithreaded. It's supported on Xbox 360, but not across all game consoles. It's certainly useful for speeding up your tools.
For a list of other compilers which support OpenMP, see here. Note that Visual Studio 2005 does support it, but isn’t listed, as they just list the latest version.
To enable OpenMP in your Visual Studio C++ project, you need to:
  • #include <omp.h> // Include OpenMP
  • Go to your ‘Project properties->C/C++->Language->OpenMP Support’, and set it to ‘Yes’.
To find out more about these and the other OpenMP directives, you can see a list on MSDN.
In my previous post, I introduced Cuda. These two technologies are very different - OpenMP requires minimal code change and runs on CPU, while Cuda requires much more work but allows you to run on the GPU with many more cores.

6 comments:

Anonymous said...

Not supported on consoles?
Xbox 360? According to this:
http://msdn.microsoft.com/en-us/magazine/cc163717.aspx

??

Mark Pope said...

Hmm, I should have said 'all' consoles. I'm used to working on three consoles at once, and often if something doesn't work the same way on each, I think of it as not being viable - like a middleware that didn't support all plats needed. Thanks!

Anonymous said...

Visual Studio 2005 Standard doesn't have omp.h. Only Professional and Team System editions come with that file.

But I guess that if you copy that header file and all of its dependecies, you'd be able to build a project that uses OpenMP in VS 2005 Standard.

You can find the different features of each edition of VS 2005 C++ here:
http://msdn.microsoft.com/en-us/library/hs24szh9(VS.80).aspx

rchrd said...

Mark:
We (OpenMP.org) have Visual Studio 2008 in our list of compilers, and not VS 2005 because we want to list the just the latest versions.

But I'm curious to know why you are using 2005 and not 2008.

Mark Pope said...

Thanks Daniel and Richard for your comments. At work we currently use 2005 Professional. As we have a lot of code and use various 3rd party sdk's / add-ins, upgrading IDE usually brings many problems, so we usually wait until there's a pressing reason to upgrade.

I'll update the post. Thanks again.

Anonymous said...

Wow, just what I needed! And I thought that simple multi threading was difficult? As you stated, I just added two lines and now my quad core is really working :)

Thanks a lot from here!