在Visual Studio 2010中为从C文件编译的mex文件添加OpenMP支持

Add OpenMP support to mex file compile from C file with Visual Studio 2010

本文关键字:文件 编译 mex 添加 支持 OpenMP Studio Visual 2010      更新时间:2023-10-16

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

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指令?

这是一个延伸的评论,而不是一个答案,老实说,我不确定你真正的问题是什么…

你给我们看的不是并行的。它可能表现得好像它是,但它不是(不完全是)。您已经定义了一个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。当您编写它时,您的程序将需要重写和重新编译以使用除两个以外的任意数量的线程。更糟糕的是,你已经完成了并行化的繁重工作;如果这是你想做的,那就去做吧,但你几乎不需要OpenMP。
  3. 在并行区域内完成的工作量很小。事实上,一个真正好的编译器可能会发现tmp没有在并行区域之外使用,并优化整个循环。你将无法得出关于并行程序串行版本性能的任何有用的结论,即使在你修复了问题之后。

关于在Windows上使用OpenMP编译MEX文件的问题,我没有什么建议,但我要指出的是,即使是最新版本的MS C和c++编译器在v2.0之后也没有实现OpenMP