Lacti's Archive

43 posts tagged with c++

  • dumpable 고찰

    June 30, 2014

    하재승님께서 던전 앤 파이터 클라이언트 로딩 속도 최적화에서 언급하신 dumpable 라이브러리에 대한 이야기를 해보자. 이 라이브러리는 serializable memory가 가능한 dynamic container와 operator =를 사용하여 dumpable한 struct를 만들어준다. 다만 몇 가지 아쉬운 점이 있었다. dptr::alloc() 함수가 thread safe하지 않다는 점 dstring, dvector…

  • variadic template을 사용한 typelist 구현

    June 29, 2014

    Modern C++ Design 책에서 소개한 typelist를 c++11 문법인 variadic template으로 구현해보자. typelist는 type들의 list형태로 compile time에 여러 type에 대한 동일한 작업을 할 때 사용된다. 예를 들면, conversion table을 만들어서 부담이 적은 dynamic_cast를 구현한다던가, hierarchical inheritance를 통한 tuple…

  • 빠른 메시지 만들기

    February 11, 2014

    Cap’n Proto와 같은 무한대(?)로 빠른 메시지를 설계한다고 생각해보자. 그렇다면 우리는 어떤 점을 고민해야 할까? 이를 위해 잠깐 네트워크로 정보를 전달하는 과정을 생각해보자. end-point #1은 정보를 패킷에 담아 네트워크로 전송한다. (serialize) end-point #2는 네트워크에서 바이트를 읽어 메시지를 구성하고, 그 메시지로부터 정보를 읽는다. (deserialize…

  • 메시지 enum에 따른 message 콜백 함수 자동생성

    November 19, 2013

    일단 message에 대한 기본 type과 각 message을 구분하기 위한 enum이 있다. message과 enum 값을 쉽게 연결하기 위해 중간 층을 도입한다. 이제 message을 만든다. 기본적인 handler는 다음과 같이 단순하게 정의할 수 있다. dispatch를 위해 handler에 대한 table을 하나 만들어둔다. 일단 등록된 handler가 없어도 서버 동작에 문제가 없도록 하기 위해 빈 handler…

  • c++ message dispatcher

    November 16, 2013

    간단한 message dispatch 코드를 c++로 구현해보자. 일단 std::function을 안 쓰고 구현해보고, 그 다음에 std::function을 써서 구현해보자. 지난 번 글에서 functor_ii로 handler_t의 근간을 이미 설명했다. interface인 wrapper_t, 실 구현체인 impl_t, 그리고 그것을 멤버로 갖는 type erasure가 적용된 대표 type인 handler_t이다.…

  • function adapter와 type inference

    November 10, 2013

    과제는 다음의 Adapter를 만들어보자는 것이다. 많은 친구들이 이미 문제를 잘 풀었기 때문에 자세한 설명은 생략한다. 이름 잘 지어주는 것도 물론 중요하지만 이정도 코드에서는 저정도 글자만 써줘도 이해할 것 같으니 과감히 생략. 개인적으로 풀이 중 가장 마음에 드는 것은 Omniavinco가 if1live 글에 댓글로 단 binder1st 상속을 통한 구현. (있는 것 가져다가 쓰는게 제일) type infererence…

  • template 프로그래밍과 type erasure

    November 10, 2013

    첫 번째 코드(for_each)는 _Iter, _FuncTy에 들어가는 각 type에 맞게 compile time에 모든 code가 생성(template instantiation)되어 어떤 함수가 호출될지 compile time에 결정되는 구조이고, 두 번째 코드(ForEach)는 Iterator와 Functor interface를 구현한 객체가 runtime에 ForEach() 함수로 넘어간 다음 virtual…

  • template을 사용한 generic 프로그래밍

    November 04, 2013

    (한 번에 1~2시간 정도로 짧게(?) 하고 있다. 대충 accelerated c++ 책이랑 EC++ 책을 보고 있다.) C++ 언어를 가지고 C++스럽게 프로그래밍을 해보자! 는 어떤 의미일까? 다양한 의견이 있겠지만, 프로그래밍 언어는 표현력이 증가하는 쪽으로 발전한다는 관점에서 프로그래머가 C에 비해서 보다 자신의 의도를 C…

  • preprocessor programming

    August 23, 2013

    http://www.slideshare.net/lactrious/preprocessor-programming github: MacRec 오늘 발표 자료인 preprocessor programming. x-macro pattern부터 시작해서 repetition까지 간단히 설명을 했다. if1live님에게 배운 mpinc(multi-pass include) 단어를 어떻게든 써먹어보려고 했는데 이미 x macro라는 이름으로 6…

  • generic한 c++ rpc 구현

    August 20, 2013

    generic한 rpc를 간단히 구현해보자. 원래 의도는 asio를 사용하여 가벼운 덧셈 rpc 정도를 구현해보자는 것이었는데 왠지 모르게 스터디 친구들이 spec을 안드로메다로 보내버려서 DSEL을 통한 rpc stub, skeleton 생성 코드를 구현해보도록 하겠다. 양이 좀 많기 때문에 개요부터 설명하겠다. rpc 메시지을 주고 받기 위한 buffer를 먼저 설계하고, 메시지을 처리할 handler…

  • producer/consumer model 구현

    August 12, 2013

    먹깨비 과제를 풀어보자. 여러 가지 구현법이 있을 것인데, 나는 간단하게 바구니는 공유 자원이니 lock으로 보호하고, 제빵사와 먹깨비는 actor로 만들어서 매 tick마다 상황 판단 후 작업을 처리하도록 했다. 따라서 공유 자원을 보호하기 위한 spin_lock과 actor 기반 코드를 만들었고 그 기반으로 바구니, 제빵사, 먹깨비를 만들었다. 먼저 spin_lock…

  • thread-safe한 counter 구현

    August 04, 2013

    먼저 간단한 counter example을 만들어보자. 문제를 확인하기 위해서 다음과 같은 코드를 작성해본다. c++ code 한 줄이 원자적(atomic)으로 실행된다는 보장은 없다. assembly의 한 줄도 원자적으로 실행된다는 보장은 없다(smp, micro-operation) 위 코드를 release로 빌드해보면 ++counter 부분에 대한 코드가 assembly로 한 줄이 나오는데, 어쨌든 expect…

  • 멤버 데이터 포인터의 casting과 안정성 1

    October 31, 2012

    어제 동아리 친구와 이야기를 나누다 run-time에서는 float array를 float pointer로 casting하여 사용할 수 있는데 compile time에서는 왜 그럴 수 없냐는 이야기가 나왔다. 질문이 좀 미묘한데, 좀 더 정확히 정의하자면 float array type의 member data pointer를 float pointer type의 member data pointer로 casting…

  • member-data-pointer와 pointer의 차이

    October 13, 2012

    pointer는 메모리의 특정 공간의 주소를 지칭하기 위해 사용된다. member data pointer는 구조체나 클래스의 특정 멤버 변수의 위치를 상대적으로 지칭하기 위해 쓰인다. 따라서 메모리 주소 값을 가지는 것이 아니라, 구조체나 클래스 객체에서 어디에 접근을 해야하는지의 정보를 담고 있다고 생각하면 된다. 때문에 실제 메모리에 접근하기 위해서는 구조체나 클래스 객체가 있어야 하고, 접근할 때에도 dereference…

  • 멤버 데이터 포인터를 사용하여 연산식 묶어내기 3

    October 07, 2012

    지난 두 글에서 사용한 전략은, 멤버에 접근하기 위한 방법을 동일한 인터페이스로 맞춰서 (첫 번째 글에서는 멤버 데이터 포인터, 두 번째 글에서는 멤버 함수 포인터) BuffType과 그 인터페이스를 대응시키는 방법을 사용하였다. 동일한 인터페이스를 사용하기 위해서 그들을 하나의 동일한 타입으로 지칭하는 방법을 사용하였고, 그렇기 때문에 서로 다른 type, int 변수와 float…

  • 멤버 데이터 포인터를 사용하여 연산식 묶어내기 2

    October 03, 2012

    이번 글에서는 Stat 자료구조 내에 배열이 있을 때 이를 어떻게 처리할지에 대해서 알아보도록 하자. Stat 코드를 작성하다보니, 이동 속도에 관해서는 각각의 변수를 따로 두는 것 보다, 배열 하나로 처리하는 것이 더 낫다는 것을 깨닫게 되었다. 배열로 묶어서 movingSpeed 관련 코드가 개선된 것까지는 좋았는데 hp와 movingSpeed는 type…

  • 멤버 데이터 포인터를 사용하여 연산식 묶어내기 1

    October 01, 2012

    게임 내 스탯 시스템을 구현한다고 해보자. 그 스탯들은 여러 상황에서 버프에 의해 값이 변경될 수 있기 때문에 스탯을 저장하는 자료구조와 그 스탯을 변경하기 위한 버프 종류 enum과, 각 버프 종류 enum에 따라 스탯을 어떻게 변경할지에 대한 연산식에 대해서 코딩을 해주어야 한다. 일단 각 스탯에 어떤 값을 어떻게 계산하면 되는지에 대해서는 다음의 3가지로 추상화를 했다고 치자. SET, ADD, RATE…

  • c++에서 reflection 사용하기 3

    June 09, 2012

    지난 #2에서는 class_t, field_t 자체가 가상 함수를 갖고, class_impl_t와 field_impl_t가 이 class를 상속 받아서 구현하는 방식을 사용하였다. 사실 굳이 이 impl_t class 들은 노출될 필요가 없으므로 이를 감추도록 해보자. 그리고 다 완성된 type을 register함에 있어, 따로 register_class, register_field…

  • c++에서 reflection 사용하기 4

    June 09, 2012

    이전 글에서는 자료구조가 선언된 header파일을 여러 번 include하면 문제가 발생했었다. 하지만 이리저리 참조가 되다보면 각 번역 단위에서 include가 한 번만 되는 것은 굉장히 힘든 일일 것이다. 따라서 본 글에서는 매크로를 잘 정의해서 선언 header파일이 구조체 선언, reflection 등록 딱 2번만 include가 될 수 있도록 만들어볼 것이다. 이전 글(#…

  • c++에서 reflection 사용하기 2

    June 04, 2012

    지난 번 글의 문제점은 다음과 같다. class 정보가 없다. 따라서 이름으로부터 class에 대한 객체를 생성할 수가 없다. field에 대한 정보가 구체 class에 묶여있다. 따라서 그 class를 모르면 field 정보를 얻어올 수 없다. 그래서 이번에는 다음의 기능을 중점으로 구현하였다. 이름(문자열)로 class 정보 찾기 class 정보는 class 객체를 생성할 수 있어야 함 class 정보는 field…

  • c++에서 reflection 사용하기 1

    June 03, 2012

    mmo-server에서 attribute를 json serialize하기 위해 attribute가 가지고 있는 field의 정보를 enumerate 해야할 일이 생겼다. 그런데 c++은 reflection이 없잖아? 그렇게 고민하다가 예전에 쓴 글을 발견했다. c++에서 구조체 RTTI 정보 남기기 기본 아이디어는 다음과 같다. 각 class마다 자신의 field…

  • lambda와 RAII 2

    May 12, 2012

    C++11은 lambda expression을 지원해주니 좀 다르게 생각해볼 수 있다. lock_t class 자체에 위와 같이 functor를 받아 실행할 수 있는 함수를 만든다. 그리고 그 앞 뒤로 lock-unlock을 불러준다. 이렇게 하면 lambda를 사용하여 lock 사용 코드를 보다 깔끔하게 정리해볼 수 있다. lambda를 통해 lock…

  • lambda와 RAII 1

    April 01, 2012

    C++11 에서 도입된 lambda expression을 통한 RAII 구현 방식의 한 예와, 단위 전략을 통한 RAII 구현을 통해 장단점을 비교해보자. Wiki: Resource Acquisition Is Initialization(RAII)는 scope 내의 정적으로 할당되는 객체의 생존 주기로 생성자와 소멸자가 쌍으로 호출되는 것을 사용하는 자원 관리 기법이다. 보통 IO…

  • 환형큐의 thread unsafety 문제

    February 23, 2012

    어떤 자원에 대한 환형큐가 있다고 해보자. size는 2의 자승이다. 위 코드는 당연히 thread safety 하지 않다. 하지만 문제가 발생하지 않도록 나름 머리를 써서 다음과 같이 위 코드를 사용한다고 해보자. 예전 자원을 반환하고, 새로운 자원을 할당받아 그것으로 무슨 작업을 하는 것이다. 이렇게 되면 pop 을 부르는 시점의 thread 는 적어도 자신이 push 한 자원…

  • template의 암시적 interface 요구

    January 10, 2012

    상속을 통한 동적 다형성을 이용하려면, 명시적인 interface가 형성되어야 한다. 와 같이 interface와 이를 구현(implements)하는 구체 class를 작성하고 이처럼 동일한 interface로 취급할 수 있도록 하나의 container에 각 구체 class들의 객체를 담고 iterating하면서 update 함수를 불러준다. 이 때 type은 game_object *이므로 update…

  • template 인자를 상속 받기

    January 09, 2012

    위와 같은 형태가 어떤 의미를 지니고, 어느 곳에서 사용될 수 있는지 살펴보자 일단 자신의 부모 class를 generic하게 취할 수 있다는 것은 부모의 class 와 자식의 class 간의 결합성을 어느 정도 느슨하게 준다는 의미가 있다. (인자로 무엇을 주냐에 따라 상속 구조가 바뀌니까.) 또한 부모 class의 종류에 상관없이 동일한 기능을 추가해줄 수 있다거나, 아니면 부모 class들이 동일한 interface…

  • type_t class 도입을 통한 임시 객체 없는 type 분기

    November 15, 2011

    어떤 class 2개가 있다. 이 class들은 기본 생성자에서 굉장히 복잡한 작업을 하는 객체들 혹은 생성 자체가 복잡한 class들이다. 이러한 class에 대해 어떠한 작업을 수행하는 generic한 함수가 있다. 이 함수는 객체의 type을 받아서 내부에서 모종의 작업을 수행하게 된다. 따라서 메인 함수에서는 다음과 같이 각 class에 대해 operation…

  • c++ 에서 구조체 RTTI 정보 남기기

    September 30, 2011

    RTTI는 Run-time Type Information의 약자로, 실행 중에 어떤 type에 대한 정보를 알 수 있다는 것이다. 보통 type 에 대한 정보는 컴파일 타임에 다 사용되고, 실행 중에는 없어지는데, 실행 중에 이 정보를 얻을 수 있으면 재밌는 일을 많이 할 수 있다. Java나 C#, 아니면 여타 동적 언어들은 당연히 이 기능을 지원하고 (보통 reflection 이라고 한다) C, C…

  • 탈무드 이야기

    September 20, 2011

  • Concurrent Pool (Static Size)

    August 22, 2011

    정적인 크기의 Thread-safe한 (Concurrent) Object Pool을 만들어보자. 핵심은 배열을 사용한다는 것. 왜냐하면 여러 thread가 접근해도 자신만의 index 지점을 접근하면 한 지점에 동시에 thread가 접근하면서 발생하는 문제가 없기 때문. 이게 동적으로 크기가 확장되면 배열의 포인터가 무효화되면서 여러 문제가 생길 수 있어 복잡하다. 따라서 정적인 크기라고 고정짓고 이야기를 해보자. Object…

  • 객체별 함수 수행 동기화

    August 11, 2011

    (주의, 아래 글은 Visual Studio 2010 을 쓴다는 가정하에 작성하였다. 아무튼 C++11 이 지원되어야 한다) 여러 Thread가 동시에 접근을 수행하는 객체를 보호하기 위해서는 어떤 방법이 있을까? lock을 건다 각 Thread들은 하나의 queue에 요청할 작업을 쌓아두고, 그 객체 전담 Thread가 그 작업들을 처리한다. Read / Write Phase를 나누어서 Read는 다같이, Write…

  • volatile과 interlocked operation

    August 02, 2011

    volatile 다음과 같은 코드가 있다. 세 번의 ++ 연산을 모두 a 라는 변수에 수행하므로, 컴파일러는 최적화를 통해 다음과 같은 코드를 만들어낼 수 있다. 만약 multi-thread 환경에서 저 코드가 여러 thread에 의해 수행된다고 하면, add eax를 수행하고 mov dword ptr [count], eax를 수행하기 전에 switching이 되면, 다른 코드에서는 아직 count…

  • MSVC call stacktrace 구현

    July 20, 2011

    이전에 Macro와 inline을 사용하여 log를 찍는 이야기를 했었다. 좀 더 나아가면 여러가지 재밌는 일을 할 수 있어 소개해보고자 한다. 다룰 내용은 __FUNCSIG__와 __if_exists이다. Visual Studio 전용일거다. gcc 유저는 저리가라 지인의 이야기를 들어보니 x64에서 디버깅을 할 경우 Call Stack이 알 수 없게 쌓인다고 한다. 따라서 x64 용 디버깅을 위해 Call Stack…

  • 객체의 생성, 소멸과 goto 이야기

    July 20, 2011

    생성자 소멸자 이야기 어떤 class의 생성자와 소멸자를 구현했다. 거기에서는 엄청나게 복잡한 작업을 수행한다. 예를 들면, 그리고 저 객체를 다음과 같이 사용한다고 해보자. 무엇이 문제일까? 복사 생성자와 대입 연산자가 적절하게 잘 구현되어있다고 하자. 그러면 sallow copy 문제는 당연히 아니다. 문제는 vector 자체가 Object로 구현되어 있기 때문에 내부에 Object…

  • class의 public과 private

    July 20, 2011

    예전에 동아리 선배님께서 어떤 코드를 수정하시면서 하셨던 말이 있다. “왜 멤버가 다 public 으로 되어있는거야!” 요즘 읽고 있는 코드에서 몇 개의 class 들이 저런 문제점을 지니고 있다. 다음 예제를 보자. (volatile keyword를 사용한 이유는 다음에 설명하겠다) 저런 class가 있다고 할 때 저 interface만 보고 class가 무슨 일을 하는지 알 수 있을까? 이름도 적절히 Worker…

  • template을 사용한 type간 동등성, 대입가능성

    July 19, 2011

    runtime에 typeid를 써서 객체 type의 동등성(Same)을 확인하고, dynamic_cast를 써서 객체간의 대입가능성(Assignable)을 확인할 수 있다. 하지만 이런 것을 확인하기 위해 runtime을 소모하는 것은 너무 아까운 일이다. 고로 template을 써보자. 아래의 예제는 두 class, C1과 C2를 통해 진행된다. 동등성 확인 type…

  • template에 의한 generic interface 정의

    July 13, 2011

    알고리즘 등의 일반화나 의존성 제거를 위해서 class 사이를 interface 로 쪼개는 경우가 있다. 나는 C++ 보다는 Java가 더 익숙해서 template보다는 interface나 generics를 사용하는게 더 익숙한 편이다. 그래서 저번 자료구조 숙제를 할 때도 당황했던 것이, Iterator나 List 에 대해 Vector나 LinkedList를 구현할 때, 먼저 Interface…

  • thread local storage 초기화

    July 13, 2011

    Tls는 Thread Local Storage로 Thread 내 전역변수라고 생각하면 간단하다(Local 인데 왠 전역!) 즉, 그냥 global 영역에 선언하는 변수는 프로그램 내에 여러 Thread 가 공유하는 자원이 되지만, Tls 로 선언한 자원들은 해당 Thread 별로 따로 갖는다고 보면 된다. (이 때문에 strtok 같은 함수도 내부에서 static 변수를 써도 Tls 로 선언하면 Multithread…

  • 반복자 i++과 ++i에 대한 헛소리

    July 01, 2011

    반복문에서 반복자를 증가시킬 때, for ( ; ; i++)과 for ( ; ; ++i)를 이야기할 때, 뭐가 빠르네 느리네 이야기가 왜 나왔을까? 간단히 생각해보면, i++과 ++i는 동작이 약간 다르다. 연산자 우선순위는 i++이 좀 더 빠르지만, 실행 측면에서 본다면 i++은 자신의 상태를 저장한다 자신의 상태를 변화한다 저장한 예전 상태를 반환한다 ++i는 자신의 상태를 변화한다 자신 자체를 반환한다. i++의…

  • class와 memset

    December 24, 2010

    c++의 class보다 java의 class를 훨씬 많이 쓰는 나는 사실 c의 struct라면 모를까 c++의 class는 아직도 생소하다. struct를 쓸 때, 가장 좋은 점 중 하나는 초기화라고 생각하는데, 와 같이 선언과 동시에 초기화를 할 수가 있어 만약 모든 값을 NULL(or 0)으로 채우려면 class…

  • stl operator 실수

    December 24, 2010

    어제 나를 1시간동안 고민하게 한 코드는 다음과 같다. 어제 정신이 없었다고 변명을 해도 너무 어이없는 실수를 저질렀는데 더 큰 문제는 컴파일에서 뱉어주는 에러를 보고도 해당 문제를 파악하지 못했다는 것이다. 위 코드의 문제는 나는 OOP 수업의 영향으로 class declaration에서 public - protected - private 순으로 선언을 하고, public method…

  • LockWindowUpdate

    December 18, 2010

    Win32 혹은 MFC를 하다보면 어떤 창 내에 여러 Child Window가 존재하고, 또, 해당 DC를 얻어서 그림을 그려야하는 경우가 생긴다. 이들이 모두 변경되는 경우, 즉 그림도 변경되고 Child Window도 SetWindowPos 등의 함수를 통해 변경될 경우에 그림은 InvalidateRect() 등의 함수에 의해 다시 그려질 것이나 Child Window는 SetWindowPos나 ShowWindow…

  • const overloading

    October 12, 2008

    c++의 overloading은 c에서 어떤 함수를 단순히 함수의 이름으로만 식별했던 것에 비해 함수의 인자의 type, 개수, 혹은 const/volatile 여부까지 고려해서 식별한다는 것이다. 즉 linking 시점에서 호출하는 지점과 호출 당하는 지점을 연결해줄 때 호출하는 지점에서 요구하는 함수의 정보(함수 이름, 인자 type, 개수, const/volatile 여부)를 기반으로 함수 table…