/MP (使用多處理序建置)
/MP選項可以減少編譯原始程式檔,在命令列上的總時間。 /MP 選項會使編譯器在不同的處理序中,建立一個或多個本身的複本。 然後這些複本同時編譯原始程式檔。 使得建置原始程式檔的總時間大幅的降低。
/MP[processMax]
引數
processMax
(選擇性) 編譯器可建立的處理序數目上限。processMax 引數必須是在從 1 到 65536 的範圍。 否則,編譯器會發出警告訊息D9014,會略過processMax引數,並假設處理序的最大數目是 1。
如果您略過 processMax 引數,則編譯器會從作業系統擷取電腦上的有效的處理器之數目,並為每一個處理器建立一個處理序。
備註
/MP 編譯器選項可以在您編譯許多檔案時,大幅縮短建置時間。 為了縮短建置時間,編譯器會建立最多processMax本身會複製,並接著使用這些複本同時編譯原始程式檔。 /MP 選項會套用於編譯,但不套用於連結或連結時間的程式碼產生。 預設狀況下**/MP** ] 選項已關閉。
建置時間的改善,必須視電腦上的處理器數目、要編譯的檔案數目、系統資源 (例如 I/O 容量) 是否可用等因素而定。 您可以嘗試 /MP 選項,以決定建置特定專案的最佳設定。 如需建議以輔助您做決定,請參閱使用方針。
不相容的選項和語言功能
/MP 選項與某些編譯器選項和語言功能不相容。 如果您使用的編譯器選項和 /MP 選項不相容,則編譯器會發出警告 D9030,並忽略 /MP 選項。 如果您使用不相容的語言功能時,編譯器會發出錯誤C2813,然後結束或繼續目前的編譯器警告層級的選項而定。
注意事項 |
---|
大部分的選項都不相容,因為如果允許這些選項,則同時執行編譯器時就會同時將輸出寫入至主控台或特定檔案中。結果,輸出就會相互混在一起而且不完整。有時候,結合其他選項還會使效能變得更差。 |
下表列出與 /MP 選項不相容的編譯器選項和語言功能:
選項或語言功能 |
描述 |
---|---|
#import 前置處理器指示詞 |
將型別程式庫中的型別轉換成 C++ 類別,然後將這些類別寫入至標頭檔。 |
將前置處理器輸出複製至標準輸出 (stdout)。 |
|
允許累加重新建置。 |
|
將 Include 檔的清單寫入至標準錯誤 (stderr)。 |
|
寫入先行編譯的標頭檔。 |
診斷訊息
如果您指定與 /MP 選項不相容的選項或語言功能,就會收到診斷訊息。 下表列出編譯器的訊息和行為:
診斷訊息 |
描述 |
編譯器行為 |
---|---|---|
C2813 |
#import 指示詞與 /MP 選項不相容。 |
除非另外指定編譯器警告層級選項,否則編譯就會結束。 |
D9014 |
為 processMax 引數指定了無效值。 |
編譯器會忽略無效值,並假設值為 1。 |
D9030 |
指定的選項與 /MP 不相容。 |
編譯器會忽略 /MP 選項。 |
方針
測量效能
使用總建置時間來測量效能。 您可以使用實體時鐘來計算建置時間,或使用軟體來計算建置開始到停止間的時間差。 如果您的電腦有多個處理器,則以實體時鐘計算出來的時間可能比軟體時間測量更精確。
有效的處理器
電腦的每一個實體處理器都可以有一個或多個虛擬處理器,又稱為有效的處理器。 每一個實體處理器都可以有一個或多個核心,而且如果作業系統允許核心的超執行緒,則每一個核心都會顯示成兩個虛擬處理器。
例如,如果電腦有一個實體處理器,而處理器有一個核心且停用超執行緒,則該電腦會有一個有效的處理器。 相反地,如果電腦有兩個實體處理器,每一個都有兩個核心,且所有核心都啟用超執行緒,則這部電腦就有八個有效的處理器。 也就是,(8 個有效的處理器) = (2 個實體處理器) x (每個實體處理器有 2 個核心) x (因為超執行緒,所以每個核心都有 2 個有效的處理器)。
如果您在 /MP 選項中略過 processMax 引數,則編譯器會取得作業系統中有效處理器的數目,然後為每個有效的處理器建立一個處理序。 但是,編譯器無法保證哪個處理序會在特定處理器上執行,這是由作業系統決定。
處理序的數目
編譯器會計算要用來編譯原始程式檔的處理序數目。 您在命令列上所指定的原始程式檔數目,以及使用 /MP 選項明確或隱含指定的處理序數目,兩者中較小的那個數目就是處理序的數目值。 如果您提供 /MP 選項的 processMax 引數,就可以明確設定處理序數目的最大值。 或者,如果您略過 processMax 引數,可以使用預設值,也就是電腦中的有效處理器之數目。
例如,假設您指定下列命令列:
cl /MP7 a.cpp b.cpp c.cpp d.cpp e.cpp
在此情況下,編譯器會使用五個處理序,因為五個原始程式檔和最多七個處理序這兩個數字中,這是較小的數目。 或者,假設您的電腦有兩個有效的處理器,而且您指定下列命令列:
cl /MP a.cpp b.cpp c.cpp
此時,作業系統會報告兩個處理器,因此編譯器會在計算中使用兩個處理序。 結果,編譯器會使用兩個處理序來執行建置,因為兩個處理序和三個原始程式檔這兩個數字中,這是較小的數目。
原始程式檔和建置順序
原始程式檔編譯的順序,可能和它們出現在命令列中的順序不同。 雖然編譯器會建立一組處理序,內含編譯器的複本,但是作業系統會排程每一個處理序何時執行。 因此,您無法保證原始程式檔會以特定順序編譯。
當處理序可用來編譯時,就會編譯原始程式檔。 如果檔案比處理序還多,可用的處理序就會編譯第一組檔案。 當處理序處理完前一個檔案,且可以再處理其中一個剩下的檔案時,就會處理剩下的檔案。
請勿在命令列上多次指定相同的原始程式檔。 如果工具自動建立 makefile (根據專案中的相依性資訊),就可能會發生這種情況。 如果您不指定 /MP 選項,則編譯器會依序處理檔案清單,並重新編譯檔案。 但是,如果您指定 /MP 選項,則不同的編譯器可能會同時編譯同一個檔案。 因此,不同的編譯器會同時嘗試寫入同一個輸出檔。 一個編譯器會取得輸出檔的獨佔寫入權限並成功,另一個編譯器則會失敗並發生檔案存取錯誤。
使用型別程式庫 (#import)
編譯器不支援使用 #import 指示詞搭配 /MP 參數。 如果可以,請遵循這些步驟來解決這個問題:
將各原始程式檔中的所有 #import 指示詞移動至一個或多個檔案,然後不使用 /MP 選項編譯這些檔案。 結果會產生一組標頭檔。
在剩下的原始程式檔中,插入 #include 指示詞 (指定產生的標頭),然後使用 /MP 選項編譯剩下的原始程式檔。
Visual Studio 專案設定
MSBUILD.exe 工具
Visual Studio 會使用 MSBuild.exe 工具來建置方案和專案。 MSBuild.exe 工具 的 **/maxcpucount:number(或/m:**number) 命令列選項可以同時組建多個專案。 /MP 編譯器選項同時組建多個編譯單位。 如果適合您的應用程式,請使用 /MP 或 /maxcpucount 或兩者一起使用,以改善您的方案建置時間。
方案的建置時間,部分需視執行建置的處理序之數目而定。 /maxcpucount MSBuild 選項的 number 引數會指定要同時建置的專案數目上限。 同樣地,/MP 編譯器選項的 processMax 引數會指定要同時建置的編譯單位數目上限。 如果 /maxcpucount 選項指定 P 專案,而 /MP 選項指定 C 處理序,則最多 P x C 個處理序會同時執行。
決定是否使用 MSBuild 或 /MP 技術的方針如下:
如果每個專案內都只有幾個檔案,請使用 MSBuild 工具。
如果有少數幾個專案有很多檔案,請使用 /MP 選項。
如果專案數目及每個專案的檔案數目平衡,請使用 MSBuild 和 /MP。 一開始,將 /maxcpucount 選項設定為要建置的專案數目,/MP 選項則設定為電腦上的處理器數目。 測量效能然後調整設定,以產生最佳結果。 重複這個循環,直到您滿意總建置時間為止。
/Gm 編譯器選項
根據預設,專案建置會針對偵錯組建 (Debug Build) 啟用 /Gm 編譯器選項 (累加建置),針對發行的組件 (Release Build) 則停用此選項。 因此,偵錯組建中的 /MP 編譯器選項會自動停用,因為這個選項和預設的 /Gm 編譯器選項衝突。