C++ 仅使用单线程的OpenMP

C++ 仅使用单线程的OpenMP,c++,multithreading,visual-studio-2017,openmp,C++,Multithreading,Visual Studio 2017,Openmp,我尝试使用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); } } 但

我尝试使用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
到目前为止,我做了以下几件事

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

  • 我的问题是我错过了什么?为什么不打印来自多个线程的输出?

    您有一个visual studio设置,使您陷入困境(例如,运行时生成不同于调试生成或类似的设置)。如果您有VisualStudio,您应该能够找到“针对VS*的开发人员命令提示符”,这样您就可以确保编译是正确的,并且不会陷入MSVC设置中。用例如

    cl /openmp hello.c
    
    在VisualStudio中,您需要通过转到“项目属性”(Alt F7)和“语言”选项卡,然后启用“打开MP支持”,来确保启用omp支持。
    我想你遗漏了什么:

    #include <cstdio>
    #include <omp.h>
    
    int main() {
    #pragma omp parallel num_threads(4)
        {
            printf("Hello from thread %d\n", omp_get_thread_num());
        }
    }
    
    请特别注意编译器标志:

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

    由于每个线程要做的工作太少,因此产生单个线程的开销而不是在同一个线程上运行所有线程似乎是愚蠢的。我猜您的OpenMP实现或编译器只是很聪明,并且意识到在这里使用多线程只会损害性能。不过,这纯粹是猜测。我猜你的visual studio设置会把你搞砸(例如,运行时构建不同于调试构建或类似的东西)。如果您有VisualStudio,您应该能够找到“针对VS*的开发人员命令提示符”,这样您就可以确保编译是正确的,并且不会陷入MSVC设置中。使用例如cl/openmp hello.cs编译。我们非常确定这是一个编译器问题,我取消删除了我的初始答案,以显示在visual studio中可以在何处启用openmp,希望这将是一个真实的答案。@Thomas openmp不是这样工作的。并行区域在所有线程中执行,如果编译正确,显示的代码应产生显示的输出。@JesperJuhl我不知道有任何编译器在基于优化假设启用时忽略OpenMP pragmas,而且它将直接违反OpenMP规范。我不确定是否理解您的解决方案。您的意思是我需要使用gcc编译器而不是MS visual studio 2017编译器吗?@mohammad.roni我想说的是,sehe想说的是,您的代码很好,所以还有其他问题。我猜,看我对你的原始帖子的评论,你的编译是错误的。在我的评论中,我建议打开一个开发者命令提示符,并使用“cl/openmp hello.c”命令进行编译(显然是导航到正确的路径等等)。然后运行它生成的hello.exe。如果这样做有效,那么您的MSCV配置需要有效。@Andrewoholmgren您是对的,感谢您的解决方案。我使用“cl/openmp hello.c”命令进行编译,它运行正常。如果要避免命令提示符,请考虑需要什么样的MS Visual Studio配置。@mohammad.roni您可能必须在“编译设置”对话框的通用文本框中填写“/openmp”。另外,确保它适用于所有构建variants@mohammad.roni您应该知道,如果您使用的是Microsoft的编译器(而不是通过VS访问的其他编译器),它们只支持非常旧版本的OpenMP 2.0[],因为OpenMP现在已升级到5.0,您将丢失很多…如果未启用OpenMP支持,程序不会编译-
    omp\u get\u thread\u num
    默认情况下不在任何链接的库中。除非打开和关闭支持,否则OpenMP运行时将保留在链接器设置中的附加库中。@hristoilev您可能会这么认为,但是MS正在编译指向库的链接,只是不使用它。如果OpenMP语言支持处于关闭状态,则不存在多线程,如果它处于打开状态,则会得到您所期望的结果。在VS IDE和提示符下都会发生。事实上,在
    omp.h
    中有一个
    #pragma注释(lib,…)
    ,它只通过包含头链接OpenMP运行时。微软总是有自己的做事方式。
    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