/openmp (啟用 OpenMP 支援)

讓編譯器處理 #pragma omp 支援 OpenMP 的指示詞。

語法

/openmp
/openmp:experimental
/openmp:llvm

/openmp

備註

#pragma omp 用來指定 指示詞 子句 。 如果未 /openmp 在編譯中指定,編譯器會忽略 OpenMP 子句和指示詞。 即使 /openmp 未指定,編譯器仍會處理 OpenMP 函 式呼叫。

C++ 編譯器目前支援 OpenMP 2.0 標準。 Visual Studio 2019 現在也提供 SIMD 功能。 若要使用 SIMD,請使用 /openmp:experimental 選項進行編譯。 此選項同時啟用一般 OpenMP 功能,以及使用 /openmp 參數時無法使用的 OpenMP SIMD 功能。

從 Visual Studio 2019 16.9 版開始,您可以使用實驗 /openmp:llvm 選項,而不是 /openmp 以 LLVM OpenMP 執行時間為目標。 目前不支援生產程式碼,因為必要的 libomp DLL 無法轉散發。 選項支援與 /openmp 相同的 OpenMP 2.0 指示詞。 而且,它支援 選項所 /openmp:experimental 支援的所有 SIMD 指示詞。 它也支援根據 OpenMP 3.0 標準,平行處理迴圈的不帶正負號整數索引。 如需詳細資訊,請參閱 改善 Visual Studio 中 C++ 的 OpenMP 支援。

選項 /openmp:llvm 支援 x64 架構。 從 Visual Studio 2019 16.10 版開始,它也支援 x86 和 ARM64 架構。 此選項與 或 /ZW 不相容 /clr

使用 /openmp/clr 編譯的應用程式只能在單一應用程式域進程中執行。 不支援多個應用程式域。 也就是說,當模組建構函式 ( .cctor ) 執行時,它會偵測是否使用 /openmp 編譯進程,以及應用程式是否載入非預設執行時間。 如需詳細資訊,請參閱 appdomain/clr (Common Language Runtime 編譯) 混合元件的 初始化。

如果您嘗試將同時使用 /openmp/clr 編譯的應用程式載入至非預設應用程式域, TypeInitializationException 則會在偵錯工具外部擲回例外狀況,並在 OpenMPWithMultipleAppdomainsException 偵錯工具中擲回例外狀況。

在下列情況下,也可以引發這些例外狀況:

  • 如果您的應用程式是使用 /clr 編譯,但不是 /openmp ,而且會載入至非預設應用程式域,其中進程包含使用 /openmp 編譯的應用程式。

  • 如果您將 /clr 應用程式傳遞至公用程式,例如 regasm.exe ,它會將其目標群組件載入非預設應用程式域。

Common Language Runtime 的程式碼存取安全性無法在 OpenMP 區域中運作。 如果您在平列區域外套用 CLR 代碼存取安全性屬性,則不會在平列區域中生效。

Microsoft 不建議撰寫 /openmp 允許部分信任呼叫端的應用程式。 請勿使用 AllowPartiallyTrustedCallersAttribute 、 或任何 CLR 程式碼存取安全性屬性。

在 Visual Studio 開發環境中設定這個編譯器選項

  1. 開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性

  2. 展開 [ 組態屬性 > C/C++ > 語言] 屬性頁。

  3. 修改 OpenMP Support 屬性。

若要以程式方式設定這個編譯器選項

範例

下列範例顯示執行緒集區啟動與啟動執行緒集區之後使用執行緒集區的影響。 假設 x64、單一核心、雙處理器,執行緒集區需要大約 16 毫秒才能啟動。 之後,執行緒集區的成本很少。

當您使用 /openmp 進行編譯時,test2 的第二次呼叫永遠不會執行超過您使用 /openmp- 編譯的時間,因為沒有線程集區啟動。 在一百萬次反覆運算中 /openmp ,版本比 /openmp- 第二次呼叫 test2 的版本快。 在 25 次反覆運算中, /openmp-/openmp 版本都會註冊小於時鐘細微性。

如果您的應用程式中只有一個迴圈,且其執行時間小於 15 毫秒(已針對電腦上的近似額外負荷進行調整), /openmp 可能不適合。 如果比較高,您可能想要考慮使用 /openmp

// cpp_compiler_options_openmp.cpp
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

volatile DWORD dwStart;
volatile int global = 0;

double test2(int num_steps) {
   int i;
   global++;
   double x, pi, sum = 0.0, step;

   step = 1.0 / (double) num_steps;

   #pragma omp parallel for reduction(+:sum) private(x)
   for (i = 1; i <= num_steps; i++) {
      x = (i - 0.5) * step;
      sum = sum + 4.0 / (1.0 + x*x);
   }

   pi = step * sum;
   return pi;
}

int main(int argc, char* argv[]) {
   double   d;
   int n = 1000000;

   if (argc > 1)
      n = atoi(argv[1]);

   dwStart = GetTickCount();
   d = test2(n);
   printf_s("For %d steps, pi = %.15f, %d milliseconds\n", n, d, GetTickCount() - dwStart);

   dwStart = GetTickCount();
   d = test2(n);
   printf_s("For %d steps, pi = %.15f, %d milliseconds\n", n, d, GetTickCount() - dwStart);
}

另請參閱

MSVC 編譯器選項
MSVC 編譯器命令列語法
MSVC 中的 OpenMP