임베디드 환경에서 C++ 사용하기
글쓴이: redrabbit / 작성시간: 목, 2009/04/23 - 5:08오후
군 제대후 C++ 위주의 프로그래밍을 했었는데요...
99년 부터 대학원 졸업할 즈음 까지 2006년정도까지군요...
그 이후 회사 생활을 하면서는...
첫 직장에서 임베디드 리눅스 환경에서 어프리케이션을 작성하였기
때문에... C++위주의 코딩을 하기도 했지만..
직장을 옮기고 나서...
거의 C 위주의 작업을 하고 있습니다.
그런데 근래 WinCE 위주의 작업을 하면서 다시 C++을 사용하게 돼었는데요...
역시 어플리케이션에서 제한적인 사용을 제외하고
드라이버등의 작업은 거의 C Like 한 구조적인 코딩을 하게 돼더군요..
근래 시간이 되어 오랜만에 Kldp에 와보니...
제가 얼마나 그동안 정체되어있었는지 느끼게 됐습니다.
임베디드 환경에서 WinCE나 임베디드 리눅스에서 C++의 사용 어느정도까지 가능할까요?
STL이나 templete의 적용등이 가능할까요?
만약 가능하다면 성능에 지장은 없을지...
여러 고견 부탁드립니다.
Forums:
때에 따라서 아닐까요?
c 만 사용해서 개발이 가능하다면, 구지 c++ 를 사용 할 필요는 없겠지요.
WinCE, e-Linux에서 모두
WinCE, e-Linux에서 모두 stl, template 사용 가능합니다.
성능에는 당연히 지장이 있습니다.
개인적으로 성능을 위해서라면 C++은 사용하더라도 stl, template은 피했으면 합니다.
STL과 템플릿을
STL과 템플릿을 사용하면 왜 성능에 지장이 있나요? 컴파일 시간이 길어지는 거라면 몰라도요. 홍민희님이 답글 다셨지만 템플릿은 컴파일 타임에만 쓰는 정적 정보입니다.
성능이 저하된다는 정확한 기술적 근거 제시를 부탁드립니다.
[예진아씨 피카사 웹앨범] 임예진 팬클럽 ♡예진아씨♡ http://cafe.daum.net/imyejin
[예진아씨 피카사 웹앨범] 임예진 팬클럽 ♡예진아씨♡ http://cafe.daum.net/imyejin
이상하게 C++
이상하게 C++ 템플릿이 런타임에 뭔가 일어나는 굉장히 동적인 차세대 기술(?!?!;;;;)처럼 여겨지는 미신이 좀 있더군요. 대개 C++를 모르거나 템플릿을 접해본 적 없는 분들이 그런 미신을 가지고 계시더라는…
—홍민희 (VLAAH, LangDev)
STL과 템플릿은 일단
STL과 템플릿은 일단 바이너리 사이즈가 커지게 됩니다.(이 차이가 꽤 많이 납니다. 특히 임베디드 환경에서는요. 시스템 메모리의 문제도 생기니까요.) 성능의 경우는 STL과 템플릿의 경우 코딩하는 사람에 따라 차이가 있겠지만 코드 최적화에 차이가 있습니다. 코딩은 편한 반면에 부분적인 최적화에서 조금씩 문제가 생긴다는 것이 제 개인적인 생각입니다.
캐시 풋프린트가
캐시 풋프린트가 커져요.
..
뭐.. 목적에 따라 다르지 않을까요? 어플리케이션에서는 C++도 많이 사용하는 것으로 알고 있습니다. 멋도 모르고 오페라 면접을 신청했다가 C++문제를 받아들고는 황당해 했던 기억이 있습니다. QT도 C++인 것으로 알고 있습니다.
A rose is a rose is a rose..
템플릿 같은 경우는
템플릿 같은 경우는 컴파일 타임에 증발하는 정보이기 때문에 크로스 컴파일러가 템플릿을 제대로 구현했다면 어느 디바이스에서든 사용이 가능합니다.
—홍민희 (VLAAH, LangDev)
_
반면 컴파일러가 템플릿 구현을 제대로 하지 못 하면 포터블하지 못한 상황이 발생하기도 합니다. C++ Template Metaprogramming에서도 부록으로 컴파일러 버전별 주의사항이 간략하게 나와 있고요. 모두들 꽤 오래 된 정보라서 현재는 어떤지 모르겠습니다만 특히 임베디드라면 컴파일러 이슈를 조심해야 하지 않을까요.
* https://developer.mozilla.org/En/C___Portability_Guide#Be_very_careful_when_writing_C.2b.2b_templates
* http://www.boost.org/doc/libs/1_39_0/doc/html/signals/tutorial.html#id3341564
실시간 성능 저하도
실시간 성능 저하도 있지 않을까요?
OOP나 컴파일러나 저질인 제 수준에서 본다면... 어차피 stl이나 템플릿들이나 virtual function(또는 vtable?)들이
안쓰일 수가 없을텐데요, control flow 입장에서 본다면 indirect branch가 많으면 많을 수록
성능이 떨어질 가능성이 높을 것 같은데요... direct branch야 branch predictor의 hit rate를 높인다던가
(gcc라면) likely 매크로로 instruction cache hit rate를 높이는 식으로 branch penalty를
줄일 수 있겠지만, indirect branch는 그러기 힘든 걸로 알고 있습니다.
데스크탑 PC들이야 클럭이 워낙 빠르고 cache가 커서 이런 indirect branch의 영향이 그리 크지
않을 (혹은 않아 보일) 수 있겠지만, 임베디드 프로세서의 경우에는 캐시가 제 성능을 발휘 못하면 아주 바보가 됩니다.
(혹시나 제가 virtual function/vtable에 대해서 잘못 이해하고 있다면 설명 부탁드립니다.)
템플릿은 vtable을
템플릿은 vtable을 안씁니다. dynamic dispatch도 없습니다. 템플릿이 컴파일 타임에만 유효하고 컴파일된 바이너리에는 증발된다는 말은 그런 뜻입니다.
—홍민희 (VLAAH, LangDev)
템플릿과 가상함수는
템플릿과 가상함수는 관계없습니다. 템플릿은 다형성이나 동적바인딩을 이용하는게 아닙니다.
stl 까지는 몰라도..
STL은 몰라도 템플릿기술을 쓰는것이 왜 성능저하를 불러일으키는지 모르겠군요.
STL이야 실행시간 성능향상 보다는 표준화, 생산성향상에 포커스를 둔 라이브러리라고
규정하는 사람들까지 있는만큼 다분히 논란의 여지가 있습니다만
템플릿기술은 그렇지 않잖아요?
오히려 적절히 사용만 잘 하면 메모리 사용량과 연산성능을 최적으로 가져갈수가
있는데 템플릿으로 인한 "실행시간" 성능저하가 발생한다는건 이해할수가 없군요.
개인적으로 정적 바인딩을 극단으로 추구하는 C++템플릿기술은 아직 그 가능성이
충분히 잘 이해되지 않을 정도의 미개척지이고, 앞으로 각광받게 될 미래의 기술
이라고 생각합니다.
STL이 템플릿으로 "구현"되었다고 해서 템플릿과 STL을 싸잡아 같이 생각할
근거는 없습니다. 다만 STL의 "내부구현"자체를 문제삼아 STL의 성능 자체를
비판하거나 그럴수는 있겠지만 이건 템플릿기술과는 별개의 문제죠.
포터블한가 아닌가 하는것도 좀 귀찮긴해도 각 컴파일러에 맞게 #ifdef, #if 같은
적절한 선행처리자를 사용하면 문제없을거라 봅니다.
위에서도 언급된내용이지만 성능상의 문제를 지적하는건
템플릿을 너무 피상적으로 접근하고 말씀하시는거라 보입니다.
STL이 주로 템플릿에
STL이 주로 템플릿에 의존되어 있는 부분은 사실입니다만 STL이 vTable을 전적으로 쓰지 않는 것은 아니며 동적 속성을 전혀 사용하지 않는 것은 아닙니다. 동적인 프로그래밍이라고 모두 느리고 정적인 프로그래밍이라고 모두 빠른 것이 아니고 일반적으로 STL의 정적 속성은 어떤 타입을 가질 것이냐라라는 컨테이너적인 부분에 국한됩니다. STL은 생각보다 빠르게 구현된 라이브러리가 아니며 속도가 문제가 될 수 있는 환경이라면 다른 대안을 찾는게 나을 수도 있습니다.
- 죠커's blog / HanIRC:#CN
- 죠커's blog / HanIRC:#CN
공부가 부족해서
공부가 부족해서 그런지, STL에서 가상함수를 이용하는걸 본적이 없는데, 예를 하나 들어주시면 감사하겠습니다.
이론적인 설명은 할
이론적인 설명은 할 수 없지만 경험적으로 말씀 드리겠습니다.
얼마전에 임베디드 환경에서 꽤 대용량의 데이터를 처리하는 어플을 작성할 일이 있었는데
(지리 정보 관련 어플이었습니다. 당연히 처리하는 데이터가 허벌나게 많았습니다.)
저도 처음엔 당연히 C로 작성해서 직접 자료구조 만들고, 왠만하면 자료구조들도 직접 작성해서 만들었습니다.
그런데도 성능 요구사항을 만족시키지 못하고 내부 자료구조는 꼬이고 해서,
그냥 다시 엎고, C++에 STL 사용해서 작성했습니다.
vector와 map 이 난무하고, 클래스와 탬플릿으로 관련 자료구조를 작성하니 오히려 C로 작성한것 보다 깔끔하더라구요.
게다가...
성능도 더 잘나오더라는...-_-;;
여기서 교훈은..
무언가 동적으로 자료구조의 크기를 바꾸거나 자료형이 변환될 일이 많은 프로그램은,
그냥 STL과 C++ 컴파일러를 믿는 것이,
내 프로그래밍 실력보다 뛰어나다...
라는 것입니다..-_-;;
물론 제가 허접해서일 수도 있지만..
결론은
임베디드 환경에서 C++에 STL 쓰는것도 그닥 성능에 영향을 주는것 같진 않았습니다.
----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라
----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라
저는 휴대폰 App을
저는 휴대폰 App을 주로 C++로 개발하는 개발자입니다만..
C++ 템플릿은 예전부터 code bloating 현상이 약점으로 알려졌던 것으로 기억합니다.
임베디드 장비의 자원에 따라 다르겠지만, 매우 작은 크기의 코드 작성이 필요하다면 C++과 템플릿은 문제가 될수 있지 않을까 생각합니다.
예전에 비해 임베디드 장비의 자원과 컴파일러 성능이 많이 향상되어 지금은 큰문제가 되지 않을수도 있을것 같긴한데..
code bloating 을 피하기 위한 C++ 컴파일러 성능향상에 대한 관련 자료는 알고 있지 못합니다.
혹, 아시는 분 있으시면 링크(URL)를 부탁드립니다.
=================================
나비아빠
=================================
나비아빠
약점이라기 보단..
그 점은 템플릿의 약점이라기보단 특성이죠..
code bloating을 막는 어떤 방법이 있다기보단..
그러한 특성을 잘 알고 "똑똑하게" 사용하는것 이상의 방법은 없다고 생각합니다.
STL에 관해서라면 예전의 Effective STL 정도의 책이 STL을 똑똑하게
다루는 법을 설명해놓고 있는데..요새는 어떤 책이 있는지 모르겠군요.
템플릿 자체에 관해서라면 스트로우스트럽(발음도 참 어렵죠;;)의 책보단
오히려 니콜라이 조서티스의 책이 설명이 잘되어 있습니다.
http://www.josuttis.com/tmplbook/
하지만 코드 크기가 커진다는것과 연산랑이 많아진다는건 전혀 다른 얘기죠?
꼭 그런건 아니지만 전자가 space complexity, 후자가 time complexity
와 밀접한 관계가 있다는건 이 분야에서 어느정도 상식적인 내용입니다.
단순히 코드 크기가 커진다고 해서 "더 나쁜것"이라 얘기하기 어렵다는거죠.
일반적으로 space complexity와 time complexity는 trade-off의 관계를
가지기 때문에 메모리가 부족한 시스템은 cpu가 더 계산하게 만들고 cpu파워가
딸리는 시스템은 메모리를 더 사용하게 만들게 되는게 어느정도 정해진 공식인것
같습니다.
가상함수와 조건식으로 점철된 코드가 다중 루프안에서 반복적으로 호출되는 경우라면
코드크기를 다소 늘리더라도 템플릿을 이용해 각 경우에 맞는 코드를 별개로 생성(generate)
시키는것이 성능상 유리합니다.
(물론 이렇게 하기 위해선 기존 설계를 갈아 엎어야겠죠..;;)
언제나 그렇지만 성능이란게... 상대적인것이고 이 상대성은 개발 과제에 부여된 제약에
따라 달라집니다.
...
성능이란 게 워낙 여러 가지 요소가 있어서 100% 맞는 법칙은 없지만, 다른 조건이 같을 때 코드 크기가 커지면 수행속도가 나빠집니다.
요즘 거의 모든 시스템은 여러 레벨에서 캐시를 사용하고 있는데, 코드 크기가 커지면 그만큼 캐시 성능이 떨어집니다. 가장 가깝게는 CPU에서 같은 일을 하기 위해 더 많은 instruction cache를 써야 하니 다른 코드/데이터가 밀려나고, 더 멀게는 메모리 사용량이 늘어나서 OS에서 다른 필요한 데이터를 swap out해버릴 수 있죠.
따라서 경우에 따라서는 template를 사용해서 같은 코드를 여러 번 생성하는 게 오히려 속도를 떨어뜨릴 수 있습니다. (뭐 흔하지는 않겠죠.)
다른 조건이 같지 않은데요..
제가 예를든 경우는 다른 조건이 같을때라는 단서 조항이 적용되지 않습니다.
템플릿 사용을 통해 vTable을 탐색하는 시간을 제거하면 그만큼 실행효율이 좋아진단거죠.
http://en.wikipedia.org/wiki/Template_metaprogramming#Static_polymorphism
하기사 요샌 캐쉬메커니즘이 워낙에 발달해서 locality가 좋은 프로그램이면
실행효율이 좋다고 얘기할 수 있을지도 모르겠습니다. 어쨋든 코드가 커지면
캐쉬miss 확률이 더 높아질테니까요. 하지만 그렇다해도 dynamic binding의
특성이 제거되진 않습니다. 캐쉬를 읽더라도 여전히 가상함수 테이블을 열라
찾을거란 말이죠. 템플릿은 그런 실행시간 탐색을 컴파일타임 코드생성으로
대체하는겁니다.
저는 그런 의미로 적절히 템플릿 사용을 하면 실행효율이 좋아진다고 한겁니다.
프로그램이나 시피유
프로그램이나 시피유 구현에 따라 다르고 indirect 점프야 예측이라도 할 수 있지만 (그것도 꽤 높은 확률로) 캐시 풋프린트 커지는 건 어떻게 피할 수가 없습니다. 마이크로 벤치마크에서야 인라인 많이 되고 브랜치 없는 코드가 빨라 보이지만 실환경에선 워킹셋이 캐시사이즈 넘어가는 게 보통이니 역효과가 나는 경우가 많구요. 대게의 경우 템플릿을 일부러 피할 이유는 안되지만 성능이 템플릿의 장점중 하나라고 얘기하긴 메모리와 캐시 속도 차이가 너무 커져버렸죠. 탬플릿을 쓰려면 다른 이유로 사용하세요.
아 그리고 약간 더
아 그리고 약간 더 보충하면 점프 예측 틀려도 캐시에 없어서 메모리까지 가야되는 거에 비교하면 오버헤드가 쉽게 여러 orders of magnitude 차이가 납니다.
어차피 리눅스
어차피 리눅스 커널이 올라가 있으므로 C++을 사용하는데는 전혀 지장이 없습니다.
성능은 C보다는 확실하게 느립니다.
그럼 C++ 쓰면서 C와 비슷한 성능을 낼수 있느냐? <- 이건 뭐 각자 알아서 능력껏 해결해야.. ^^;