如何使用C中的预处理器执行/跳过某些代码行?

如何使用C中的预处理器执行/跳过某些代码行?,c,parallel-processing,openmp,c-preprocessor,n-queens,C,Parallel Processing,Openmp,C Preprocessor,N Queens,我有一个用于N皇后计算的简单C程序。我使用OpenMP将其并行化。现在我想执行串行和并行版本,并计算加速。关键是,我不想为串行代码创建新文件,也不想在没有OpenMP指令的情况下将解决方案复制到新函数。我想做的是,保留一个函数,并从main告诉它何时以串行方式执行,何时以并行方式执行。我曾想过使用预处理器,但我确定这是否可能,如果可能,我如何实现它 void solve() { int i; #if PARALLEL == 1 #pragma omp parall

我有一个用于N皇后计算的简单C程序。我使用OpenMP将其并行化。现在我想执行串行和并行版本,并计算加速。关键是,我不想为串行代码创建新文件,也不想在没有OpenMP指令的情况下将解决方案复制到新函数。我想做的是,保留一个函数,并从main告诉它何时以串行方式执行,何时以并行方式执行。我曾想过使用预处理器,但我确定这是否可能,如果可能,我如何实现它

void solve() 
{
    int i;

    #if PARALLEL == 1
      #pragma omp parallel for
    #endif
    for(i = 0; i < size; i++) {
        int *queens = (int*)malloc(sizeof(int)*size);
        setQueen(queens, 0, i);
        free(queens);
    }
}


int main()
{
   ...

    #define PARALLEL 0
    st_start = clock();
    solve();
    st_end = clock();

    #define PARALLEL 1
    pt_start = omp_get_wtime();
    solve();
    pt_end = omp_get_wtime();

    ...
}
void solve()
{
int i;
#如果并行==1
#pragma-omp并行
#恩迪夫
对于(i=0;i
不幸的是,你不能那样做

预处理器只是扫描您的代码并替换#东西。 完成此操作后,编译器编译代码,没有任何与此相关的内容

因此,在您发布的代码中,预处理器从第一行开始,如果PARALLEL为1,则对代码执行#pragma操作,然后在main继续,将PARALLEL定义为0,然后定义为1

它不是从main开始,然后进入solve()

你可能想看看

你可以试试

void solve(int paral) 
{
    int i;


    #pragma omp parallel for if (paral == 1)

    for(i = 0; i < size; i++) {
        int *queens = malloc(sizeof(int)*size);
        setQueen(queens, 0, i);
        free(queens);
    }
}
void solve(内部并行)
{
int i;
#if的pragma omp parallel(paral==1)
对于(i=0;i

我没有尝试过这段代码,也没有使用OMP的经验,不过…

编辑:我想到了一种使用预处理器的方法。这解决了代码重复的问题,但代价是编译和链接稍微复杂一些。它使用的功能是,如果未在编译器中启用OpenMP,则忽略OpenMP构造

#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);
    }
}
然后,您可以在solve_serial和solve_parallel对象文件中使用与下面类似的带有函数指针和链接的主函数

另一个选项是按如下方式传递线程数:

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);
    }
}
void solve(常量int)
{
int i;
常数int size=10;
#用于num_线程(n线程)的pragma omp并行
对于(i=0;i
但是,即使对于nthreads=1,编译器也必须插入OpenMP结构,与不使用OpenMP编译相比,这会降低性能,因此可能会产生偏差

一个更公平的解决方案是定义两个带OpenMP和不带OpenMP的函数,然后使用函数指针数组(见下文)。当您要比较函数的多个变体以进行优化时,这一点更为有用

#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;
}
#包括
#包括
void solve_parallel(const int size)
{
int i;
#pragma-omp并行
对于(i=0;i对于(i=0;i调用预处理器,这是编译过程的第一部分;也就是说,所有包含的内容都已解决,所有预处理器指令都已解决,常量替换为它们的值等等


因此,您不能使用预处理器指令进行运行时决策,只能进行编译时决策。

还有其他方法吗?实际上,
#pragma
不会被预处理器取代。而且。我已经添加了我认为对您的情况有效的发现。@谢谢您的反馈。if语句仍然有效将OpenMP构造插入到代码中(因为它是在运行时解析的,而不是在编译时解析的)。这将使串行代码产生偏差。编译器无法同时优化代码。公平比较并行和串行代码的唯一方法是定义两个单独的函数。有关if语句仍然插入OpenMP构造并可能限制优化的原因,请参阅Shahbaz在的回答。
#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;
}