Microsoft MVP성태의 닷넷 이야기
VS.NET IDE: 49. Orcas - VC++ 다중 소스 동시 컴파일 옵션: /MP [링크 복사], [링크+제목 복사],
조회: 28074
글쓴 사람
정성태 (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

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  127  [128]  129  130  131  132  133  134  135  ...
NoWriterDateCnt.TitleFile(s)
1855정성태2/10/201520747개발 환경 구성: 256. WebDAV Redirector - Sysinternals 폴더 연결 시 "The network path was not found" 오류 해결 방법
1854정성태2/10/201521720Windows: 104. 폴더는 삭제할 수 없지만, 그 하위 폴더/파일은 생성/삭제/변경하는 보안 설정
1853정성태2/6/201552045웹: 29. 여신금융협회 웹 사이트의 "Netscape 6.0은 지원하지 않습니다." 오류 메시지 [5]
1852정성태2/5/201522438.NET Framework: 492. .NET CLR Memory 성능 카운터의 의미파일 다운로드1
1851정성태2/5/201523368VC++: 88. 하룻밤의 꿈 - 인텔 하스웰의 TSX Instruction 지원 [2]
1850정성태2/4/201544168Windows: 103. 작업 관리자에서의 "Commit size"가 가리키는 메모리의 의미 [4]
1849정성태2/4/201524129기타: 51. DropBox의 CPU 100% 현상 [1]파일 다운로드1
1848정성태2/4/201519370.NET Framework: 491. 닷넷 Generic 타입의 메타 데이터 토큰 값 알아내는 방법 [2]
1847정성태2/3/201522681기타: 50. C# - 윈도우에서 dropbox 동기화 폴더 경로 및 종료하는 방법
1846정성태2/2/201531987Windows: 102. 제어판의 프로그램 추가/삭제 항목을 수동으로 실행하고 싶다면? [1]
1845정성태1/26/201532865Windows: 101. 제어판의 "Windows 자격 증명 관리(Manage your credentials)"를 금지시키는 방법
1844정성태1/26/201530829오류 유형: 269. USB 메모리의 용량이 비정상적으로 보여진다면? [7]
1843정성태1/24/201521864VC++: 87. 무시할 수 없는 Visual C++ 런타임 함수 성능
1842정성태1/23/201544348개발 환경 구성: 255. 노트북 키보드에 없는 BREAK 키를 다른 키로 대체하는 방법
1841정성태1/21/201519329오류 유형: 268. Win32 핸들 관련 CLR4 보안 오류 사례
1840정성태1/8/201527557오류 유형: 267. Visual Studio - CodeLens 사용 시 CPU 100% 현상
1839정성태1/5/201520443디버깅 기술: 69. windbg 분석 사례 - cpu 100% 현상 (2)
1838정성태1/4/201540198기타: 49. 윈도우 내레이터(Narrator) 기능 끄는 방법(윈도우에 파란색의 굵은 테두리 선이 나타난다면?) [4]
1837정성태1/4/201526319디버깅 기술: 68. windbg 분석 사례 - 메모리 부족 [1]
1836정성태1/4/201526320디버깅 기술: 67. windbg - 덤프 파일과 handle 정보
1835정성태1/3/201526797개발 환경 구성: 254. SQL 서버 역시 SSL 3.0/TLS 1.0만을 지원하는 듯!
1834정성태1/3/201551430개발 환경 구성: 253. TLS 1.2를 적용한 IIS 웹 사이트 구성
1833정성태1/3/201527481.NET Framework: 490. System.Data.SqlClient는 SSL 3.0/TLS 1.0만 지원하는 듯! [3]
1832정성태1/2/201520563오류 유형: 266. Azure에 응용 프로그램 게시 중 로그인 오류
1831정성태1/1/201528452디버깅 기술: 66. windbg 분석 사례 - cpu 100% 현상 (1) [1]
1830정성태1/1/201527490오류 유형: 265. svchost.exe 프로세스(IP Helper: IPHLPSVC)의 CPU 100% 현상
... 121  122  123  124  125  126  127  [128]  129  130  131  132  133  134  135  ...