【问题标题】:OpenMP using single thread only仅使用单线程的 OpenMP
【发布时间】:2020-07-08 15:54:46
【问题描述】:

我尝试使用 MS Visual Studio 2017 运行此代码,我的 CPU 有 48 个线程。

#include <stdio.h>
#include <omp.h>

int main() {
   #pragma omp parallel num_threads(4)
   {
      int i = omp_get_thread_num();
      printf_s("Hello from thread %d\n", i);
   }
}

我希望得到这样的输出

Hello from thread 0
Hello from thread 1
Hello from thread 2
Hello from thread 3

但实际上我得到了这个输出

Hello from thread 0

到目前为止,我已经做了以下事情

  1. 在项目设置中启用 openMP:属性 -> C/C++ -> 语言 -> OpenMP
  2. 将环境变量 OMP_DYNAMIC 设置为 FALSE

我的问题是我缺少什么?为什么它不打印来自多个线程的输出?

【问题讨论】:

  • 每个线程要做的工作如此之少,与只在同一个线程上运行所有东西相比,产生单个线程的开销似乎很愚蠢。我猜测您的 OpenMP 实现或编译器只是很聪明,并意识到在此处使用多个线程只会损害性能。不过纯属猜测。
  • 我猜你的 Visual Studio 设置让你很困惑(例如,运行时构建不同于调试构建或类似的东西)。如果您有 Visual Studio,您应该能够找到“VS* 的开发人员命令提示符”,这样您就可以确保编译正确并且不会陷入 MSVC 设置。用例如编译cl /openmp hello.c
  • 因为我们很确定这是一个编译器问题,所以我取消了我最初的答案,以显示您可以在 Visual Studio 中启用 openmp 的位置,希望这将是一个真实的答案。
  • @Thomas 这不是 OpenMP 的工作方式。并行区域在所有线程中执行,如果编译正确,所示代码应产生所示输出。
  • @JesperJuhl 我不知道任何编译器在基于优化假设启用时会忽略 OpenMP 编译指示,而且它会直接违反 OpenMP 规范。

标签: c++ multithreading visual-studio-2017 openmp


【解决方案1】:

您的 Visual Studio 设置让您感到困惑(例如,运行时构建不同于调试构建或类似的东西)。如果您有 Visual Studio,您应该能够找到“VS* 的开发人员命令提示符”,这样您就可以确保编译正确并且不会陷入 MSVC 设置。用例如编译

cl /openmp hello.c

在 Visual Studio 中,您需要通过转到项目属性 (Alt F7) 和语言选项卡,然后启用 Open MP 支持来确保启用了 omp 支持。

【讨论】:

  • 如果未启用 OpenMP 支持,程序将无法编译 - 默认情况下,omp_get_thread_num 不在任何链接的库中。除非打开和关闭支持将 OpenMP 运行时留在链接器设置中的其他库中。
  • @HristoIliev 你会这么认为,但是 MS 正在编译它链接到库,只是不使用它。如果 Open MP 语言支持关闭,则没有多线程,如果启用,您将得到您所期望的。在 VS IDE 和提示符下都发生。
  • 确实,omp.h 中有一个 #pragma comment(lib, ...),它会导致 OpenMP 运行时仅通过包含标头来链接。微软总是有自己的做事方式。
【解决方案2】:

我认为你遗漏了一些东西:

Live On Coliru

#include <cstdio>
#include <omp.h>

int main() {
#pragma omp parallel num_threads(4)
    {
        printf("Hello from thread %d\n", omp_get_thread_num());
    }
}

打印

Hello from thread 3
Hello from thread 2
Hello from thread 0
Hello from thread 1

特别注意编译器标志:

g++ -std=c++17 -O2 -Wall -pedantic -pthread -fopenmp main.cpp && ./a.out

【讨论】:

  • 。不确定我是否理解您的解决方案。你的意思是我需要使用 gcc 编译器而不是 MS Visual Studio 2017 编译器?
  • @mohammad.roni 我在说什么,而 sehe 说的是你的代码很好,所以还有其他问题。我的猜测,看到我对你原来的帖子的评论,你的编译是错误的。在我的评论中,我建议打开开发人员命令提示符并使用“cl /openmp hello.c”命令进行编译(显然导航到正确的路径等)。然后运行它生成的 hello.exe。如果这行得通,那么您的 MSCV 配置需要工作。
  • @AndrewHolmgren 你是对的,感谢你的解决方案。我使用“cl /openmp hello.c”commnad 进行编译,它工作正常。如果我要避免命令提示符,任何想法都需要什么样的 MS Visual Studio 配置。
  • @mohammad.roni 您可能必须在编译设置对话框的通用文本框中填写“/openmp”。此外,请确保它适用于所有构建变体
  • @mohammad.roni 您应该知道,如果您使用的是 Microsoft 的编译器(而不是通过 VS 访问的其他编译器),它们仅支持非常旧的 OpenMP 2.0 版本 [docs.microsoft.com/en-us/cpp/build/reference/…],由于 OpenMP 现在已达到 5.0,因此您错过了很多...
猜你喜欢
  • 2021-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-04
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多