ari님 글에 대한 세번째 트랙백
이 글은 ari님의 글 '성능에 대한 미신'(http://sparcs.kaist.ac.kr/~ari/each/article.each.463.html)에 대한 세번째 트랙백입니다.
마지막까지 남는 의문이 있으니 그걸 다시 한 번 밝히고 저의 트랙백 시리즈는 여기서 접도록 하겠습니다. 어차피 ari님이나 저나 실험을 많이 해본 것도 아니고 해봐서 결론이 지어질 것도 아니니 말입니다. ari님께서 수고스럽게 답변을 주셨는데도 제 의문은 아직도 남습니다. 아래 크게 두 단락에 걸쳐 있습니다.
ari님께서 남겨주신 답변은 녹색으로 처리하였습니다. 일부 문장만 따서 인용하지만 의도적으로 부분만 가지고 곡해할 생각은 없습니다.
프로그래머가 의도하지 않아도 자동으로 추가되는 그런 코드는 무시해도 좋을 만큼 미미합니다. 전체 코드에서 비중이 0.001%나 될까요 ? 생각보다 그렇게 추가되는 어셈블리는 많지도 않습니다.
이 부분에 대한 논증이 부족하다는 생각이 듭니다. 논증 부족을 운운하는 이유는 ari님께서 원글에 '미신'이라는 표현을 사용하셨기 때문입니다. 미신이라 불리우는 것들은 과학적인 방법의 실험이나 관찰이 동반되지 않은 결론도출된 현상이나 믿음일 것입니다. '미신'이라는 주장을 하려면 특히 스스로의 주장부터 합리적인 추론과 증거제시가 필요하다고 봅니다.
저는 C와 C++이 성능 차이를 크게 보이지는 않는다는 쪽을 '믿는' 편이긴 합니다. 그러나 C가 C++보다 조금이나마 빠르지 않을까하는 생각도 하는 편입니다. 어느 쪽이 빠르다 느리다라고 단정을 짓고 싶진 않지만 'C가 C++보다 빠르다'라는 주장은 컴파일러가 빠르다는 소리가 아니니까 곧 '어떤 작업을 위해 C로 작성한 코드가 C++로 작성한 코드보다 빠르다'와 동일합니다. 어느 상황에서나 C가 C++보다 빠르다고 주장할 생각은 없습니다.
그러나 분명히 미니멀리즘의 측면에서 보면 C가 유리한 입장이고 분명히 빠른 경우도 있다고 생각하는 거죠. 그러니까 C가 C++보다 빠르다는 말은 지나친 일반화이지만(저는 여기에 동의함을 이미 밝힌 바 있습니다) 그 주장이 미신이라고 일축하며 C와 C++이 차이가 없다라는 말은 논거가 부족한 주장이라는 생각이 든다는 거죠. 여기에는 계속 관점 차이가 존재할 테니 ari님의 의견은 제가 충분히 납득하고 있고 그냥 제 입장은 이렇다는 걸 말씀드립니다.
마지막으로 한 가지만 질문을 드립니다.
OS에서도 너무너무 빈번하게 수행되는 코드는 C도 아닌 어셈으로 작성할 수밖에 없습니다. 그런 코드는 C 컴파일러가 생성해내지도 못합니다. CPU 제조사에서 나온 메뉴얼을 보고 거기 나온 인스트럭션들을 그대로 따라 써야 하죠.
제 질문을 다시 반복하면 '왜 OS에서조차 성능차이가 발생하지도 않는, 빈번하게 수행되지 않는 코드를 C++이나 Java로 작성하지 않는가?'라고 할 수 있겠네요. ari님의 주장을 확장하게 되면 빈번하게 수행되는 부분이 어셈블리 인스트럭션으로 되어 있으니까 나머지는 C++이나 Java로 작성해도 된다는 결론에 이르거든요. 제가 지나친 귀납에 빠진 것일 수도 있겠습니다만…
저는 OS처럼 성능이 바로 경쟁력이 되고 결국 돈이 되는 DBMS 쪽을 하고 있습니다. DBMS의 API를 C나 Java(JNI / Pure-Java)로 개발하는 일을 지금도 하고 있습니다. 그런데 분명히 비슷한 작업(ODBC, JDBC, ESQL)에 대해 코드를 작성하는데도 각 API 구현 별로 성능차이가 발생합니다. 당연히 JDBC 버전이 다른 C API에 비해 느립니다. 단순히 JDBC가 느린 이유가 (JDBC 구현을 하는 개발자나 JVM 개발자가) 최적화를 잘못해서 그런 것일까요? 저는 Java의 특성상 C보다 무거울 수 밖에 없다고 생각합니다. 필요에 따라 다른 언어로 된 API를 제공해야 하지만 성능 차이가 존재하는 걸 인정할 수 밖에 없는 현실에 처해 있는 거죠. ^^
바쁜 시간 쪼개서 답변 주신 ari님께 진심으로 감사드립니다.
댓글 15개
ari
제가 처음 글에 쓴 모든 미신들을 한번 살펴보면,. function call overhead, float가 느리다, inline을 쓰면 빨라진다. 입니다.
이 말들을 모두 미신이라고 했지만 어느 정도는 맞는 말입니다. 많은 책들에서 저런 것들에 대해 다루고 있고 많은 프로그래머들이 상식으로 알고 있는 것들이죠.
그러나, 제가 미신이라고 했던 이유는 저런 것들이 너무나도 과대평가되어 있기 때문입니다. 실제로는 0.0001%도 성능에 영향을 미치지 않는 function call overhead에 대해 집착하며 inline을 쓰는 삽질을 자주 봐왔기 때문이기도 하구요.
C와 C++간의 차이에 대해서도 마찬가지입니다. 많은 프로그래머들이 C와 C++간의 차이를 10%라던가 20%라던가 혹은 2배라던가 4배라던가 하는 식으로 과대평가하고 있습니다. 어떤 C++프로그램에 성능상의 문제가 있어보이면 'C로 컨버젼해보면 빨라질까?' 하는 생각을 가지고 있습니다.
제가 미신이라고 한 이유는 이런 생각이 틀렸기 떄문입니다. 눈에 띄는 성능 차이가 발생한다면 그것은 C++코드를 엉터리로 썼기 때문이지 결코 C++이 느리기 때문이 아닙니다. 이것은 저의 경험에 따른 것이기도 하고, 제 주변의 많은 개발자들이 경험한 것이기도 합니다. 어떤 프로그램을 C++로 만들었을 때 이게 느리다고 해서 C로 바꿔서 빨라지는 일은 결코 없습니다.
OS에서 빈번하게 수행되지 않는 코드는 C++로도 만듭니다. Java의 경우는 virtual machine위에서 수행되는거라서 OS를 만드는데 Java를 쓰는건 말이 안됩니다. 일단 OS가 있어야 그 위에 JVM을 띄우고 그 위에서 Java를 실행시키는 것이니까요.
그리고 DBMS쪽에서 발생하는 성능차이는 다른 이유때문입니다. Embeded SQL이 빠른 이유는 이게 DBMS에 더 직접 액세스하는 방식이기 때문입니다. JDBC나 ODBC의 경우 더 많은 단계를 거쳐 간접적으로 DBMS와 통신을 하는 방식입니다. 그리고, Java의 경우 JVM을 한번 거쳐서 수행되기 때문에 당연히 그렇지 않은 C에 비해 느릴 수 밖에 없습니다.
파파스머프
십몇년 전 컴퓨터를 배울 때 간단한 프로그램을 짜려고 노력했지만, 감각이 떨어져 포기했더니, 두 분의 말씀을 다 이해하긴 힘드네요. 하지만 진지한 토론이 이뤄지는 모습이 참 보기 좋습니다..^^
Terzeron
http://alexvn.freeservers.com/s1/perfo/tests/pftests.htm
http://www.cs.colorado.edu/department/publications/reports/docs/CU-CS-698-94.pdf
Terzeron
그리고 ari님께서 ESQL과 ODBC/JDBC를 비교하신 내용은 전혀 '틀린' 내용입니다만 토론의 주제에서 벗어나니 논의를 확장시키진 않겠습니다. 'DBMS에 더 직접 액세스'하는 것과도 전혀 거리가 멉니다.
CN
저는 오히려 다르게 생각합니다. C++은 C보다 더 빠르게 프로그래밍될 수 있습니다. Loki 등의 라이브러리의 코드를 보셨으면 C++이 C보다 더 빠를 가능성을 인정하게 될 것입니다. (일반적으로는 클래스 등의 런타임 개입만 생각하는 경향이 큽니다만) C++은 C보다 컴파일 과정에 더 많은 개입을 할 수 있습니다. template과 functor의 상호작용으로 인한 컴파일 과정에 개입은 Loki나 Boost의 MPL에서 예술적으로 승화되었습니다. 그런 방식으로 만들어진 C++으로 만들어진 효과적인 코드는 이미 수치해석 라이브러리 등에서 그 효용을 인정받고 있습니다. 가장 간단히C++이 효과적인 경우를 알아보는 법은 std::sort와 qsort가 생성하는 기계어/어셈블리 코드를 비교해 보는 것입니다. 다만 C++의 다양한 특성을 사용한 코드는 매우 비직관적이고 이해하기 어렵습니다. 일반적인 프로그램 개발에 사용하는 것은 유지보수가 힘들지 않을까 생각합니다. Andrei Alexandrescu와 같은 천재들이 만들어 낸 코드가 대부분 “라이브러리”에 모여있다는 것이 응용 프로그램으로서 유지보수가 힘든 증거라고 생각합니다.
terzeron
CN님의 답변을 보니, programability 측면에서의 속도를 말씀하시는 것 같은데, 저도 그런 측면에서라면 C++이나 Java가 C보다 ‘빠르고 용이하다’는 것을 인정합니다.
제가 애초에 의문을 제기한 C와 C++이 만들어내는 object code 또는 assembly code의 간결성(minimalism)의 측면에서는 ‘C++이 C보다 느릴 거라는 것은 미신이다’라는 주장은 여전히 납득이 가지 않습니다. C++은 C보다 빠르거나 최소한 같은 거라는 ‘미신’이 C++ 프로그래머들 사이에서 공유되고 있는 것도 알고 있는데 이에 대한 논의나 논증은 다소 부족한 것 같더군요. (전에 이 쓰레드를 작성할 때, C++에 호의적인 논거를 많이 찾아봤습니다만 의외로 적더군요.)
CN
먼저 std::sort와 qsort를 써서 만든 코드를 디스어셈블리해보셨나요? 해보셨다면 아래의 코드를 디스어셈블리해보십시요.
template struct newton {
static const unsigned q = n/a;
static const unsigned a2 = (a+q)/2;
static const bool good = a2==a || a2==q;
static const unsigned value = newton::value;
};
template struct newton {
static const unsigned value = a;
};
template struct Sqrt : newton { };
많은 프로그래머들이 C++의 코드가 더 방대할 것이다고 생각하시지만 C++은 니모닉 코드를 방대하게 만들 수도 있고 더 간략하게 만들 수도 있습니다. 더 빠르게 만들 수도 있고 더 느리게 만들 수 도 있습니다.
CN
템플릿 코드가 제대로 첨부가 되지 않네요. 메일 주소 terzeron@hotmail.com로 코드를 보내겠습니다.
CN
글이 스팸으로 판별되었네요. 템플릿이 깨져서 메일로 보내겠습니다.
terzeron
이젠 이 주제는 지긋지긋합니다. 아예 벤치마크 결과로 이야기를 하는 게 나을 듯 싶네요.
http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=all
http://shootout.alioth.debian.org/debian/benchmark.php?test=all&lang=all
위 웹사이트는 P4와 Sempron을 가지고 여러 벤치마크를 돌린 결과를 종합한 겁니다. 게다가 C++이 특히 불리한 Startup time을 제외한 것이구요.
벤치마크를 신뢰하지 못하신다면 제가 적어놓은 논문 링크 외에 몇 가지 더 논문을 제시하도록 하죠.
CN
알려주신 링크에 대해서는 반론을 여유가 있을 때 인터넷 상에 공개할 생각입니다. 지긋지긋하시다고 하니 이 이야기는 이쯤에서 접을까 합니다. 날씨가 나쁘긴 하지만 편안한 주말되시길 바랍니다.
terzeron
CN님, 반론보다는 performance benchmark나 technical paper로 C++의 성능에 대한 근거를 제시해주시면 더 감사하겠습니다. 여태까지의 흐름으로 봐서는, 몇 가지 특정 사용패턴에 근거한 반론은 또 다른 반론으로 상쇄될 따름인 것 같습니다.
개발초보
C++ 이 C 를 포함한다면
즉 c + something == c++ 이면
수행 시간은 당연히
c++ >= c
이렇게 되야하지 않을까?
개발초보
c++은 c 이기도 하니 이런 논쟁은 무의미해 보이는데…
언젠가 c++ 코드 최적화 (속도 최대화)에 관한 책을보니..
스타일이 완전 c 가 되가더만….
terzeron
요즘의 성능 비교는 C++이나 C나 별 차이 없습니다. 특히 GCC 개발 그룹에서 C++와 C를 같이 개발하기 때문입니다. (C++과 C는 모듈이 다르지만 크게 다른 부분은 특히 STL에 집중되어 있습니다.)
다만, 이 글을 처음 쓴 이후로 저도 C++로 개발하는 경험을 많이 쌓고서(회사에서는 대용량 데이터를 실시간으로 처리하는 시스템 개발을 하고 있습니다) 느낀 거지만, 성능을 위해서라면 결국 C++로 작성하더라도 C로 작성한 것과 별반 다르지 않게 나오더군요. OO스타일로 작성하다보면 성능이 나오지 않아서 결국 C 스타일로 고치게 됩니다. 이에 관해서는 http://terzeron.com/?p=762 에 소회를 다시 적은 바 있습니다.