Edit: I thought of a way to do this using the preprocessor. This fixes the problem of duplicate code at the expense of making the compiling and linking slightly more complicated. It uses the feature that if OpenMP is not enabled in the compiler then the OpenMP constructs are ignored.
#include <stdlib.h>
void setQueen(int* x, int y, int z) {
/*code*/
}
#if defined _OPENMP
void solve_parallel(const int size)
#else
void solve_serial(const int size)
#endif
{
int i;
#pragma omp parallel for
for(i = 0; i < size; i++) {
int *queens = (int*)malloc(sizeof(int)*size);
setQueen(queens, 0, i);
free(queens);
}
}
Compile with
gcc -O3 -c foo.c -o solve_serial
gcc -O3 -fopenmp -c foo.c solve_parallel
Then you can use a main funciton similar to the one below with function pointers and link in the solve_serial and solve_parallel object files.
Another option is to pass the number of threads like this:
void solve(const int nthreads)
{
int i;
const int size = 10;
#pragma omp parallel for num_threads(nthreads)
for(i = 0; i < size; i++) {
int *queens = (int*)malloc(sizeof(int)*size);
setQueen(queens, 0, i);
free(queens);
}
}
However, even for nthreads=1 the compiler has to insert OpenMP constructs which can reduce the performance compared to not compiling with OpenMP and therfore can give a biased compairison.
A more fair solution is to define two functions with and without OpenMP and then use an array of function pointers (see below). This is more useful when you have several variations of a function you want to compare for optimization.
#include <stdlib.h>
#include <omp.h>
void solve_parallel(const int size)
{
int i;
#pragma omp parallel for
for(i = 0; i < size; i++) {
int *queens = (int*)malloc(sizeof(int)*size);
setQueen(queens, 0, i);
free(queens);
}
}
void solve_serial(const int size)
{
int i;
for(i = 0; i < size; i++) {
int *queens = (int*)malloc(sizeof(int)*size);
setQueen(queens, 0, i);
free(queens);
}
}
int main(void) {
const int size = 100;
int i;
double dtime[2];
void (*solve[2])(int);
solve[0] = solve_serial;
solve[1] = solve_parallel;
solve[1](size); /* run OpenMP once to warm it up */
for(i=0; i<2; i++) {
dtime[i] = omp_get_wtime();
solve[i](size);
dtime[i] = omp_get_wtime() - dtime[i];
}
return 0;
}