출처 : http://blog.naver.com/chaewh83/140016180847

 

이걸 내가 쓰는 프로그래밍으로 풀면

 

1. 컴파일러 최적화 옵션에서 '속도 최적화' 대신 '코드 크기 최적화' 설정이 캐쉬 성능을 향상시켜 좀 더 빠른 코드를 얻게 함.

 

-> 네트워크 프로그래밍의 경우, 경우에 따라 덜 최적화된 코드가 필요하므로 volatile 를 써야 함.

 

2. 각 CPU(인텔의 SSE, SSE2 / AMD 3D Now)의 SIMD를 활용하는 함수를 만들것.

-> 서버는 현재로선 인텔 CPU니까.....

 

3. 가능한 나눗셈 연산을 최소화 할것.

예)

-> b = a / m;

    c = d / m;

이 있으면

 

-> m = 1/m;

    b = a * m;

    c = d * m;

... 쉬프트가 여러우면 곱셈으로 해버림...

 

4. switch문을 쓸때 연속된 수치를 사용할것, 그러면 VC가 테이블 형태의 분기를 만들어줌.

-> 즉 가능하면 enum {} 으로 쓰는게 좋다는 이야기임.

 

예) case 0:
     case 1:

     case 2: ... (역순으로도 상관없음)

 

잘못) case 2:

        case 4:

        case 3:

 

5. 펜티엄 pro 이상에서는 CMOVxx/FCMOVxx 같은 조건적 이동 명령이 가능.

간단한 if문보다는 ? 를 사용할것.

 

->A == 0 ? choice1 : choice 2;

 

다만 디버깅할때 어느쪽 분기로 떨어지는지는 추적하기 힘드므로

#if _DEBUG

 if()...

#else

 ?...

#endif

를 쓰는것도 나쁘지 않을듯.

 

6. 자주 사용하는 자료 구조는 32bit 배수로 정렬시켜서 사용할것,

컴퓨터의 캐쉬라인을 최적으로 쓸 수 있기때문에 성능이 크게 향상됨. 팬티엄4는 L1캐쉬가 64바이트고 L2가 128바이트

이런걸 감안해서 쓰는 기법을 padding 이라 함.

 

7. sin, cos, tan, exp, arcsin등 수학 함수는 가급적 쓰지말고,

각 수치 데이터를 테이블로 만들어서 간략한 함수로 만들어 쓸것

 

-> psp나 3ds때도 이렇게 했는데...

 

8. 부동소수점은 가급적 double보다 float를 사용할것.

double 의 나눗셈은 39사이클이 걸리지만, float는 19사이클임. (단 2의 제곱수로 나누면 8사이클정도만 걸림)

그리고 float형일때 반드시 뒤에 f를 붙일것.

float a = 1.0; 보다는

float a = 1.0f; 이쪽이 더 빠름

 

9. 순서에 상관이 없다면 후연산자 보다는 선연산자를 사용할것.

a++; 보다는 ++a; 를 쓸것.

 

->출처쪽에선 이유가 안나와 있지만, 이걸 어셈 코드상에서 보면

a++; => a = a + 1; 개념이고, ++a; => a+1; 개념임.

 

10. 가능한 const를 사용할것. 컴파일러가 좀더 최적화를 잘 해줄 가능성이 높아짐.

 

11. 메모리 관리 함수는 따로 사용하는것이 좋음. malloc 과 free는 느리기 때문에 가능한 메모리풀을 만들어사용할것.

 

'C/C++언어' 카테고리의 다른 글

간단한 텍스트 뒤집기, 메모리 복사 함수  (0) 2012.10.19
[ VC11-C++11 ] range base for - 1  (0) 2012.09.24
코드 최적화 팁  (0) 2012.09.10
CAtlMap 사용법 정리  (0) 2012.08.25
MSXML 파싱  (0) 2012.07.03
프로그램 시간 측정  (0) 2012.03.21

[ 선 언 ]

#include <atlcoll.h>

// Key 값이 문자형 일 경우

CAtlMap<CString, CImageData*, CStringElementTraits<CString>> m_tImage;

// 위의 조건을 제외한 선언

CAtlMap<int, CImageData*> m_tImage;

[ 등록 ]

m_tImage.SetAt( Key , Value );

[ 삭제 ]

m_tImage.RemoveKey( Key );

m_tImage.RemoveAll();

[ 검색 ]

m_tImage.LookUp( Key, Value ); // Key 값을 넣으면, Value 를 준다. 리턴값은 bool

CAtlMap<Key, Value>::CPair* pPair = m_tImage.LookUp( Key );

[ 시작 위치 ]

POSITION pos = m_tImage.GetStartPosition(); // iterator 라고 생각하면 된다.

[ 다음 위치 ]

m_tImage.GetNext(POSITON); // 리턴값 : CPair*

m_tImage.GetNextValue(POSITON); // 리턴값 : Value

[ 검색 응용 ]

POSITION pos = m_tImage.GetStartPosition();

CAtlMap<Key, Value>::CPair* pPair = NULL;
while (pos)
{
pPair = m_tImage.GetNext(pos);
}

POSITION pos = m_tImage.GetStartPosition();
while (pos)
{
CImageData* data = m_tImage.GetNextValue(pos);
}

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

나머지 다른 기능들도 있지만, 위의 내용만 알아도 충분히 알수 있는 내용들이라서 정리하지 않겠다.

[출처] CAtlMap 사용법 정리|작성자 스쿠프

 

 

지금, 서버 엔진쪽을 보고 있는데,  map 구조를 hash_map 으로 바꿔보고 다음 위의 CAtlMap으로도 적용시켜봐서

성능 테스트를 해봐야 할꺼 같다.

'C/C++언어' 카테고리의 다른 글

[ VC11-C++11 ] range base for - 1  (0) 2012.09.24
코드 최적화 팁  (0) 2012.09.10
CAtlMap 사용법 정리  (0) 2012.08.25
MSXML 파싱  (0) 2012.07.03
프로그램 시간 측정  (0) 2012.03.21
버츄얼과 오버라이드 차이 Virtual? Override?  (0) 2012.03.06
쉽게 말해 코드상 디버그를 좀더 편하게 해주는 컴파일러 매크로임
그중 제일 잘 쓰는건 __FILE__ (현재 파일 이름), __FUNCTION__ (현재 함수 이름), __LINE__ (현재 실행 라인)
정도.
이하 msdn 을 긁어왔다.
http://msdn.microsoft.com/ko-kr/library/b0084kay(v=VS.90)

Names the predefined ANSI C and Microsoft C++ implementation macros.

The compiler recognizes predefined ANSI C macros and the Microsoft C++ implementation provides several more. These macros take no arguments and cannot be redefined. Some of the predefined macros listed below are defined with multiple values. See the following tables for more information.

ANSI-Compliant Predefined Macros

Macro

Description

__DATE__

The compilation date of the current source file. The date is a string literal of the form Mmm dd yyyy. The month name Mmm is the same as for dates generated by the library function asctime declared in TIME.H.

__FILE__

The name of the current source file. __FILE__ expands to a string surrounded by double quotation marks. To ensure that the full path to the file is displayed, use /FC (Full Path of Source Code File in Diagnostics).

You can create your own wide string version of __FILE__ as follows:

#include <stdio.h>
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)
wchar_t *pwsz = __WFILE__;

int main() {}

__LINE__

The line number in the current source file. The line number is a decimal integer constant. It can be altered with a #line directive.

__STDC__

Indicates full conformance with the ANSI C standard. Defined as the integer constant 1 only if the /Za compiler option is given and you are not compiling C++ code; otherwise is undefined.

__TIME__

The most recent compilation time of the current source file. The time is a string literal of the form hh:mm:ss.

__TIMESTAMP__

The date and time of the last modification of the current source file, expressed as a string literal in the form Ddd Mmm Date hh:mm:ss yyyy, where Ddd is the abbreviated day of the week and Date is an integer from 1 to 31.

밑의 인터넷에서 가져온 소스를 테스트 해봤지만, 몇몇 컴파일러에선 args... 이후 뭐냐고 에러를 뱉기도 합니다.
그럴경우엔

#define DEBUG_ON       (TRUE)

#if DEBUG_ON
   // 일반 printf처럼
  #define debugMes(fmt, ...) printf(fmt, __VA_ARGS__)
   // 이 메시지가 나올땐, 소스 파일의 이름, 함수, 라인수를 같이 출력
  #define debugInfoMes(fmt, ...) printf( "[%s %s %d]" fmt, __FILE__, __FUNCTION__,__LINE__, __VA_ARGS__ )
#else
  #define debugMes(fmt, ...)
  #define debugInfoMes(fmt, ...)
#endif

식으로 매크로를 써주면 왠만한곳은 다 먹힙니다.


이하 긇어온곳 원본
/* -------------------------------------------------------
Printf를 이용한 debug
-------------------------------------------------------
2005.12.08 hugman@postech.ac.kr
원본출처 : http://cafe.naver.com/drv.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=25

다음과 같은 좋은 debug 방법이 있습니다.
프로그램은 매우 간단하므로 한번 살펴보시면 쉽게 파악
하실 수 있습니다.
팁이 있다면,
      1) 프로그램을 다 완성하고, 이 debug를 아예 없애고 싶다면
         공통 해더파일에
          #define NDEBUG
          라고 해주면, 컴파일시 해당부분이 없어지게 됩니다.
      2) 컴파일 옵션으로 지울수도..
            컴파일 옵션에 -DNDEBUG 라고 추가합니다.
            예를 들어
            CFLAGS += -Wall -O2 -g
            라고 되어 있는 부분을
            CFLAGS += -Wall -O2 -g -DNDEBUG
            이렇게 말이죠.

  ++ 추가할점
  VC++ 에서도 잘 작동하는지는 확인해봐야 합니다.
-------------------------------------------------------
*/

#include "iostream"
//#define NDEBUG
//printf( "%s %s %d ", __FILE__, __FUNCTION__, __LINE__ );
// --> source 파일 이름, function 이름, line 번호를 출력해줍니다.

#ifndef NDEBUG
  #define dp(fmt,args...) printf( fmt, ## args )
  #define dlp(fmt,args...) printf( "[%s %s %d]" fmt, __FILE__, __FUNCTION__,__LINE__, ## args )
#else
  #define dp(fmt,args...)
  #define dlp(fmt,args...)
#endif

int func2()
{
  dlp(" ");
}
int main()
{
  dlp(" ");
  func2();
  func2();
}

+ Recent posts