我是并行编程的新手,我遇到了 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) }
}
注意:
- 我包含了一个工作共享指令,
for
。 - 有了 OpenMP,程序员(几乎)永远不需要关心线程 ID。正如您编写的那样,您的程序需要重写和重新编译才能使用除两个以外的任意数量的线程。更糟糕的是,您已经完成了并行化的繁重工作;如果那是您想要做的,请继续,但您几乎不需要 OpenMP。
- 在并行区域内完成的工作量很小。事实上,一个非常好的编译器可能会发现
tmp
没有在并行区域之外使用并优化整个循环。您将无法就并行程序的性能与串行版本的性能得出任何有用的结论,即使在您解决问题之后也是如此。
至于在 Windows 上使用 OpenMP 编译 MEX 文件的问题,我没有什么建议,但我要指出,即使是最新版本的 MS C 和 C++ 编译器在 v2.0 之后也不会实现 OpenMP
关于c++ - 将 OpenMP 支持添加到使用 Visual Studio 2010 从 C 文件编译的 mex 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23875313/