기술자료

DBMS, DB 구축 절차, 빅데이터 기술 칼럼, 사례연구 및 세미나 자료를 소개합니다.

비주얼 C++와 함께하는 코드 생산성 향상 팁 ③

기술자료
DBMS별 분류
Etc
작성자
dataonair
작성일
2016-01-28 00:00
조회
4177


◎ 연재기사 ◎


비주얼 스튜디오 2015 활용 가이드 : 비주얼 C++와 함께하는 코드 생산성 향상 팁 ①


비주얼 스튜디오 2015 활용 가이드 : 비주얼 C++와 함께하는 코드 생산성 향상 팁 ②


비주얼 C++와 함께하는 코드 생산성 향상 팁 ③



비주얼 스튜디오 2015 활용 가이드

비주얼 C++와 함께하는 코드 생산성 향상 팁 ③



빌드 2015(build 2015) 행사를 통해 밝혀진 새로운 비주얼 스튜디오는 파이썬 언어를 기본으로 지원할 뿐 아니라 안드로이드와 iOS 앱 개발이 가능한 크로스 플랫폼 환경으로 진화했다. 그간 개발자들이 손꼽아 기다려온 새 기능들과 더불어 C++ 표준 도입이 더 확대되고 개발 편의성과 생산성을 높여주도록 개발 환경도 업데이트됐다. 비주얼 C++와 함께하는 코드 생산성 향상 팁, 그 마지막 시간에는 개발 효율성을 높이는 새로운 기능을 실습을 통해 살펴보고 프로젝트에 적용하는 법을 함께 고민해본다.



비주얼 스튜디오 2015에 포함된 비주얼 C++는 향상된 컴파일러와 함께 크로스 플랫폼, 표준 C++ 문법 지원이 강화됐다. 또한 보다 편리하고 효율적으로 SW를 개발할 수 있도록 IDE의 기능도 개선됐다. 지난 연재에 이어 이번 시간에도 비주얼 C++의 새로운 변화를 점검해보고 유용합 팁만을 선별해 소개한다.



보다 스마트해진 컴파일러의 최적화

임베디드 장치나 일부 특수한 상황이 아닌 경우 최신 컴파일러를 썼을 때 가장 최적화(General Optimaizations)된 결과물을 얻을 수 있다. 마이크로소프트(MS)의 컴파일러 개발자들은 그간 일반적인 소스 코드에 대한 최적화를 주로 연구하고, 이를 컴파일러에 반영해 왔다. 그러므로 컴파일러는 예외적인 상황이 아닌 일반적인 상황에 맞춰 최적화되고, 가장 최상의 결과물을 생성해 낸다.

새 비주얼 스튜디오 컴파일러에는 새로운 최적화 기법이 여럿 추가됐다. 그 중 가장 흥미로운 것은 다름아닌 루프-if 문 언스위칭(Loop-if Unswitching)이다. 이 최적화 기법은 if 문의 영향을 받는 루프 코드가 있으면 루프 코드 밖으로 if 문을 옮겨 루프 문을 수행할 때 반복적으로 if 문이 수행되는 것을 막아준다(<리스트 1> 참조).



<리스트 1> 루프-if 문 언스위칭 최적화 예
// 소스 코드
for (int i = 0; i < 100; i++)
if (some_invariant_condition)
...// 최적화된 코드
if (some_invariant_condition)
for (int i = 0; i < 100; i++)
...



또한 제어 흐름 벡터화(Vectorization of control flow)는 if-then-else 구문이 있을 때 루프 구문을 분석하고 벡터화해 최적화한다. if 문을 인식해 값의 변화를 추적함으로써 코드 수행 시간을 단축시킨다(<리스트 2> 참조).



<리스트 2> 제어 흐름 벡터화를 통한 최적화 예// 소스 코드
void blackscholes(float* input, int *signArray, int n) {
for (int i = 0; i < n; i++) {
float InputX = input[i];
int sign;
if (InputX < 0.0f) {
InputX = -InputX;
sign = 1;
} else {
sign = 0;
}
input[i] = InputX;
signArray[i] = sign;
}
}
// 최적화된 코드
void blackscholes(float* input, int *signArray, int n) {
for (int i = 0; i < n; i++) {
float InputX = input[i];
int sign;
mask = InputX < 0.0f 0xFFFFFFFF : 0;
InputX = (mask & -InputX) | (~mask & InputX);
sign = (mask & 1) | (~mask & 0);
input[i] = InputX;
signArray[i] = sign;
}
}



비트 필드를 다루는 코드가 연속적으로 있을 때가 있다. 새 비주얼 스튜디오에는 해당 코드의 비트 필드의 연관관계를 파악해 최적화하는 비트 테스트 머징(Bit-test merging) 기능도 추가됐다(<리스트 3> 참조).



<리스트 3>비트 테스트 머징 최적화의 예// 소스 코드
if ((((data->bitfield >> 3) & 1) != 0) ||
(((data->bitfield >> 6) & 1) != 0) ||
(((data->bitfield >> 9) & 1) != 0) ||
(((data->bitfield >> 4) & 1) != 0) ||
(((data->bitfield >> 8) & 1) != 0)) {
...
}// 최적화된 코드
if ((data->bitfield & 0x1258) != 0) {
...
}



그밖에도 이전 컴파일러 보다 향상되고 폭넓어진 벡터화 지원, Parallel STL 라이브러리의 최적화 지원 등 여러 최적화 방식이 추가됐다. 이를 통해 기존 프로젝트나 소스 코드를 최신 비주얼 스튜디오로 다시 컴파일하는 것만으로도 성능 향상 효과를 얻을 수 있다.



빨라진 컴파일 속도

비주얼 스튜디오 2015의 비주얼 C++는 빌드 속도가 눈에 띄게 향상됐다. 그 중에서도 특히 링커의 수행 시간이 몰라보게 단축됐다. 이밖에도 PDB 정보를 생성하는 방법과 함께 단일 스레드 방식의 링커가 멀티스레드로 변경됐다. 링커 내부에 병목현상이 있던 부분도 수정돼 링커 속도가 크게 빨라진 점도 새로운 변화다.

컴파일러의 템플릿 처리 속도 향상도 주목된다. 템플릿 코드가 많이 포함돼 있는 언리얼4를 컴파일했을 때 비주얼 스튜디오 2013는 5283초, 비주얼 스튜디오 2015는 3811초로, 약 38%나 컴파일 속도가 빨라졌다. 또 정적 라이브러리를 많이 사용하는 프로젝트인 경우 정적 라이브러리 처리 속도가 향상돼 전체 컴파일 성능과 소요 시간 측면에서도 더 나은 속도를 경험할 수 있다.



tech_img4270.bmp

더욱 유용해진 에러 창

비주얼 스튜디오 2013의 에러 리스트 창(Error List Window)은 에러, 경고, 메시지 리스트를 토글 형태의 버튼으로 선택해야 원하는 항목을 볼 수 있었다. 에러 리스트 내 검색도 지원했다. 출력창(Output Window)을 통해 컴파일러의 에러 메시지를 참고하는 것보다 에러 메시지를 한눈에 확인할 수 있어 유용했다. 이 덕분에 디버깅 시 기본으로 보여지는 창이 아님에도 불구하고 개발자들이 가장 즐겨 쓰는 인기 기능이 됐다. 그렇다고 단점이 없는 것은 아니다. 빌드 툴 체인을 관장하는 MSBuild와 인텔리센스 엔진에서 발생하는 항목들이 모두 혼합된 선별해 보기에는 불편했다. 그런데 이 불편이 마침내 개선됐다.

tech_img4271.bmp

비주얼 스튜디오 2015에는 에러, 경고, 메시지를 토글 형태로 구분해 보여줄 뿐 아니라 컴파일 과정에서 발생하는 MSBuild의 메시지와 인텔리센스 엔진에서 발생하는 메시지를 구분해 볼 수 있는 옵션이 추가됐다.

tech_img4272.bmp
tech_img4273.bmp

또한 에러 항목을 보여줄 범위도 열려있는 문서 전체, 현재 프로젝트, 현재 문서뿐만 아니라 전체 솔루션을 선택할 수 있게 됐다(<그림 4> 참조).

tech_img4274.bmp



예외 설정

실행 중인 애플리케이션에서 엑세스 바이얼레이션(Access Violation)과 같은 예외가 발생하면 소스 코드상의 예외를 처리할 수 있는 핸들러가 호출된다. 만일 처리하지 못한다면 프로그램 수행이 중단되는 게 일반적이다. 디버깅 중이면 예외는 디버거가 먼저 받아 처리한다. 이 경우 개발자는 디버거를 통해 확인할 예외 종류를 선택할 수 있다.

tech_img4275.bmp
이전 버전의 예외 설정 창은 모달 창(Modal Window)이었다. 그렇기 때문에 디버깅 작업과 함께 수행하거나 작업 중에 수시로 설정 내용을 변경하는 것이 불편했다. 반면 비주얼 스튜디오 2015의 예외 설정 창은 모달리스 창(Modaless Windows)으로 바뀌었다. 디버깅 중 또는 개발 작업 및 성능 측정을 진행하는 중에도 처리해야 할 예외를 설정하고 확인할 수 있다.

tech_img4276.bmp
비주얼 스튜디오는 많은 개발 언어를 지원한다. 프로젝트나 애플리케이션은 많은 언어가 혼용돼 구성될 수 있으며, 네이티브와 닷넷 프레임워크, 웹개발 모두를 지원한다. 각 개발 환경마다 혹은 언어별, 프레임워크별로 발생하는 예외가 있을 수 있기 때문에 비주얼 스튜디오가 받아 확인할 수 있는 예외의 종류가 많다. 자연스레 예외 설정 창에서 선택할 수 있는 항목도 많아졌다.

이렇게 많은 예외 중 원하는 예외를 찾아 활성화시키려면 필터와 검색 기능을 이용해야 할 것이다. 필터를 이용해 현재 활성화돼 있는 익셉션 항목의 리스트를 확인할 수 있고, 바로 사용 가능하도록 노출된 입력창에서 예외 종류를 쉽게 찾을 수도 있다.



진단 도구

애플리케이션을 개발 시 닷넷 프레임워크나 자바를 이용하지 않고 비주얼 C++로 네이티브 애플리케이션을 만든다면, 그 이유는 C나 C++로 된 기존의 소스 코드를 재활용하거나 빠른 속도 혹은 많은 연산이 필요한 로직이 필요해서다. 네이티브 애플리케이션은 일반적으로 가비지 컬렉션을 사용하지 않고 운영체제가 제공하는 자원을 낮은 레벨로 접근하다보니 항상 자원을 정확하고 올바르게 사용했는지가 관건이다. 상속받은 클래스의 소멸자에 virtual 속성이 없거나 DeleteObject를 생략하고, new와 delete의 쌍이 맞지 않는 등 경험이 많은 개발자라도 실수의 여지가 많았다. 애플리케이션을 배포하기 전에 진단 도구(Diagnostics Tools)를 사용하면 추후 발생할 수 있는 이러한 문제를 미리 방지할 수 있다. 상용 진단 도구로는 데브파트너(Dev Partner) 제품 등이 널리 쓰이고 있다.

tech_img4277.bmp

비주얼 스튜디오에는 CPU, 메모리, GPU 등의 성능을 측정하고 애플리케이션이 사용한 리소스를 시각화해 진단할 수 있는 진단 도구가 포함돼 있다.

tech_img4278.bmp

이 진단 도구는 버전이 올라갈수록 성능이 향상되고 있고 많은 항목들을 검증할 수 있게 개선돼 왔다. 비주얼 스튜디오 확장 형식이 아니라 비주얼 스튜디오와 밀착돼 동작하므로 개발자가 좀 더 편리하게 사용할 수 있다. 비주얼 스튜디오가 기본 제공하는 진단 도구는 디버거와 같이 실행된다. 이 도구를 이용하면 디버깅 시 실시간으로 CPU와 메모리의 변화를 살펴볼 수 있다. 별도로 실행되는 특성 덕분에 애플리케이션을 심층적으로 분석할 때에도 유용하다. 디버깅 시 진단 도구를 보기 위해서는 메뉴의 [Debug] → [Show Diagnostic Tools]를 선택하면 된다. 만약 디버그와 별도로 동작하는 진단 툴을 원한다면 [Debug] → [Show Diagnostic Tools Without Debugging...]을 선택하면 된다. 디버깅과 함께 시작되는 진단툴은 이벤트 여부, 메모리 사용량(Process Memory), CPU 사용량(CPU utilization)을 타임라인과 테이블 형태로 일목요연하게 보여준다.

tech_img4279.bmp

타임라인과 표 형식의 항목들은 서로 동기화되며 상호 작용한다. 이벤트 항목에는 인텔리트레이스(IntelliTrace)가 포함된 이벤트 항목이 표기된다. 만일 코드상에 브레이크 포인트가 걸리거나 출력이 이루어지는 등의 예외상황이 발생하면 해당 이벤트에 대한 시간 정보, 수행시간, 이벤트가 발생한 스레드 정보를 보여준다. 메모리 사용(Memory Usage) 탭에서는 디버깅되는 동안 애플리케이션 프로세스가 사용한 메모리 사용량을 시각화된 형태로 확인할 수 있다.

tech_img4280.bmp

진단 도구의 메모리 진단 세션에서는 힙에 할당되는 메모리 이미지를 캡처 가능한 것이다. 캡처 이미지는 서로 비교할 수 있다. 이를 통해 여러 힙 상태의 차이점을 쉽게 찾을 수 있다. 또한 인스턴스의 객체, 인스턴스 값, 콜 스택 등도 확인 가능하다. 메모리가 증가되는 부분의 코드를 추적하거나 메모리 릭(Memory Leak) 발생 지점을 찾고 분석하는 등이 가능하다. CPU 사용량 탭에서는 CPU 사용량을 시각화해 보여준다.



개선된 파일에서 찾기 기능

코드를 작성하거나 디버깅을 하다보면 ‘파일에서 찾기’ 기능을 써야할 때가 있다. 특정 함수나 상수의 위치를 찾아주는 기능인데, 경우에 따라서는 ‘파일에서 찾기’ 기능을 심볼의 이름을 알기 위해 먼저 찾기를 한 후 해당 결과를 바탕으로 반복해서 수행해야 할 때가 있다. 때론 파일에서 찾기 결과를 여러 번 수행한 다음 서로 비교해야 할 때도 있다.

비주얼 스튜디오 2013에서는 결과를 볼 수 있는 찾기 결과 창이 2개 있어 결과값을 서로 비교할 수 있었다. 그러나 유지하고 싶은 찾기 결과 값이 있으면 메모장 등에 별도로 복사해 써야 했다. 그런데 비주얼 스튜디오 2015부터는 파일 찾기 결과를 누적 보관할 수 있는 옵션이 추가돼 좀 더 쉽게 결과.

tech_img4281.bmp

파일에서 찾기 창의 [Result options] → [Append results] 항목을 체크하면 결과값을 계속 누적시킬 수 있다. 누적된 결과값은 트리 형태로 관리돼 검색한 순서대로 확인할 수 있다.

tech_img4282.bmp
tech_img4283.bmp

뿐만 아니라 검색된 결과의 항목을 삭제할 수도 있다. 검색된 항목에서 오른쪽 클릭을 통해 컨텍스트 메뉴의 [Delete]로 해당 항목을 지울 수 있다. 단축키로도 삭제 가능한데 ‘Delete’ 키를 누르면 된다.

tech_img4284.bmp

만일 검색된 결과에서 항목 트리가 시작되는 라인에서 삭제 기능을 수행하면 이에 해당하는 누적된 검색 결과 전체가 삭제된다.



인텔리센스 가독성 개선

C++는 엄격하게 타입을 검증한다. C++에서 템플릿을 활용해 코딩하면 반복되는 코딩 분량을 상당히 줄일 수 있을 뿐 아니라 많은 상황에서 범용적으로 활용할 수 있다. 이런 특성 덕분에 C++에 있어 템플릿은 함수 및 클래스 구현에 특히 유용하다. 그런데 코드 자체가 번거롭기도 하고 구현한 클래스가 범용적이지 않는 등의 이유로 굳이 템플릿을 써야할 필요를 못 느낄 수도 있다. 그렇다 하더라도 템플릿을 아에 배제하기는 어렵다. C++나 MFC 등의 수많은 범용 라이브러리가 제공하는 유틸리티성 함수들의 대부분이 템플릿으로 돼 있기 때문이다.

템플릿 함수나 클래스를 처음 사용하면 복잡한 선언부, 가독성이 떨어지는 코드, 낯선 에러 메시지 등의 불편을 느낄 수 있다. 그러나 비주얼 스튜디오의 버전이 올라갈수록 템플릿에 대한 지원이 강화되고 있다. 비주얼 스튜디오 2015에 이르러서는 비주얼 C++의 템플릿 클래스에 대한 인텔리센스(IntelliSense)의 가독성이 크게 개선되는 등 이러한 단점이 상당 부분 개선됐다.

tech_img4285.bmp
tech_img4286.bmp

뿐만 아니라 복잡한 템플릿을 인스턴스화하는 방법이나 형식 정의를 읽기 쉽고 직관적으로 쓸 수 있게 돕는 매개변수 도움말과 요약 정보도 보여줘 코드 생산성을 향상이 기대된다.



깃 그리고 깃허브 사용

소스 코드를 공개적으로 형상 관리할 수 있는 가장 대중적인 서비스 중 하나는 깃허브(GitHub)다. 깃(Git)은 구글을 비롯해 많은 기업들이 사용하는 형상관리 도구다. 깃허브, 비주얼 스튜디오 온라인, 깃랩(GitLab.com), 빗버킷(BitBucket.org), 소스포지(Sourceforge.net) 등의 수많은 공개 또는 전용 소스 코드 관리 사이트들도 있다. 별도의 형상관리 서버가 없는 단순 프로젝트이더라도 로컬 컴퓨터의 저장소나 외장 하드, 드롭박스 등에 깃 저장소를 만들어 형상관리를 할 수 있다.

비주얼 스튜디오 2015부터는 이렇게 대중적으로 쓰이는 깃과 이를 이용한 대표적인 형상관리 사이트인 깃허브 저장소를 간편하게 사용할 수 있다. 먼저 비주얼 스튜디오 설치 시 깃과 비주얼 스튜디오 깃허브 확장(GitHub Extension for Visual Studio)을 함께 설치해야 한다. <그림 15>의 설치 그림에서 [Common Tools] 예하의 항목을 꼭 확인하자. 이 두 항목은 기본값으로 체크돼 있지 않으므로 트리를 확장해 직접 체크해서다.

tech_img4287.bmp

비주얼 스튜디오 설치 시 체크하지 않았다면 비주얼 스튜디오 복구를 통해 해당 기능만 추가로 설치할 수 있다. 이 경우 가급적 비주얼 스튜디오 갤러리를 통해 최신 버전의 비주얼 스튜디오 확장을 설치하자. 해당 비주얼 스튜디오 깃허브 확장은 깃허브에서 제작하는데, 비주얼스튜디오 깃허브 닷컴(https://visualstudio.github.com) 또는 비주얼 스튜디오 갤러리에서 다운로드할 수 있다.

tech_img4288.bmp

메뉴의 [View] → [Team Explorer]를 통해 깃과 관련된 기능을 한눈에 파악할 수 있다. Team Explorer 창 상단의 Back, Forward, Home, Manage Connections, Refresh 아이콘을 통해 기능을 빠르게 찾고 실행할 수 있다.

tech_img4289.bmp

Team Explorer의 상단 기능명 부분을 클릭하면 바로 아래에 기능을 선택할 수 있는 컨텍스트 메뉴가 나타난다. 여기서 [Changes]와 [Branches] 등의 메뉴를 선택하고 관리할 프로젝트를 선택하면 형상관리를 할 수 있다.

tech_img4290.bmp

깃을 이용하는 대부분의 주요 기능들을 몇 번의 클릭만으로 쉽게 사용할 수 있다. 해당 내용은 한눈에 파악하기 편리하도록 정갈하게 정렬된 결과물을 생성해 준다. 해당 내용은 비주얼 스튜디오과 바로 연동할 수도 있다.

tech_img4291.bmp
tech_img4292.bmp

특정 깃허브 저장소의 소스 코드를 복제하고 싶다면 [Manage Connections]를 선택한 후 Local Git Repositories의 [Clone]을 클릭한 후 해당 저장소의 URL을 입력하면 된다. 이를 이용하면 보다 손쉽게 오픈소스를 활용할 수 있다.

tech_img4293.bmp
tech_img4294.bmp
tech_img4295.bmp

입력된 URL의 저장소 소스 코드는 로컬에 복제된다. 더블 클릭으로 이를 선택하면 비주얼 스튜디오에서 바로 사용할 수 있다. 복제뿐만 아니라 생성, 병합, 체크아웃 등의 동작도 몇 번의 클릭만으로 기능을 수행할 수 있다.

tech_img4296.bmp
tech_img4297.bmp
tech_img4298.bmp

개발 과정에서 Solution Explorer, Tem Explorer을 빈번히 확인해야 할 경우가 많다. 해당 파일에 대한 컨텍스트 메뉴의 [Compare with Previous...] 기능을 수행하면 각 파일로 변환된 사항을 자세히 비교할 수 있다. 파일 비교 툴의 경우 프로젝트의 성격이나 소스 코드의 길이, 형상관리할 리소스 및 문서의 종류에 따라 선호하는 프로그램이 다를 수 있다. Team Explorer를 통해 형상관리를 수행할 경우 사용자가 임의로 비주얼 스튜디오에 내장된 기본 파일 비교 기능 대신 외부 툴을 지정할 수 있는데, Team Explorer의 [Setting] 메뉴를 통해 해당 내용을 설정할 수 있다.



출처 : 마이크로소프트웨어 11월호

제공 : 데이터 전문가 지식포털 DBguide.net