c++ - 将 OpenMP 支持添加到使用 Visual Studio 2010 从 C 文件编译的 mex 文件

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

最佳答案

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

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

#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

关于c++ - 将 OpenMP 支持添加到使用 Visual Studio 2010 从 C 文件编译的 mex 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23875313/

相关文章:

c - 如何从二进制文件读取到字符串/数组和 c 中的 int?

将数组转换为 int/float

c - 调用 setsockopt() 来禁用 udp 多播中的环回时,它返回 255

matlab - 是否可以通过继承来扩展图形对象的功能?

c++ - 从 C++ dll 返回数组到 matlab

c++ - gluProject 的文档是否缺少透视除法?

c# - 如何创建一个全局处理 Win+<some key> 组合的应用程序?

c++ - SQLite blob 数据类型

python - 无法从偏航角超过 90 glm 的欧拉角创建 quat

Matlab - 如何制作自定义图例