共用方式為


自動平行處理錯誤和警告

Auto-Parallelizer 和 Auto-Vectorizer 的設計目的是為您程式碼中的迴圈提供自動效能提升。

Auto-Parallelizer

/Qpar 編譯器參數可讓您程式碼中的迴圈進行自動平行處理。 當您指定這個旗標而不變更現有的程式碼時,編譯器便會評估程式碼,以尋找可能受益於平行處理的迴圈。 因為它可能會發現沒有什麼作用、因此不會受益於平行處理的迴圈,而且,因為每個不必要的平行處理可能會引起執行緒集區繁衍 (Sprawning)、額外的同步處理,或其他容易導致效能變慢 (而非改善效能) 的處理序,所以編譯器會保守地選取它平行處理的迴圈。 下列範例中,在編譯期間,迴圈的上限為未知:

void loop_test(int u) {
   for (int i=0; i<u; ++i)
      A[i] = B[i] * C[i];
}

因為 u 可能是較小的值,所以編譯器不會自動平行處理此迴圈。 不過,您可能仍想將它平行處理,因為您知道 u 永遠會是大的值。 若要啟用自動平行處理,請指定 #pragma loop(hint_parallel(n)),其中 n 是要平行處理的執行緒數目。 在下列範例中,編譯器會嘗試在 8 個執行緒之間平行處理迴圈。

void loop_test(int u) {
#pragma loop(hint_parallel(8))
   for (int i=0; i<u; ++i)
      A[i] = B[i] * C[i];
}

如同所有 pragma 指示詞,也支援替代的 pragma 語法__pragma(loop(hint_parallel(n)))。

對於部分迴圈,即使您希望平行處理它們,編譯器仍無法處理。 以下為範例:

#pragma loop(hint_parallel(8))
for (int i=0; i<upper_bound(); ++i)
    A[i] = B[i] * C[i];

每次呼叫函式 upper_bound() 時,它可能會有所變更。 因為無法知道上限,編譯器可發出診斷訊息,說明它為何無法平行處理此迴圈。 下列範例將展示可平行處理的迴圈、無法平行處理的迴圈、在命令提示字元中使用的編譯器語法,以及每個命令列選項的編譯器輸出:

int A[1000];
void test() {
#pragma loop(hint_parallel(0))
    for (int i=0; i<1000; ++i) {
        A[i] = A[i] + 1;
    }

    for (int i=1000; i<2000; ++i) {
        A[i] = A[i] + 1;
    }
}

使用下列命令進行編譯:

cl d:\myproject\mylooptest.cpp /O2 /Qpar /Qpar-report:1

會產生以下輸出:

--- Analyzing function: void __cdecl test(void)
d:\myproject\mytest.cpp(4) : loop parallelized

使用下列命令進行編譯:

cl d:\myproject\mylooptest.cpp /O2 /Qpar /Qpar-report:2

會產生以下輸出:

--- Analyzing function: void __cdecl test(void)
d:\myproject\mytest.cpp(4) : loop parallelized
d:\myproject\mytest.cpp(4) : loop not parallelized due to reason '1008'

請注意兩個不同 /Qpar-report (自動平行化工具報告層級) 選項之間的輸出差異。 /Qpar-report:1 只會針對平行處理成功的迴圈輸出平行化工具訊息。 /Qpar-report:2 會對平行處理成功和失敗的迴圈輸出平行化工具訊息。

如需原因碼和訊息的詳細資訊,請參閱向量化工具和平行化工具訊息

自動向量化工具

自動向量化工具會分析您程式碼中的迴圈,並嘗試在目標電腦上使用向量暫存器和指令,以執行這些迴圈。 這可以改善您程式碼的效能。 根據 /arch 參數而定,編譯器會以 Intel 或 AMD 處理器中的 SSE2、AVX 和 AVX2 指令,或是 ARM 處理器上的 NEON 指令為目標。

自動向量化工具可能會產生不同的指令,而非 /arch 參數所指定的指令。 這些指令受執行階段檢查保護,以確定該程式碼仍然能夠正確執行。 例如,當您編譯 /arch:SSE2 時,可能會發出 SSE4.2 指令。 執行階段檢查會驗證目標處理器是否適用 SSE4.2,若該處理器不支援這些指令的話,便會跳到非 SSE4.2 版本的迴圈。

根據預設,會啟用自動向量化工具。 如果您想要比較您的程式碼在向量化之後的效能,可以使用 #pragma loop(no_vector) 來針對任何特定迴圈停用向量化。

#pragma loop(no_vector)
for (int i = 0; i < 1000; ++i)
   A[i] = B[i] + C[i];

如同所有 pragma 指示詞,也支援替代的 pragma 語法__pragma(loop(no_vector))。

如同 Auto-Parallelizer 一般,您可以指定 /Qvec-report (自動向量化工具報告層級) 命令列選項,藉此僅報告向量化成功的迴圈 —/Qvec-report:1— 或是向量化成功和失敗迴圈 —/Qvec-report:2)。

如需原因碼和訊息的詳細資訊,請參閱向量化工具和平行化工具訊息

如需展現向量化工具如何運作的範例,請參閱 Project Austin 的第 2 部分 (共 6 個部分):頁面捲曲

請參閱

參考

迴圈

/Qpar (自動平行化工具)

/Qpar-report (自動平行化工具報告層級)

/Qvec-report (自動向量化工具報告層級)

其他資源

使用機器碼的平行程式設計

向量化工具和平行化工具訊息