使用Visual Studio 2010从C文件向mex文件编译添加OpenMP支持

时间:2014-05-26 17:43:43

标签: c++ c matlab openmp mex

我是并行编程的新手,我遇到过OpenMP库的问题。我在Visual Studio win 32控制台应用程序中使用简单的代码进行了测试:

int main(){
omp_set_num_threads(2);
#pragma omp parallel
    { 
       int tid = omp_get_thread_num();
       long tmp;
       if(tid == 0){ for (int i = 0;i<10000;i++){ tmp = ((i*999)*90000)*((i*999)*90000) }
       if(tid == 1){ for (int i = 0;i<10000;i++){ tmp = ((i*999)*90000)*((i*999)*90000) }
    }
}

代码并行运行,如果我在没有OpenMP的情况下运行代码,则会运行2次。 现在,在MATLAB中,我可以运行.mex个文件,这些文件是编译为在MATLAB中运行的C文件,您需要在文件中为特定编译器添加/openmp编译标志。由于我在Visual Studio 2010中工作,需要修改的文件是msvc100opts.bat,我在那里将/openmp添加到编译标志中。当我进行基准测试时,我得到的结果不好而且不稳定。我读过很多对我没有帮助的指南。如何在MATLAB中的.mex文件中可靠地使用OpenMP指令?

1 个答案:

答案 0 :(得分:1)

这是一个扩展的评论而不是答案,说实话,我不确定你真正的问题是什么......

您向我们展示的内容并非并行化。它可能表现得好像它不是,但它不是(不完全)。您已经定义了一个OpenMP并行区域,因此块内的每一行都是

#pragma omp parallel
    { 
     ...
    }

由每个线程运行。现在,每个线程都会遇到两个if语句并且行为正确,因此您可能认为您的程序并行运行,而您可能是对的,但您已经完成了并行化,而不是OpenMP。

您已省略并行化工作共享指令,例如for。对于OpenMP并行化,您必须编写类似的东西(我还没有检查过它的语法或语义):

#pragma omp parallel for
    { 
       for (int i = 0;i<10000;i++){ tmp = ((i*999)*90000)*((i*999)*90000) }
    }

注意:

  1. 我已经加入了工作共享指令for
  2. 使用OpenMP,(几乎)从不需要程序员关注自己的线程ID。正如您所写,您的程序需要重写和重新编译才能使用除2之外的任意数量的线程。更糟糕的是,你已经完成了并行化的繁重工作;如果那是你想要做的事情,那就去吧,但你几乎不需要OpenMP。
  3. 并行区域内完成的工作量很小。事实上,一个非常好的编译器可能会发现tmp未在并行区域之外使用并优化掉整个循环。您无法得到关于并行程序 vs 串行版本性能的任何有用结论,甚至在您解决问题之后也是如此。
  4. 至于在Windows上使用OpenMP编译MEX文件的问题,我没有任何建议,但我要指出,即使最新版本的MS C和C ++编译器也不会实现OpenMP。 2.0