Aug 14 2008

OpenMP in Visual C++

Category: OpenMP,Paralell/Concurrentsemihozmen @ 07:31

Here is a sample code given by MSDN and commented by me to remember the milestones of OpenMP which is one of the simplest ways of parallelizing a program.

// The OpenMP DLLs are in the Visual C++ redistributable directory and
// need to be distributed with applications that use OpenMP.
 
#include "stdafx.h"
 
#include <iostream>
#include <math .h>
#include <omp .h> 
// If _DEBUG is defined in a compilation and if #include omp.h is in source code,
// VCOMPD.LIB will be the default lib. Otherwise, VCOMP.LIB will be used.
 
#define NUM_THREADS 4
#define NUM_START 1
#define NUM_END 10
 
int main() {
int i, nRet = 0, nSum = 0, nStart = NUM_START, nEnd = NUM_END;
int nThreads = 0, nTmp = nStart + nEnd;
unsigned uTmp = (unsigned((abs(nStart - nEnd) + 1)) *
unsigned(abs(nTmp))) / 2;
int nSumCalc = uTmp;
 
if (nTmp < 0)
nSumCalc = -nSumCalc;
 
omp_set_num_threads(NUM_THREADS); 
// Sets the number of threads in subsequent parallel regions,
// unless overridden by a num_threads clause.
 
// parallel:: Defines a parallel region, which is code that will be executed by multiple threads in parallel.
// default::: shared, which is in effect if the default clause is not specified, means that any variable
// in a parallel region will be treated as if it were specified with the shared (OpenMP) clause.
// none means that any variables used in a parallel region that are not scoped with
// the private (OpenMP), shared (OpenMP), reduction, firstprivate, or lastprivate clause will
// cause a compiler error.
 
// private::: Specifies that each thread should have its own instance of a variable.
// shared::: Specifies that one or more variables should be shared among all threads.
 
#pragma omp parallel default(none) private(i) shared(nSum, nThreads, nStart, nEnd)
{
#pragma omp master 
// only master thread will run following statement
nThreads = omp_get_num_threads();
 
#pragma omp for 
// Causes the work done in a for loop inside a parallel region to be divided among threads.
for (i=nStart; i<=nEnd; ++i) {
#pragma omp atomic 
// The statement containing the lvalue whose
// memory location you want to protect against multiple writes.
nSum += i;
}
}
 
if (nThreads == NUM_THREADS) {
printf_s("%d OpenMP threads were used.\n", NUM_THREADS);
nRet = 0;
}
else {
printf_s("Expected %d OpenMP threads, but %d were used.\n",
NUM_THREADS, nThreads);
nRet = 1;
}
 
if (nSum != nSumCalc) {
printf_s("The sum of %d through %d should be %d, "
"but %d was reported!\n",
NUM_START, NUM_END, nSumCalc, nSum);
nRet = 1;
}
else
printf_s("The sum of %d through %d is %d\n",
NUM_START, NUM_END, nSum);
}

Tags: ,