Microsoft MVP성태의 닷넷 이야기
VS.NET IDE: 49. Orcas - VC++ 다중 소스 동시 컴파일 옵션: /MP [링크 복사], [링크+제목 복사],
조회: 28087
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

Orcas - VC++ 다중 소스 동시 컴파일 옵션: /MP


컴파일 옵션만큼은... VC++이 .NET보다는 앞서 있습니다.
일례로, 다중 코어(또는 하이퍼쓰레딩)에 따른 다중 프로젝트 동시 컴파일은 VS.NET 2005에서 VC++이 지원을 해주던 것을, .NET 프로젝트는 Orcas에 와서야 해주게 되었지요.

그런데, Orcas에서의 VC++는 한 걸음 더 나아가고 있습니다. 이젠 프로젝트 수준이 아닌, "소스 파일" 수준에서 동시 컴파일을 지원합니다. 이에 대해서는 다음에서 설명해 주고 있습니다.

차세대 Visual C++의 내부 살펴보기 - 사용자 계정 컨트롤을 위한 준비
; http://msdn.microsoft.com/msdnmag/issues/07/06/Cpp/default.aspx?loc=ko#S8

오... 멋집니다. ^^
아직은 베타 버전이라서 그런지 VC++ 프로젝트 속성창에서는 "/MP" 스위치에 대한 명시적인 옵션이 제공되지 않고 다음과 같이 직접 지정을 해야 사용이 가능합니다.

cl_new_mp_option_1.png




기대에 부풀어서, 이제 빌드 명령을 내려 보았습니다. 역시나... 딱 한방에 되진 않는군요. 어쩌겠습니까??? 하나씩 해결해 나가는 수밖에. ^^

1. /Gm (Enable Minimal Rebuild)
우선, 첫 번째... "/Gm" 옵션이 문제였습니다. 해당 컴파일러 스위치가 같이 사용되는 경우 다음과 같은 경고가 발생합니다.

cl : Command line warning D9030 : '/Gm' is incompatible with multiprocessing; ignoring /MP switch

왠지 아깝지만... 해당 프로젝트의 속성창에서 "C/C++" / "Code Generation" 범주의 "Enable Minimal Rebuild" 옵션을 해제했습니다.

2. /Yc (Create Precompiled Header File)
/Yc 옵션이 붙은 경우에도 다음과 같은 경고가 발생합니다.

cl : Command line warning D9030 : '/Yc' is incompatible with multiprocessing; ignoring /MP switch

이 옵션은 ...? 별도로 설정한 것이 없어서 난감하더군요. 아직 베타 버전이라 그런지 /Yc 옵션에 대한 판단에 버그가 있는 것 같습니다. 어느 경우에는 새로 빌드하면 위와 같은 경고가 발생하다가도, 어느 순간 이후부터는 경고가 사라졌습니다.

분명한 것은, /Yc 옵션이 stdafx.cpp 파일 이외에 지정이 되었다면 조정이 되어야 한다는 것.

3. #import 사용
보통, 외부 COM 개체를 사용하는 경우, 다음과 같은 식의 #import 구문을 이용해서 참조를 하게 되지요.

#import ".\ExternalCom.dll"

그런데, 이 옵션으로 인해 다음과 같은 오류가 발생하게 됩니다.

d:\...\test.h(265) : error C2813: #import is not supported with /MP

음... 이건 좀 불편하게 되었군요. 그런데, 가만 보니 모든 #import 구문에서 오류가 나는 것은 아니었습니다. 오호... stdafx.h 파일에서 정의된 #import에서는 오류가 안나고, 그 이외의 파일들에서는 오류가 나는군요. /MP 스위치를 이용해서 빌드를 해보면 알게 되지만, "precompiled-header" 파일을 생성해 내는 stdafx.cpp 파일인 경우에는 다른 C/C++ 파일들과 동시에 빌드되지 않는다는 점을 발견하게 됩니다. 따라서, #import 구문이 stdafx.h 파일에 있는 경우에는 다중 소스 컴파일 기능에 영향을 미치지 않기 때문에 오류가 안 나는 것이었습니다.

이 때문에, 각 소스 파일에 흩어져 있던 #import를 이용한 COM 개체 소스 생성 구문을 stdafx.h 파일로 모았습니다.




일단,,, 제가 만든 프로젝트들에서는 위와 같은 정도의 충돌만 있었을 뿐이었습니다. 모두 수정하고 나니 정상적으로 다중 소스 컴파일이 지원되었습니다. 우와~~~ ^^.

자... 이제 결과를 보기 위해. 최대한 환경을 동일하게 하기 위해서 - 디스크 캐쉬라든가 - 우선, "Clean Solution" 메뉴를 이용해서 모든 파일을 제거한 다음에 빌드를 새로 했습니다. 그다음에 다시 "Rebuild Solution" 메뉴를 이용해서 빌드를 할 때 시간을 재보았습니다.

각각 Debug 모드로 빌드했고 - 현실적으로 개발시에 가장 빈번히 빌드되는 유형이므로 - 한 번은 /MP 스위치를 주고, 한 번은 주지 않는 식으로 테스트해서 7개의 프로젝트를 가진 솔루션을 대상으로 테스트했습니다.

/MP 스위치 있을 때: 1분 42초
/MP 스위치 없을 때: 2분 11초

흠... 29초라... 기대했던 만큼은 많이 차이가 나지 않는 군요. 사실, 생각해 보면 그다지 차이가 나지 않을 법한 이유를 알게 됩니다.

왜냐하면, 이미 VS.NET 2005부터 "다중 프로젝트 동시 컴파일"을 지원하고 있었지요. 그래서, "프로젝트 의존성"이 없는 한은 (2개의 CPU 코어가 있는 경우를 가정하면,) 2개의 프로젝트를 동시에 빌드하고 있었습니다. 즉, "/MP" 스위치가 빛을 발하는 시점은, "프로젝트 의존성"으로 인해 빌드가 "직렬"로 단일 프로젝트만 대상이 되어 빌드 수행 시에 C/C++ 파일을 2개씩 동시 컴파일을 하게 되는 경우입니다.

그래서, 빌드와 함께 CPU 모니터링을 하면 재미있는 현상을 볼 수 있습니다. /MP 스위치가 있는 경우에는 거의 항상 CPU가 100%를 치고 있는 반면, /MP 스위치가 없는 경우에는 다중 프로젝트 빌드 시에는 100%를 치고 있다가도 의존성으로 인한 단일 프로젝트 빌드로 진입하게 되면 50%로 떨어지게 됩니다.

좀 더 확실한 결과를 얻기 위해서 단일 프로젝트를 대상으로만 한정지어서 빌드를 다시 해본 결과는 다음과 같았습니다.

/MP 스위치 있을 때: 46초
/MP 스위치 없을 때: 59초

음... ^^; 일단 13초에 만족합시다.




정리해 볼까요?

어찌 보면, /MP 스위치를 모든 프로젝트에 사용할 필요는 없어 보입니다. 왜냐하면 "다중 프로젝트 동시 빌드"가 이뤄지는 시점에는 /MP 스위치가 필요 없기 때문입니다. 따라서, 자신의 VC++ 솔루션을 빌드하면서 의존성으로 인한 단일 프로젝트 빌드만을 찾아내서 /MP 스위치를 적용하는 것도 현명할 수 있습니다.

하지만, 언제나 솔루션 단위의 빌드를 하는 것은 아니죠. 대개의 경우 하나의 프로젝트만을 대상으로 하면서 그 프로젝트 하나만을 다시 빌드하는 경우도 많기 때문에. 그것을 생각해 보면 모든 프로젝트에 /MP 스위치를 적용시키는 것도 좋을 것 같습니다.

크게 만족스러운 성능 차이는 아니지만. 그래도 VC++ 컴파일러의 이러한 꾸준한 노력이 마음에 듭니다. ^^



[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 7/17/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 106  [107]  108  109  110  111  112  113  114  115  116  117  118  119  120  ...
NoWriterDateCnt.TitleFile(s)
11249정성태7/12/201718537오류 유형: 410. LoadLibrary("[...].dll") failed - The specified procedure could not be found.
11248정성태7/12/201725033오류 유형: 409. pip install pefile - 'cp949' codec can't decode byte 0xe2 in position 208687: illegal multibyte sequence
11247정성태7/12/201719375오류 유형: 408. SqlConnection 객체 생성 시 무한 대기 문제파일 다운로드1
11246정성태7/11/201718139VS.NET IDE: 118. Visual Studio - 다중 폴더에 포함된 파일들에 대한 "Copy to Output Directory"를 한 번에 설정하는 방법
11245정성태7/10/201723765개발 환경 구성: 321. Visual Studio Emulator for Android 소개 [2]
11244정성태7/10/201723313오류 유형: 407. Visual Studio에서 ASP.NET Core 실행할 때 dotnet.exe 프로세스의 -532462766 오류 발생 [1]
11243정성태7/10/201720001.NET Framework: 666. dotnet.exe - 윈도우 운영체제에서의 .NET Core 버전 찾기 규칙
11242정성태7/8/201720274제니퍼 .NET: 27. 제니퍼 닷넷 적용 사례 (7) - 노후된 스토리지 장비로 인한 웹 서비스 Hang (멈춤) 현상
11241정성태7/8/201719023오류 유형: 406. Xamarin 빌드 에러 XA5209, APT0000
11240정성태7/7/201721953.NET Framework: 665. ClickOnce를 웹 브라우저를 이용하지 않고 쿼리 문자열을 전달하면서 실행하는 방법 [3]파일 다운로드1
11239정성태7/6/201723426.NET Framework: 664. Protocol Handler - 웹 브라우저에서 데스크톱 응용 프로그램을 실행하는 방법 [5]파일 다운로드1
11238정성태7/6/201720945오류 유형: 405. NT 서비스 시작 시 "Error 1067: The process terminated unexpectedly." 오류 발생 [2]
11237정성태7/5/201722603.NET Framework: 663. C# - PDB 파일 경로를 PE 파일로부터 얻는 방법파일 다운로드1
11236정성태7/4/201725842.NET Framework: 662. C# - VHD/VHDX 가상 디스크를 마운트하지 않고 파일을 복사하는 방법파일 다운로드1
11235정성태6/29/201719967Math: 20. Matlab/Octave로 Gram-Schmidt 정규 직교 집합 구하는 방법
11234정성태6/29/201717310오류 유형: 404. SharePoint 2013 설치 과정에서 "The username is invalid The account must be a valid domain account" 오류 발생
11233정성태6/28/201717226오류 유형: 403. SharePoint Server 2013을 Windows Server 2016에 설치할 때 .NET 4.5 설치 오류 발생
11232정성태6/28/201718228Windows: 144. Windows Server 2016에 Windows Identity Extensions을 설치하는 방법
11231정성태6/28/201718842디버깅 기술: 86. windbg의 mscordacwks DLL 로드 문제 - 세 번째 이야기 [1]
11230정성태6/28/201718021제니퍼 .NET: 26. 제니퍼 닷넷 적용 사례 (6) - 잦은 Recycle 문제
11229정성태6/27/201719255오류 유형: 402. Windows Server Backup 관리 콘솔이 없어진 경우
11228정성태6/26/201716718개발 환경 구성: 320. Visual Basic .NET 프로젝트에서 내장 Manifest 자원을 EXE 파일로부터 제거하는 방법파일 다운로드1
11227정성태6/19/201724468개발 환경 구성: 319. windbg에서 python 스크립트 실행하는 방법 - pykd [6]
11226정성태6/19/201716328오류 유형: 401. Microsoft Edge를 실행했는데 입력 반응이 없는 경우
11225정성태6/19/201715642오류 유형: 400. Outlook - The required file ExSec32.dll cannot be found in your path. Install Microsoft Outlook again.
11224정성태6/13/201718132.NET Framework: 661. Json.NET의 DeserializeObject 수행 시 속성 이름을 동적으로 바꾸는 방법파일 다운로드1
... 106  [107]  108  109  110  111  112  113  114  115  116  117  118  119  120  ...