'전체'에 해당되는 글. 250건

  1. 2010/07/30 [C++0x] r-vaule reference: 파라미터의 const 속성 없애기!? (1)
  2. 2010/07/25 [C++] r-value vs. l-value (1)
  3. 2010/07/25 World of Warcraft: 리치왕의 분노 설치 화면... (1)
  4. 2010/07/22 [Apache] 찾을 수 없습니다. (3)
  5. 2010/07/13 [C++] r-value Reference: Performance (2)
  6. 2010/05/28 2010 지방선거.. (5)
  7. 2010/05/27 [C++] 임의의 이름의 변수 만들기
  8. 2010/05/15 [C++] 지연 호출(Deferred Functional Call) 구현
  9. 2010/04/28 예비군 훈련(관동 교장) (3)
  10. 2010/04/21 [C++] Visual Studio 2010, GCC 4.5.0 Released (2)
  11. 2010/03/31 [Tip] Chrome에서 사용하기 좋은 드래그 사전(DragDic) Bookmarklet (1)
  12. 2010/03/28 [C++] Google의 C++ 라이브러리 (2)
  13. 2010/03/24 [RSS] 네이버 Hot 뉴스 피드
  14. 2010/03/24 [RSS] 네이버캐스트 Feed (2)
  15. 2010/03/19 [VS] ProjectName도 창 제목 표시 해주기.
  16. 2010/03/07 [Tip] Customizing Windows Command Prompt (2)
  17. 2010/03/02 [Game] GameTech 2010 - TERA의 서버 구조 (1)
  18. 2010/02/16 한국 귀화시험 기출 문제... (1)
  19. 2010/02/16 [RSS] 네이버 캐스트 Feed (2)
  20. 2010/02/04 빌드(컴파일, 링크) 속도가 느리다면.... (3)
  21. 2010/01/22 [MySQL] NULL이지만 NULL이 아닌 슬픈 이야기.. (3)
  22. 2010/01/18 [Linux] 콜스택이 깨진 Core 파일 디버깅 하기 (5)
  23. 2010/01/13 내 책상 (2010) (6)
  24. 2009/12/22 [VS] 위대한 발견: Visual Studio 검색창 늘리기 (2)
  25. 2009/10/31 [Vim] 여러 파일 Tab으로 열기 (2)
  26. 2009/06/12 슬픈이야기... (7)
  27. 2009/05/22 F#, Project Euler - Problem #4 (2)
  28. 2009/05/12 F#, Project Euler - Problem #12
  29. 2009/05/12 F#, Project Euler - Problem #20
  30. 2009/05/11 F#, Project Euler - Problem #5

 C++ 표준 문서 N2798의 14.3.1의 4번째 항목을 보면. 위와 같은 내용이 있다.
 ( 더 최신 문서인 N3092 에는 위 항목이 빠져 있음. )

 해석을 해서 옮기고 싶지만..
 괜히 혼란만 가중 시킬것 같아서.. 패스하고..

  아무튼 자세히 보면.. 정말 해괴망측한 부분이 있는데
  그 부분을 조금 더 살펴 보자면... 아래와 같은 코드가 있다고 했을 때

    1 template<typename T>

    2 struct X

    3 {

    4     static void f(const T& t)

    5     {

    6         t.a = 100;

    7     }

    8 };

 
 함수 f()는 const로 받은 변수의 값을 변경하고 있다.
 얼핏 보아도 이상한 코드다.
 (  아직 template가 instantiation이 되지 않아서 이 부분만 가지고는 컴파일 에러가 나지 않는다.)


 코드를 조금 더 작성해 보면..

    9 struct S

   10 {

   11     int a;

   12 };

   13 

   14 int main(int argc, char* argv[])

   15 {

   16     S s;

   17     X<S>::f(s);

   18 


이제 아마 Line 17에서 readonly인 a에 값을 넣으려고 했다고 해서 컴파일 에러가 날 것이다.
근데 C++0x 부터는 이를 회피할 수 있는 아주 간단한 방법이 생겼다.
단순히 ' & ' 하나만 추가 하면 된다.


   16     S s;

   17     X<S&>::f(s);

   18 

   19     cout << s.a << endl;


 이제 함수 f()는 
 void X::f(S& t) 와 같이 파라미터의 타입이 정해지고, const 속성을 날려버리게 된다. 우왕ㅋ굳ㅋ
 ( 물론, 이렇게 만들어서 const 속성을 없애서 쓰자는 이야기는 절대 아님...)



 C++의 복잡도는.. 날이 갈 수록 올라가고 있다.


끝으로 Quiz..
각각 파라미터 타입은 어떻게 될까요? ( Line 11 ~ Line 29 )
참고로 gcc 4.5.0과 VS2010 에서 둘다 돌려봤는데. 같게 나왔습니다.

    1 template<typename T>

    2 struct R

    3 {

    4     static void A(T&){}

    5     static void B(const T&){}

    6     static void C(T&&){}

    7     static void D(const T&&){}

    8 };

    9 

   10 {

   11     R<int&>::A(?)

   12     R<int&>::B(?)

   13     R<int&>::C(?)

   14     R<int&>::D(?)

   15 

   16     R<const int&>::A(?)

   17     R<const int&>::B(?)

   18     R<const int&>::C(?)

   19     R<const int&>::D(?)

   20 

   21     R<int&&>::A(?)

   22     R<int&&>::B(?)

   23     R<int&&>::C(?)

   24     R<int&&>::D(?)

   25 

   26     R<const int&&>::A(?)

   27     R<const int&&>::B(?)

   28     R<const int&&>::C(?)

   29     R<const int&&>::D(?)

   30 }



Posted by U_Seung

{Quiz}. 다음 중 l-value는 몇 개일까요? (line 12 ~ line 29 중에서.. )


    1 int* pa = &a;

    2 const int* pb = &a;

    3 

    4 int fa() { return 1; }

    5 const int fb() { return 2; }

    6 

    7 int& fra() { return a; }

    8 const int& frb() { return b; }

    9 

   10 void main_rvalue()

   11 {

   12     RVALUE_CHECKER(1);

   13     RVALUE_CHECKER(int(1));

   14     RVALUE_CHECKER(new int(1));

   15     RVALUE_CHECKER(*(new int(1)));

   16 

   17     RVALUE_CHECKER(++a);

   18     RVALUE_CHECKER(a++);

   19     RVALUE_CHECKER(a + 1);

   20 

   21     RVALUE_CHECKER(++*pa);

   22     RVALUE_CHECKER(*pa++);

   23     RVALUE_CHECKER(*pa + 1);

   24 

   25     RVALUE_CHECKER(fa());

   26     RVALUE_CHECKER(fb());

   27 

   28     RVALUE_CHECKER(fra());

   29     RVALUE_CHECKER(frb());

   30 }



참고로...
#1.  l-value, r-value 구분은 expression에 대한 구분임 (type 이라던지 하는 건 관계가 없음.)
#2.  ++a (line 17) 은 l-value 이지만, a++ (line 18)은 rvalue임.


Posted by U_Seung







 Localization 할 때...
 굴림체 쓰면 진짜 없어 보임..



'잡담 놀이터' 카테고리의 다른 글

World of Warcraft: 리치왕의 분노 설치 화면...  (1) 2010/07/25
2010 지방선거..  (5) 2010/05/28
예비군 훈련(관동 교장)  (3) 2010/04/28
내 책상 (2010)  (6) 2010/01/13
슬픈이야기...  (7) 2009/06/12
AION 계정 털리다.  (8) 2009/05/04
오랜만에 블로깅...  (3) 2009/04/23
Posted by U_Seung

 Apache를 설치하고, 서비스를 시작하면.. 간혹 실행이 안되고 실패를 한다.
 특별한 메시지를 주는 것이 아니기 때문에.. 관리도구 - 이벤트 로그를 확인 하면..



 뭔가 알 수 없는 메시지를 준다.
 
 아무래도.. 알 수가 없어서.

 >>> \xc3\xa3\xc0\xbb \xbc\xf6 \xbe\xf8\xbd\xc0\xb4\xcf\xb4\xd9.

 여기에 단서가 있을까 해서.. 좀 살펴 보니..

 1. 한글이 깨진 것 같고,
 2. \x 가 붙은 것으로 봐서 바이너리 형태 같고,
 3. 세글자가 아닌 두 글자로 쪼개지며, 대충 범위 대역이 EUC-KR 같아서..

  바꿔 보기로 했다. 

  gvim을 이용해서 아래 처럼 입력하고..
  도구(T) - 원래대로 변환(r) 을 누르면..
  xxd 프로그램으로 Binary로 바꿔 준다.



 결국, 이 메시지 만으로는 문제를 '찾을 수 없다는 것'을 알게 되었다.
 장난 하냐? 응?



Posted by U_Seung

r-value reference 쓸려고 테스트를 해봤습니다.


#. 일단 임의의 문자열(string) N개를 vector에 넣고..

    1     static const size_t N = 100000;

    2     static const size_t MaxLen = 100;

    3     static const char range[] = "abcdefghijklmnopqrstuvwxyz_0123456789";

    4 

    5     struct rnd_gen

    6     {

    7         char operator()() const

    8         {

    9             return range[std::rand() % (_countof(range) - 1)];

   10         }

   11     };

   12 

   13     std::vector<std::string> v(N);

   14     for(int i=0; i<N; ++i)

   15     {

   16         std::generate_n(

   17             std::back_inserter(v[i]),

   18             std::rand() % MaxLen + 1, rnd_gen());

   19     }



#. Sorting 해보고

   20     {

   21         boost::timer t;

   22         std::sort(v.begin(), v.end());

   23         std::cout << "Sort: " << t.elapsed() << std::endl;

   24     }



#. Join 해봤습니다.

   25     {

   26         boost::timer t;

   27         std::string result = boost::algorithm::join(v, ",");

   28         std::cout << "Join: " << t.elapsed() << std::endl;

   29     }




-[ VS 2008 ]--------------
Sort: 0.178
Join: 0.104

-[ VS 2010 ]--------------
Sort: 0.079
Join: 0.029


 C++0x 이전에는 위 처럼 코딩 하지 말라고 했겠죠..
 사실 부자연 스러울 것이 없는 코드인데..
 하지 말라고 하는게 안타까운 상황이었습니다..ㅋ




Posted by U_Seung



 나도 소중한 나의 권리를 의미있게 사용하고 싶지만...
 인간적으로 정책선거를 하기엔 내가 너무 많은 비용을 소모해야 한다.

 차라리 각 후보별 비교자료를 일목요연하게 볼 수 있게 해주던가 하지...
 재활용도 안된다는 저 전단지는 전단지대로 아깝고..
 내 참여 의지는 더욱 떨어지고..

 안타깝구려...




'잡담 놀이터' 카테고리의 다른 글

World of Warcraft: 리치왕의 분노 설치 화면...  (1) 2010/07/25
2010 지방선거..  (5) 2010/05/28
예비군 훈련(관동 교장)  (3) 2010/04/28
내 책상 (2010)  (6) 2010/01/13
슬픈이야기...  (7) 2009/06/12
AION 계정 털리다.  (8) 2009/05/04
오랜만에 블로깅...  (3) 2009/04/23
Posted by U_Seung
TAG 선거

C++로 프로그래밍을 하다보면 딱히 변수 이름이 중요하지 않을 때가 많이 있습니다.
주로 생성자 혹은 파괴자를 이용한 RAII 패턴을 사용하는 상황이 그렇습니다.


임의의 변수명은 Macro를 이용하여 구현합니다.

 

#include <boost/preprocessor/cat.hpp>

#define RANDOM_NAME BOOST_PP_CAT(_random_, __COUNTER__)

 


선언은 위와 같이 하고
대략적인 사용은 아래와 같이 합니다.

 

namespace NS

{

    bool Func(Arg* arg)

    {

        SomeGuard<Arg> RANDOM_NAME(arg);

 

        (...)

    }

 

    static Initialization RANDOM_NAME;

}

 



이렇게 만들어진 변수 명은 '해당 변수를 생성자와 파괴자의 동작만 사용하겠다' 라고 명시적으로 지정하는 역할도 담당하게 됩니다. 변수 명을 알 수가 없으니까 강제로 다른 용도로 사용하려고 해도 할 수가 없겠지요.



Posted by U_Seung

제가 구독하는 블로그 중에
rein님의 C++0x를 써서 Closure 다시 만들기와 C++기반의 closure를 보고
제가 쓰고 있던 방법도 공개 합니다.


사용할 수 있는 곳은 여러 곳이 있겠습니다만..
다른 곳으로 Message를 Passing 한다던가 Timer를 쓴다던가 할 때
유용하게 쓸 수 있겠습니다.




typedef
function<void (void)> Closure;


C++0x가 지원되면 std.function을 써도 되고
그렇지 않으면 boost.function을 쓰면 됩니다.




void
freef(int a, int b)

{

    cout << a << " + " << b << " = " << a+b << endl;

}

 

struct Class

{

    Class(int a): a_(a) {}

 

    void memf(int b)

    {

        cout << a_ << " - " << b << " = " << a_-b << endl;

    }

 

    int a_;

};

 

vector<Closure> closures;

{

    int a = 10;

    closures.push_back(bind(freef, a, 4));

    closures.push_back(bind(&Class::memf, new Class(a), 2));

//  closures.push_back([=](){ cout << a << endl; });

}

 

foreach(Closure& closure, closures)

{

    closure();

}



마찬가지로 std.bind 나 boost.bind를 사용하고,
C++0x가 지원되면 lambda를 추가적으로 사용할 수 있습니다.




Posted by U_Seung



 예비군 훈련을 처음 다녀왔습니다.
 3일 교육이고 날마다 09:00 ~ 18:00 (8시간)  동안 하는 교육입니다.

 훈련장까지 가는데는 1시간 30분정도 잡아야 되고 (버스 기다리는 시간 포함)
 돌아오는 데는 1시간 정도 걸렸습니다.


 첫 예비군 훈련 소감을 말하자면... -_-
 착한(?) 날씨 덕분인지..



 밖에서 비 맞으면서 오들오들 떨다보니
 앉아있는 것도, 서 있는 것도 고욕이었습니다.

 안 그래도 충분히 추운 군대.... 몸도 마음도 정신도 얼어 붙게 만들거더군요..
 

 이틀간 충분히 즐거웠는데..
 더 즐거운 사실은... 내일 새벽에 일어나서 또 가야 된다는거 ㅡoㅡ;



이 장소를 Daum지도에서 확인해보세요.
경기도 안양시 만안구 석수1동 | 관동예비군훈련장
도움말 Daum 지도

'잡담 놀이터' 카테고리의 다른 글

World of Warcraft: 리치왕의 분노 설치 화면...  (1) 2010/07/25
2010 지방선거..  (5) 2010/05/28
예비군 훈련(관동 교장)  (3) 2010/04/28
내 책상 (2010)  (6) 2010/01/13
슬픈이야기...  (7) 2009/06/12
AION 계정 털리다.  (8) 2009/05/04
오랜만에 블로깅...  (3) 2009/04/23
Posted by U_Seung
TAG


 둘다 깔아서 써보고 있는데 괜찮네요 :)

 이제 tr1뿐만 아니라.
 auto, decltype, lambda, strongly typed enum, Rvalue references 등등의 
 C++0x의 훌륭한 Feature 들을 양쪽에서 사용할 수 있게 되었습니다.

 저런 것들은 Boost 등과 같은 Library 만으로 커버가 안되는 것들이라서 더 의미가 깊다 할 수 있겠습니다.



 이건 g++ 4.5.0 인증샷.

#1.  Local Class를 template parameter로 넘길 수 있게 되었습니다.

#2. -flto 옵션이 컴파일, 링크에 추가 되었습니다. 

#3. c++0x feature 중에 하나인 lambda 가 가능해졌습니다.









Posted by U_Seung
TAG C++, gcc

DragDicN: 네이버 사전

DragDicD: 다음 사전

DragDicY: 야후 사전



 만든지 정말 오래된 것이지만..
 Chrome이 IE보다는 크롬을 더 많이 쓰기 시작한 시점에서 더욱 유용해졌습니다.
 그래서 Chrome에 더 잘 맞도록 수정했습니다. (추가 버튼 색상을.... )

 사용법은...
 1. Boomarklet을 Browser에 등록 합니다.
 2. 사전에 찾아 보고 싶은 단어를 마우스로 Drag합니다. (옵션)
 3. 설치한 북마클릿(Bookmarklet)을 클릭 합니다.





 4. 그럼 아래와 같은 창이 뜹니다.



 5. 단어 뜻을 봤으면 .. 창을 닫아 버리면 됩니다. (옵션)




Posted by U_Seung

C++ 관련 자료를 찾다 보면 
Google에서 공개한 자료를 많이 접할 수 있게 됩니다.

뭐 사실 C++의 Library야 찾아보면 다른 Library도 많습니다만...
Google의 자료들은 몇가지 공통적으로 기본빵을 해주는게 몇 가지 있는데..
 - 오픈소스라서 소스레벨의 접근이 가능합니다.
 - 라이선스가 BSD/MIT 입니다. 즉 GPL이 아니라서 라이선스 제약이 상대적으로 덜 합니다.
 - 멀티 플랫폼을 지원합니다. (Windows/Linux은 기본으로 됩니다.)
 - 마지막으로 Google이라는 거대 회사에서 직접 적용해본 도입 사례가 있습니다.


제가 찾은 Google의 자료를 공유 합니다. 이밖에 좋은 자료가 있으시면 공유 부탁드립니다.


#. Google Test & Google Mock
 - Google Test: Google C++ Testing Framework
 - Google Mock: Google C++ Mocking Framework

   C++의 xUnit 도구들이 상당히 많은데.. 사용하다보면 뭔가 하나씩 부족한 느낌이 듭니다.
  그 중에서 제일 덜 부족한 느낌이 드는게 Google Test가 아닌가 싶습니다.







#. Google Performance Tools
 - Google Perftools: Fast, multi-threaded malloc() and nifty performance analysis tools

   멀티쓰레드에서 더욱 좋은 성능을 내는 TCMalloc(Thread-Caching Malloc), CPU Profiler를 제공 합니다. TCMalloc에는 HeapProfiler와 HeapChecker포함되어 있습니다. 하지만, Windows 쪽은 지원이 미약하며 다른 좋은 것들도 많기 때문에 Linux에서 쓰기에 적합하다고 할 수 있겠습니다.







#. Google Log
 - Google glog: Logging library for C++

   glog는 Application Level Logging을 할 때 쓰는 Library입니다. 서버 Application을 만든다면 반드시 어떠한 방식으로든 로깅 기능을 사용할텐데 참조가 될만한 Library입니다. 직접 써도 좋을 것 같다는 생각도 들고요.

  인상적인 부분중에 하나는 google::InstallFailureSignalHandler() 함수 하나만 호출하면.. SIGSEGV 등을 받으면 아래와 같이 Logging을 하게 해준다고 합니다. 매우 편할 것 같습니다. 

*** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: *** PC: @ 0x412eb1 TestWaitingLogSink::send() @ 0x7f892fb417d0 (unknown) @ 0x412eb1 TestWaitingLogSink::send() @ 0x7f89304f7f06 google::LogMessage::SendToLog() @ 0x7f89304f35af google::LogMessage::Flush() @ 0x7f89304f3739 google::LogMessage::~LogMessage() @ 0x408cf4 TestLogSinkWaitTillSent() @ 0x4115de main @ 0x7f892f7ef1c4 (unknown) @ 0x4046f9 (unknown)







#. Google Sparse Hash
 - Google Sparse Hash: An extremely memory-efficient hash_map implementation

 긴 설명 보다는 아래 테스트 결과가 많은 것을 말해줄 수 있을 것 같습니다.

Average over 10000000 iterations
Wed Dec  8 14:56:38 PST 2004

SPARSE_HASH_MAP:
map_grow                  665 ns
map_predict/grow          303 ns
map_replace               177 ns
map_fetch                 117 ns
map_remove                192 ns
memory used in map_grow    84.3956 Mbytes

DENSE_HASH_MAP:
map_grow                   84 ns
map_predict/grow           22 ns
map_replace                18 ns
map_fetch                  13 ns
map_remove                 23 ns
memory used in map_grow   256.0000 Mbytes

STANDARD HASH_MAP:
map_grow                  162 ns
map_predict/grow          107 ns
map_replace                44 ns
map_fetch                  22 ns
map_remove                124 ns
memory used in map_grow   204.1643 Mbytes

STANDARD MAP:
map_grow                  297 ns
map_predict/grow          282 ns
map_replace               113 ns
map_fetch                 113 ns
map_remove                238 ns
memory used in map_grow   236.8081 Mbytes






#. Google CoreDumper
 - Google CoreDumper: A neat tool for creating GDB readable coredumps from multithreaded applications

  Runtime에 원하는 시점의 Memory를 Dump할 수 있는 기능입니다.
  ASSERT를 걸어야할 시점이 Runtime에서 한참 작업을 진행중이라면 Core만 떠두고, 일단 작업을 진행하도록 한 다음에 나중에 수정하여 업데이트 하는 방법이 있겠습니다.
 (당연히도) Linux만 지원됩니다.







#. 그 밖에..
 - gflags: Commandline flags module for C++
 - Keyczar: Toolkit for safe and simple cryptography
 - Breakpad: An open-source multi-platform crash reporting system
 - Omaha: Software installer and auto-updater for Windows
 - Protocol Buffers: Google's data interchange format

그리고 꼭 읽어보길 권장하는...
Posted by U_Seung
Posted by U_Seung

네이버캐스트 :: 교양 경제학RSS

네이버캐스트 :: 옛날신문RSS

네이버캐스트 :: 오늘의 문학RSS

네이버캐스트 :: 오늘의 클래식RSS

네이버캐스트 :: 지구촌 산책RSS

네이버캐스트 :: 철학의 숲RSS

네이버캐스트 :: 키친 스페셜RSS

네이버캐스트 :: 포토 스페셜RSS

Posted by U_Seung


 S/W 개발을 하다 보면... 프로젝트들이 하나 둘 추가 되고
 그러다보면 Visual Studio 창은 온갖 창들로 복잡해 집니다.

 저 같은 경우에는 파일 이름을 정하는 것이 힘들어서 프로젝트는 다르지만 같은 이름의 파일을 많이 만들게 됩니다. 그러다 보면 이게 어느 파일인지 창만 보고는 분간이 힘들어지고, 작업이 불편하다고 느끼게 되었습니다.



 그래서 찾아낸 해결 책이 Tabs Studio Add-in 입니다.
 Tabs Studio에 보면 여러 기능이 있는데 그 중에서 창 제목을 바꿀 수 있는 기능을 제공 합니다.
 이를 이용 해서 창 제목에 [$(ProjectName)] $(FileName) 가 되도록 만들었습니다.
 ( Tabs Studio에서는 Add-in안의 Add-in 기능을 제공하는데.. 제작자가 샘플로 공개한 Disambiguator를 조금 고쳐서 만들었습니다. )

 이렇게 쓰고 나서 부터는 작업 효율이 좀 나아진 느낌입니다. :)



Posted by U_Seung


#1. Prompt 설정.

PROMPT=$P$G$_$$

계속 사용하고 싶으면..
환경 변수에 등록해주면 됩니다.

몇 가지 포인트가 있는데..
$_는 한 줄을 바꿀 때 씁니다.
마지막에 Space 를 넣어 주는 것이 보기 편합니다.

편의에 따라서 %USERNAME%, %COMPUTERNAME% 등을 넣어 줄 수도 있지만
Remote로 접속하는 경우가 적기 때문에 필요 없는 경우가 많습니다.

 

#2. 폰트 변경.


Fixed Width 폰트를 지정할 수 있습니다.
한글은 굴림체, 돋움체, 나눔고딕 코딩 등을 지정할 수 있습니다.
원하는 폰트가 목록에 나오게 하기 위해서는
Registry의 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont 에 추가하시면 됩니다.

영문폰트를 사용하고 싶으시면 Codepage를 바꿔야 합니다.
chcp 명령어를 사용하거나
Registry의 HKEY_CURRENT_USER\Console의 하위를 직접 세팅 해서 바꾸면 됩니다.

Posted by U_Seung

지난 주에 GameTech 2010에 다녀 왔습니다.
정말 오랜만에 세미나를 들으러 갔던 것 같습니다.

GameTech 2010 공식 홈페이지: http://gametech.gamespot.co.kr/

여러가지 세션을 들었지만 가장 인상 깊었던 블루홀 스튜디오의 세션에 대해서만 몇자 남깁니다.

일단 TERA의 서버 구조는 매우 간단합니다.
  • 한 Planet(Wow의 Relm)당 수용인원은 대략 5000명 정도 예상.
  • 한 Planet에는 하나의 Arbiter 서버를 Front-end로 둠.
  • 한 Arbiter 서버에는 여러개의 World서버를 Back-end로 둠.
    • TERA에서는 Planet간에도 유저가 만날 수 있는 통합전장이라는 시스템이 있으므로,
      특정 World서버에서는 여러개의 Arbiter 서버와 연결을 가질 수 있음.
이게 끝입니다.
(물론, 로그인과 같은 인증관련 부분은 생략 되었습니다. 한게임에서 처리하니 필요 없을 것 같기도 합니다.)

정말 간단합니다.
그렇기 때문에 역할 구분도 매우 명확합니다.

[Arbiter 서버]
  • 주로 I/O를 담당.
  • Network 통신에 해당하는 Non-Blocking I/O와 Database 작업에 해당하는 Blocking I/O를 담당.
    (내부적으로는 위의 두가지 방식의 Thread Pool을 분리 한다고 함.)
  • 채팅, 길드 등의 게임 로직을 담당

[World 서버]
  • 주로 (CPU작업이 많은) 게임로직을 담당.
  • Blocking I/O만을 처리하며 모든 Thread가 대등한 역할을 수행.
  • 대부분의 게임 로직을 처리하며, 통합 전장/Instance Dungeon 기능도 가짐.

----

여기까지는 발표 내용이고, 제 개인적인 생각을 몇 자 적어보자면...
발표 초반에 액션성을 강조한 게임이라고 TERA의 특징을 소개하였으나
설명을 들을 수록 액션성이 잘 표현되는 CPU와 I/O를 많이 쓰는 곳에 적합한 구조라는 생각은 안 들었습니다.

지금 구조에서는 Arbiter 서버 프로세스 하나에서 대부분의 I/O가 일어 나는데
I/O쪽 부하가 지나치게 집중 되도록 되어 있으며,
안정성 측면에서도 Arbiter 서버 이거 다운되면 어떻게 하나 걱정부터 많이 들었습니다.

물론, 서버 기능별로 채팅서버, 파티서버, 몬스터서버 이렇게 한 없이 분리하다보면
복잡도가 올라가서 결국 서버의 안정성이 떨어진다는 것을 부정하긴 힘들지만
아무리 그래도 프로세스 하나에서 Network I/O, 채팅/길드, DB 까지 다하는 것은 좀 지나치다는 생각이 듭니다. ( 물론, 블로홀 스튜디오에는 국내 최고 수준의 막강 QA 인력이 포진하고 있다고 합니다... )

뭐 이런 저런 우려와 걱정이 되긴 하였지만..
가슴 속에서는 'Arbiter 서버와 World 서버만 있다고? 이거 만들기 엄청 편하겠는데 +_+)/.... '


끝으로 강연자 분이 했던 말씀중에 인상 깊었던 말이 있었는데...
정확히 문구까지는 기억이 나지는 않지만 대략 아래와 같은 말이었습니다.

서버 구조는 해당 게임의 특징에 따라서 다르겠지만 그것과 더불어서 해당 게임을 만드는 팀에 따라서 달라져야 합니다. 지금 만들고 있는 서버 구조는 현재 팀의 구성에 따라서 정한 것입니다. 만약 현재 팀 구성이 아니었다면 다른 모델을 도전 해볼 수도 있었을 것 같습니다.




Posted by U_Seung





Posted by U_Seung

네이버에서는 좋은 정보를 참 많이 제공 해주고 있습니다.
구워진지(Burned) 얼마 되지 않은 Feed.



네이버캐스트 :: 매일의 디자인: RSS, EMAIL

네이버캐스트 :: 아름다운 한국: RSS, EMAIL

네이버캐스트 :: 오늘의 과학: RSS, EMAIL

네이버캐스트 :: 오늘의 미술: RSS, EMAIL

네이버캐스트 :: 오늘의 집: RSS, EMAIL

네이버캐스트 :: 오늘의 체조: RSS, EMAIL

네이버캐스트 :: 인물과 역사: RSS, EMAIL



Posted by U_Seung

 컴파일 속도가 느리다면.. IncrediBuild를 쓰세요.




 링크 속도가 느리다면.
 일단 64비트 OS를 설치하고,
 RAM을 넉넉하게 늘리세요.   ( 4G 이상, 6G 이상 추천 )



 RAM 업그레이드 이후에 체감 링크 속도가 2~3배 빨라졌습니다.

------------------------------------

 OS를 Windows 7 x64로 업그레이드 했더니 빌드 속도가 더 빨라 졌습니다.
 Windows 7 에서 멀티코어 지원이 강화 된 영향 같습니다.





Posted by U_Seung
TAG C++

 일단 어떤 테이블에 varbinary(123) 타입을 가진 컬럼이 하나 있었습니다.

mysql> DESC SomeTable col1;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| col1  | varbinary(123) | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+
1 row in set (0.00 sec)


 이 컬럼에는 NULL이 들어 있었습니다.

mysql> SELECT col1 FROM SomTable LIMIT 0, 10 ;
+------+
| col1 |
+------+
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
+------+
10 rows in set (0.00 sec)


 Stored Procedure를 통해서 여러개의 테이블에서 여러개의 컬럼을 읽는 프로그램이었는데... 디버깅 끝에 이 부분부터 꼬이기 시작한다는 것을 발견했습니다.
 그리고 희한하게도 이 컬럼을 읽는 부분에서 NULL이 아닌 값을 읽고 있는 것을 발견했습니다.




 그리고... 확인결과 ... 진짜 NULL이 아님을 알았고

mysql> SELECT col1 FROM SomeTable WHERE col1 IS NULL LIMIT 0, 10 ;
Empty set (0.00 sec)

 



 비극의 진실은...

mysql> SELECT col1 FROM SomeTable WHERE col1 = "NULL" LIMIT 0, 10 ;
+------+
| col1 |
+------+
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
| NULL |
+------+
10 rows in set (0.00 sec)



.......... oTL

 한 가지 고려해볼 수 있는 사항은
 Binary 컬럼은 SELECT시에 *(asterisk)를 쓰지 않고, HEX(col1) 처럼 HEX() 함수로 감싸도록 (마음속으로.. ) 강제 하는 방법.
 


Posted by U_Seung

 Linux에서 Daemon을 돌리다 보면 버그로 인해서 프로그램이 Crash 되는 일이 종종 있습니다.
 당연히 문제가 되는 부분 찾아서 고쳐야 합니다.

 그럴때 대부분 사용하는 방법이 Process가 죽기전에 기록을 Core파일에 남기도록 설정 하는 방법 입니다.
 정상적으로 남겨진 Core파일 경우라면 디버깅 하는게 큰 문제는 없을 테지만
 아래와 같이 콜스택이 깨져 보이는 난감한 상황을 만들어 내기도 합니다.

Loaded symbols for /lib/tls/librt.so.1

Reading symbols from /usr/lib/libggauth2.so.56...done.

Loaded symbols for /usr/lib/libggauth2.so.56

#0  0x02d10100 in ?? ()

(gdb) bt

#0  0x02d10100 in ?? ()

#1  0x01010000 in ?? ()

#2  0x000002d2 in ?? ()



 콜스택이 깨져 보이는 경우는 주로 Stack Buffer Overrun 으로 인한 문제 입니다.
 (다른 문제는 이 글에서 다루지 않습니다.)
 이 경우, 스택에 있던 Return Address가 지워져 있기 때문에 GDB는 콜스택을 표시하지 못합니다.

 하지만 이런 경우라고 해서 너무 낙심할 것은 아닙니다.
 Stack Buffer가 조금 넘친 경우에는 남은 정보를 이용해서 문제를 해결 할 수 있기 때문입니다.

 이때, 실마리를 제공해주는 것은 Register의 ESP 입니다.
 비록 원하던 Return Adress는 지워졌지만 ESP는 값은 정상적인 값을 유지하고 있습니다.
 이제 ESP가 가르키던 메모리 주변을 뒤져서 Return Address와 유사한 값들이 있는지 찾아보면 문제에 대한 힌트를 얻을 수 있습니다.

 일단 Return Address랑 유사한 녀석들은 어떤 녀석이어야 하는지 파악 해야 합니다.
 당연히 Return Address는 실행가능한 Instruction 들이 저장되어 있는 Code Segment를 가르키고 있습니다. GDB에서는 maint info sections .text 명령어를 통해서 Code Segment를 찾아 볼 수 있습니다.

(gdb) maint info sections .text

Exec file:

    `/home/aa/bb.debug.1f25cf3be302bd7308d598c132ac904b', file type elf32-i386.

    0x08051e20->0x0824fc08 at 0x00009e20: .text ALLOC LOAD READONLY CODE HAS_CONTENTS

Core file:

    `/home/aa/core.1214458224.bb.30678', file type elf32-i386.



 이제 Code Segment의 범위도 구했으니 ESP를 기준으로 주변 탐색해서 Return Address와 유사한 녀석들을 찾아 본다면 아마 콜스택과 유사한 모양이 만들어 질 수 있을 겁니다.

 이를 위해서 간단한 User-defined Command를 만들었습니다.

define findsymbols
set $textbegin = $arg0
set $textend = $arg1
set $si = $arg2
set $ei = $arg3
while $si < $ei
set $value = *(int*)$si
if ($textbegin <= $value && $value <= $textend)
printf "[0x%08x] ", $si
info symbol $value
end
set $si = $si + sizeof(void*)
end
end

 가독성이 다소 떨어지긴 하지만 동작은 간단합니다.
 주어진 범위를 탐색하면서 정해진 범위의 값(Code Segment의 범위)이 들어오면..
 해당 값을 info symbol 을 이용해서 출력하는 Command 입니다.



 실제로 사용하면 아래와 같은 결과를 얻을 수 있습니다. (함수 이름은 가명..)

(gdb) findsymbols 0x08051e20 0x0824fc08 $esp-1024 $esp+1024

[..] IoHandler::SendPacket(char const*, unsigned int, bool) + 786 in section .text

[..] IoHandler::UniCast(char const*, unsigned int) + 26 in section .text

[..] Remote::PartyCast(Party*, char const*, unsigned int) + 141 in section .text

[..] Dispatcher::Do(Task*, TaskMsg*) + 795 in section .text

[..] Task::ExtractTaskMsg(TaskMsg*) + 953 in section .text

[..] Task::svc() + 510 in section .text



콜스택(?)을 얻었으니 ESP값과 비교 등을 통해서 어느 지점에서 Crash되었는 지를 파악할 수 있을 것입니다. 아마 있어야 하는 함수 1~2개가 누락되어서 보이는 경우가 대부분 일테고요. 어떤 함수가 버퍼를 넘치게 했는지 찾아내면 됩니다.

좀 더 정확한 원인을 얻어 보기 위해서는 GDB의 x 명령어 등을 이용해서 ESP 주변 메모리를 잘 뒤져보면 답을 찾을 수 있습니다. 하지만 이 정도 까지 얻었다면 소스를 보고 문제의 원인을 먼저 찾고 문제점이 맞는지 검증하는 편이 더 빠를 수 있습니다.

그럼 즐거운 디버깅 되세요 :)


Posted by U_Seung
(사진 찍은 날짜는 사진 우측 위에 표시.)

 아시는 분은 아시겠지만
 저는 온라인 게임 서버를 만들고 있습니다.

#.
 모니터는 세 대를 사용합니다.
 본체는 두 대를 이용하며, 두 컴퓨터는 Input Director로 연결해서 사용합니다.
 (지금은 내부 사정으로 서브컴퓨터를 사용하지 못하고 있습니다만,
  서브 컴퓨터의 용도는 주로 웹서핑이나 모니터링 툴을 사용하는 목적으로 썼습니다. )


#.
 키보드는 원래 기계식을 쓰다가 너무 시끄러운것 같아서 i-rocks를 씁니다.
 근데 요즘 가끔씩 손목이 아파서(원인은 잘 모르겠지만..)
 Microsoft의 Natural Keyboard로 바꿀까 말까 고민하고 있습니다.


#.
 키보드 아래에는 Post-It을 붙이는 장소입니다.
 할일이 생기면 Post-It을 붙이고, 그 위에 적어 둡니다.
 할일을 다 하면 두줄로 긋고, Post-It에 적힌 리스트가 모두 두줄로 그으면 Post-It을 버립니다.


#.
 주로 쓰는 프로그램은 Microsoft Visual Studio 2008 입니다.
 Linux에서 돌아가야하는 Application을 만들지만 Linux에서 개발/디버깅은 불가피한 경우가 아니면 하지 않습니다.

 Visual Studio을 쓸때는 양쪽 화면에 꽉차게 창 크기를 늘려서 씁니다.
 이렇게 쓰면 창 두개를 한 화면에 볼 수 있어서 편리합니다.
 (사진에서는 파일 하나만 열었네요.)

 색상은 검은 바탕을 선호하며, 폰트는 Bit Stream Vera Sans Mono를 씁니다.
 



'잡담 놀이터' 카테고리의 다른 글

World of Warcraft: 리치왕의 분노 설치 화면...  (1) 2010/07/25
2010 지방선거..  (5) 2010/05/28
예비군 훈련(관동 교장)  (3) 2010/04/28
내 책상 (2010)  (6) 2010/01/13
슬픈이야기...  (7) 2009/06/12
AION 계정 털리다.  (8) 2009/05/04
오랜만에 블로깅...  (3) 2009/04/23
Posted by U_Seung


 그림의 오른쪽 아래 동그라미 쳐진 곳을 주목하면 된다.
 저 상자가 늘어난다는 것..

 매일 쓰던 툴에서 발견한 신선함 이랄까;;;


Posted by U_Seung

 일단 회사에 보면 대부분이 U모 Editor를 사용하고 있다.
 훌륭한 프로그램이라고 생각하지만 그냥 안 쓰다보니 설치도 안했다.

 나는 주로 Windows에서도 Vim을 쓰는데..
 다른 사람들에 비해서 여러개의 파일을 다루는 것이 불편하다는 것을 알게 되었다.




 그래서 위와 같이 Vim의 Tabs 기능으로 자주 쓰는 파일을 열어야 생각이 들었다.
 일단 생각하고나니 문제가 간단해졌다.

CD F:\TT\
gvim -p *.xml

 자주 쓰는 파일 목록을 따로 저장해서 열어주는 방식도 있겠지만..
 난 이 정도로 충분했다.

 두 개의 바로가기를 만들었는데
 하나는 *.xml을 읽어 주고, 하는 *.ini를 읽어 준다.

 이제는 다른 사람보다 편해졌다. :)


----
(추가)

Vim 기본설정에서 tabpage 개수는 10개로 제한되어 있다.
이를 늘리려면

set tpm=20


Posted by U_Seung

[root@localhost root]# gcc homework1.c -o homework1.c
[root@localhost root]#
[root@localhost root]# ls
homework1.c
[root@localhost root]# 

[root@localhost root]# 
[root@localhost root]# 



 보기만 해도 가슴이 미어지는 정말 가슴 아픈 이야기.......

 내가 쓰는 방법은..
 Vim으로 파일을 열고, Ctrl-Z 로 suspend 시켜서 컴파일 하는 방법..
 그리고, 작업이 완전히 끝나기 전까지는 Vim을 닫지 않는다.
 이렇게 하면 소스 파일이 다른 요인에 의해서 날라가더라도 Vim 프로세스 메모리에 저장되서 안전하다.

 두번째 주의할 사항은.
 저런 무자비한.. 자비없는 명령을 한번 실행했다면.;
 Bash Command History를 날리고, Bash를 재시작 하는 것..
 더욱 더 끔찍한 일은.. 저런일이 반복 되는 것이기 때문에...


 

'잡담 놀이터' 카테고리의 다른 글

2010 지방선거..  (5) 2010/05/28
예비군 훈련(관동 교장)  (3) 2010/04/28
내 책상 (2010)  (6) 2010/01/13
슬픈이야기...  (7) 2009/06/12
AION 계정 털리다.  (8) 2009/05/04
오랜만에 블로깅...  (3) 2009/04/23
정말 쩌는 포스터...  (6) 2008/09/02
Posted by U_Seung


 Project Euler를 F#으로 푸는 작업은 계속 틈나는 대로 하고 있는데..
 안그래도 구독자가 별로 없는 블로그에 계속 그것만 올리면..
 구독자들에게 짜증을 줄까봐 자제하고 있습니다.ㅋ


 아무튼 Neon군이 리플로 제안한 방식으로 구현해보았습니다.
 일단 기존 방식은 무식하게 세자리 숫자의 곱을 모두 계산 하는 방식이었는데
 새로운 방식은 세자리 숫자의 곱 중에서 큰 수 순서대로 숫자를 뽑습니다.
 그리고, (123 * 312) 과 (312 * 123)은 같은 값이기 때문에 한번만 계산 합니다.


set [ (999*999, 999, 999) ]

    |> Seq.unfold (fun pq ->

        let head = pq.MaximumElement

        let product, a, b = head

        let newElements =

            set [ ((a-1)*b, a-1, b); (a*(b-1), a, b-1) ]

                |> Set.filter (fun (_, a, b) -> a <= b)

        Some (product, ((pq.Remove head) + newElements)))

    |> Seq.filter is_parlindrome

    |> Seq.hd

    |> printfn "Problem #4 = %d"



Priority Queue 구현에서 일반적으로 사용되는 Heap를 사용하는 것이 가장 좋아 보이지만...
F#에서 쓰기 쉬운 Set (Binary Tree) 기반으로 구현 하였습니다.




'내 생산물' 카테고리의 다른 글

F#, Project Euler - Problem #4 (2)  (0) 2009/05/22
F#, Project Euler - Problem #12  (0) 2009/05/12
F#, Project Euler - Problem #20  (0) 2009/05/12
F#, Project Euler - Problem #5  (0) 2009/05/11
F#, Project Euler - Problem #4  (2) 2009/05/11
F#, Project Euler - Problem #3  (0) 2009/05/10
F#, Project Euler - Problem #1  (2) 2009/05/10
Posted by U_Seung

Problem #12. What is the value of the first triangle number to have over five hundred divisors?

번역: 500개가 넘는 (양의) 약수를 가진 첫번째 triangle number는 ?

먼저 triangle number의 수열은 아래와 같이 구할 수 있다.

Version1. 정의에 가까운 가장 직관적인 방식..

let triangle_numbers =

    let rec triangle_number =

        function 0 -> 1 | n -> (n + 1 + triangle_number (n-1))

    Seq.init_infinite triangle_number



Version 2. Recursive call을 제거..

let triangle_numbers = Seq.unfold (fun (n, i) -> Some(n, (n+i, i+1))) (1, 2)



Version 3. 최적화.

let triangle_numbers = Seq.init_infinite (fun n -> (n+2)*(n+1) / 2)



triangle number의 수열을 구했으니 답을 구하면..

let factorize n =

    let rec factorize_horse n factor count result =

        if (n <= 1) then

            count::result

        else

            match (n % factor) with

            | 0 -> (factorize_horse (n/factor) factor (count+1) result)

            | _ -> (factorize_horse n (factor+1) 0 (count::result))          

    factorize_horse n 2 0 []

        |> List.filter (fun x -> x<>0)

 

let factor_count n =

    factorize n

        |> List.map (fun x -> x+1 )

        |> List.fold_left (*) 1

 

triangle_numbers

    |> Seq.filter (fun x -> 500 < (factor_count x))

    |> Seq.hd

    |> printfn "Problem #12 = %d"



약수의 개수를 빨리 구하려고, 소인수 분해를 하였다.
약수 개수를 구하기 위해 모든 약수가 무엇인지 다 파악한다면..
얼마나 느릴지는 장담할 수 없음. ㅋ



'내 생산물' 카테고리의 다른 글

F#, Project Euler - Problem #4 (2)  (0) 2009/05/22
F#, Project Euler - Problem #12  (0) 2009/05/12
F#, Project Euler - Problem #20  (0) 2009/05/12
F#, Project Euler - Problem #5  (0) 2009/05/11
F#, Project Euler - Problem #4  (2) 2009/05/11
F#, Project Euler - Problem #3  (0) 2009/05/10
F#, Project Euler - Problem #1  (2) 2009/05/10
Posted by U_Seung

Problem #20. Find the sum of the digits in the number 100!

번역: 100! 값의 모든 자릿수의 합을 구하시오.


 여러가지 방법이 있을 수 있지만.
 가장 직관적인 방법은 계산해서 더하면 된다.


open Microsoft.FSharp.Math

 

(BigInt.Factorial (BigInt 100)).ToString()

    |> Seq.map (fun x -> (int x) - (int '0'))

    |> Seq.sum

    |> printfn "Problem #20 = %d"






'내 생산물' 카테고리의 다른 글

F#, Project Euler - Problem #4 (2)  (0) 2009/05/22
F#, Project Euler - Problem #12  (0) 2009/05/12
F#, Project Euler - Problem #20  (0) 2009/05/12
F#, Project Euler - Problem #5  (0) 2009/05/11
F#, Project Euler - Problem #4  (2) 2009/05/11
F#, Project Euler - Problem #3  (0) 2009/05/10
F#, Project Euler - Problem #1  (2) 2009/05/10
Posted by U_Seung

#Problem 5. What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?

번역: 1부터 20까지 수로 모두 나누어 떨어지는 수 중 가장 작은 수는?


뭐 복잡하게 설명할 것 없이
최소공배수(LCM, Lowest Common Multiple)를 구하는 문제다.
Result = (lcm ...... (lcm (lcm 1 2) 3) 4) ... 20)


let lcm x y =

    let rec gcd x y =

        match y with

        | 0 -> x

        | _ -> (gcd y (x%y))

    x * (y / (gcd x y))

 

{1 .. 20}

    |> Seq.fold lcm 1

    |> printfn "Problem #5 = %d"




조금 어려운 문제로 번호를 넘겨야 할 듯...

'내 생산물' 카테고리의 다른 글

F#, Project Euler - Problem #4 (2)  (0) 2009/05/22
F#, Project Euler - Problem #12  (0) 2009/05/12
F#, Project Euler - Problem #20  (0) 2009/05/12
F#, Project Euler - Problem #5  (0) 2009/05/11
F#, Project Euler - Problem #4  (2) 2009/05/11
F#, Project Euler - Problem #3  (0) 2009/05/10
F#, Project Euler - Problem #1  (2) 2009/05/10
Posted by U_Seung