如果项目仅使用 OpenMP 构建,会发生什么差异

What differences could happen if a project is just built with OpenMP

我正在使用 Visual Studio 2012 在 c++ 中工作。我想知道下面这些案例之间的区别,

  1. 我通过启用 openmp 构建了我的应用程序,但我没有进行并行编程。我的意思是我没有在我的任何代码中使用#pragma 等。

  2. 我通过禁用 openmp 构建了我的应用程序,我没有进行任何并行编程。

在这种情况下,可能会发生什么样的变化或问题,例如应用程序大小等

绝对没有。举个简单的例子

#include <cstdio>

int main()
{
    printf("Hello world\n");
    return 0;
}

输出汇编器完全在有/没有/openmp标志的情况下是相同的(有/O2,但没有优化的结果相似)

; Listing generated by Microsoft (R) Optimizing Compiler Version 17.00.61030.0 

    TITLE
    .686P
    .XMM
    include listing.inc
    .model  flat

INCLUDELIB OLDNAMES

PUBLIC  ??_C@_0N@NLPDAPMJ@Hello?5world?6?$AA@       ; `string'
EXTRN   __imp__printf:PROC
EXTRN   @__security_check_cookie@4:PROC
;   COMDAT ??_C@_0N@NLPDAPMJ@Hello?5world?6?$AA@
CONST   SEGMENT
??_C@_0N@NLPDAPMJ@Hello?5world?6?$AA@ DB 'Hello world', 0aH, 00H ; `string'
CONST   ENDS
PUBLIC  _main
; Function compile flags: /Ogtp
;   COMDAT _main
_TEXT   SEGMENT
_main   PROC                        ; COMDAT

; 5    :    printf("Hello world\n");

    push    OFFSET ??_C@_0N@NLPDAPMJ@Hello?5world?6?$AA@
    call    DWORD PTR __imp__printf
    add esp, 4

; 6    :    return 0;

    xor eax, eax

; 7    : }

    ret 0
_main   ENDP
_TEXT   ENDS
END

OpenMP 是一组编译器指令(我没有使用)、库例程(我没有 link)和一些环境变量(同样,没有使用)。因此,没有理由输出程序会有任何不同。即使包括 omp.h 也不会改变任何东西(除了注释行)。

在启用 OpenMP 的情况下进行编译可能会产生一些影响,即使未启用 OpenMP 指令也是如此。但是,从代码的结果角度来看,它应该没有任何区别。由于编译器选择了一组不同的启发式方法来优化代码,因此它只会在性能方面有所不同。例如,在为 OpenMP 编译时可以禁用消耗大量内存带宽的积极优化(即使代码中不包含 OpenMP 指令),同时为非并行代码启用这些优化。同样,为 OpenMP 编译通常意味着链接线程安全版本的库(如果适用),这可能比非线程安全的库优化得少一些。但总的来说,我怀疑你会看到任何不同,除非你陷入一个非常极端的情况。

举个例子,这里摘自英特尔 C 编译器(旧)版本的手册页:

    -opt-mem-bandwidth<n> (i64, L*X only)
          Enables  or  disables  performance  tuning and heuristics
          that control memory bandwidth use among  processors.   It
          allows  the compiler to be less aggressive with optimiza-
          tions that might consume  more  bandwidth,  so  that  the
          bandwidth  can  be  well-shared among multiple processors
          for a parallel program.  For values of <n>  greater  than
          0,  the option tells the compiler to enable a set of per-
          formance tuning and heuristics in compiler  optimizations
          such   as  prefetching,  privatization,  aggressive  code
          motion, and so forth, for reducing memory bandwidth pres-
          sure   and   balancing  memory  bandwidth  traffic  among
          threads.  The <n> value is the level  of  optimizing  for
          memory  bandwidth  usage. You can specify one of the fol-
          lowing values for <n>:

          0 -- Disables a set of performance tuning and  heuristics
          in compiler optimizations for parallel code.  This is the
          default for serial code.

          1 -- Enables a set of performance tuning  and  heuristics
          in  compiler  optimizations for multithreaded code gener-
          ated by the compiler.  This is the  default  if  compiler
          option  -parallel  or  -openmp  is  specified, or Cluster
          OpenMP option -cluster-openmp is specified (see the Clus-
          ter OpenMP documentation).

          2  --  Enables a set of performance tuning and heuristics
          in compiler optimizations for parallel code such as  Win-
          dows  Threads,  pthreads,  and  MPI  code, besides multi-
          threaded code generated by the compiler.

因此,如您所见,启用或不启用 OpenMP 可能会对性能产生一些副作用,因为默认值通常是 -opt-mem-bandwidth0,但如果启用了 OpenMP 支持,则会变为 -opt-mem-bandwidth1。 同样,我记得 IBM 编译器在多线程代码的性能启发式方面也有一些类似的变化。我不会对这种选择性行为仍在内部应用感到惊讶,甚至对于 Microsoft 编译器也是如此。