CryptGenRandom는 랜덤 값을 생성하는 함수로 C 라이브러리의 rand와 비슷합니다.

틀린 점은 rand는 랜덤 값이 예측 가능하고 CryptGenRandom는 암호화 기능을 사용하여 예측 할 수 없는 랜덤 값을 생성해 줍니다.
(rand
의 경우 srand을 사용한 후 사용해야 이전과 중복되지 않은 패턴으로 랜덤 값을 생성합니다)

 


CryptGenRandom의 또 하나의 장점은 시드 값의 자료형 크기를 넘지 않는 랜덤 값을 생성합니다.
즉 시드 값의 자료형이 unsigned char라면 CryptGenRandom을 사용한 랜덤 값은 0 ~ 255 사이의 값만 나옵니다.


CryptGenRandom는 기존의 srand+rand의 조합에 비해서 장점이 있지만 단점도 있습니다. 단점은 성능입니다. CryptGenRandom가 암호화 기능을 사용하므로 rand에 비해서 느립니다. Win32 API에서는 어느 정도 차이가 나는지 잘 모르겠지만 똑 같은 기능이 있는 닷넷에서는 rnadCryptGenRandom의 성능 차이는 대략 100배 정도라고 합니다.

 

 

 

참고

Step By Step: Visual C++에서 난수 생성 방법
http://support.microsoft.com/kb/983137/ko

 

[MSDN] CryptoRandom 이야기
http://msdn.microsoft.com/ko-kr/magazine/cc163367.aspx

 

저작자 표시
신고
by 흥배 2010.11.08 09:00

시간 계산 어떻게 하시나요?

여러 가지 방법이 있겠지만 SYSTEMTIME을 사용하여 계산하는 경우라면 COleDateTimeCOleDateTimeSpan을 사용하여 계산하면 쉽게 할 수 있습니다.

COleDateTimeCOleDateTimeSpan ATL에 있는 라이브러리입니다.

 

 

COleDateTimeCOleDateTimeSpan을 사용하기 위한 조건

필요한 파일 : ATLComTime.h

 

 

예제

아래 예제는 지정된 시간에서 을 더한 시간을 계산합니다.

void UpdateTime( SYSTEMTIME& stPatchTime, INT32 wMinute )

{

COleDateTime PatchTime( stPatchTime.wYear, stPatchTime.wMonth, stPatchTime.wDay, stPatchTime.wHour, stPatchTime.wMinute, stPatchTime.wSecond );

 

COleDateTimeSpan SpendTime;

SpendTime.SetDateTimeSpan( 0, 0, wMinute, 0 );

PatchTime += SpendTime;

          

stPatchTime.wYear = PatchTime.GetYear();

stPatchTime.wMonth = PatchTime.GetMonth();

stPatchTime.wDay = PatchTime.GetDay();

stPatchTime.wHour = PatchTime.GetHour();

stPatchTime.wMinute = PatchTime.GetMinute();

}


 

COleDateTime은 생성자에서 SYSTEMTIME을 인자로 사용할 수 있습니다. 그러나 인자로 사용할 SYSTEMTIME의 값이 올바른 값인 경우만 사용할 수 있습니다. 예를 들어 아래와 같은 것을 인자로 넘기면 디버그 모드에서는 경고가 발생합니다.

SYSTEMTIME stTime;

stTime.wYear = 2010;

stTime.wMonth = 10;

stTime.wDay = 11;

 

COleDateTime CurTime( stTime );

// 이후 이것을 계산에 사용할 때 에러발생

 

 

저작자 표시
신고
by 흥배 2010.10.15 09:00

LuaLuaC 언어의 API 훅을 제공하는 애플리케이션이라면 어떤  애플리케이션이라도 짜 넣을 수 있는 스크립트 엔진이다. 최근 LuaJIT 컴파일러의 버전 2가 베타가 되었다. 이것은 트레이스 컴파일러와 어셈블러에서 쓰여진 인터프린터에 근거하여 완전하게 고쳐 쓴 VM이 포함되어 있다.

 

………

 

Lua는 범용 스크립트 언어로 구문은 Modula로부터 빌려 오고 있다. SNOBOL이나 AWK, C++ 그리고 Lisp으로부터도 영향을 받고 있다. Scheme로부터도 큰 영향을 받은 언어이다. 데이터 정의 언어의 구문은 Ierusalimschy씨가 만들었던 SOL(포르투갈어로 '태양')이라고 하는 언어로부터 계승하고 있지만 이 SOLLua에 의해서 바뀌었다. 그 외의 특징으로서는 함수형으로 확장하면 객체 지향 언어로서 사용할 수 있고 프로토 타입 베이스이기도 하며 가베지 콜렉션도 지원하고 있다.

 

LuaCAPI를 가지고 있으므로 여러가지 언어로 쓰여진 애플리케이션에 간단하게 임베디드 할 수 있다. API는 코어 부분의 API와 확장 라이브러리로 나누어져 있다. 바이너리 패키지의 크기는 플랫폼에 따라서 다르지만 200 ~ 700KB정도로 매우 작으며 ANSI 또는 ISO C 컴파일러를 탑재하는 플랫폼이면 어떠한 플랫폼에서도 동작한다. 실제  모든 Unix/LinuxWindows에서 동작할 뿐만 아니라 ARM을 탑재한 휴대 단말이나 Rabbit 마이크로 프로세서/콘트롤러로에서도 동작한다.

 

가장 중요한 특징의 하나로서 들 수 있는 것은 테이블 형태다. 이 데이터형은 유일한 복합형이지만 확장할 수 있다. 테이블은 키와 데이터의 조합의 컬렉션(해시 이종성 연상 배열로도 알려져 있다)으로 키에 의해서 데이터를 참조한다. nil 이외라면 어떤 형태라도 키(인덱스)로서 이용할 수 있다. 수치형의 키 1은 문자열 형의 키 "1"과는 구별된다.

 

Lua에는 클래스라고 하는 개념은 없지만 펑션과 테이블을 사용해 만들 수도 있다.

테이블 안에 펑션과 관련하는 데이터를 배치하는 것으로 오브젝트를 형성할 수 있다. 계승(단일이든 다중이라도)"메타 테이블"을 사용하면 실현될 수 있다. 으브젝트가 자신에게는 존재하지 않는 메소드나 필드를 부모 오브젝트에 있는지  탐색하도록 짜면 된다.

아래는 Lua의 단순한 샘플 코드다.

 
function factorial(n)
  if n == 0 then
    return 1
  else
    return n * factorial(n - 1)
  end
end

 

다른 스크립트 언어와는 다르게 Lua는 직접 해석되는 것이 아니라 바이트 코드에 컴파일 되고 나서 독자적인 레지스터 베이스의 버추얼 머신 상에서 실행된다. 독일의 오픈 소스 개발자인 Michael Pall씨는 Lua JIT 컴파일러를 구현하여 현재 전2.0이 베타 2가 되어 있다. 우선 x86 아키텍처용 JIT를 작성하여고 현재 64비트 아키텍처로의 이식을 시도하고 있다. 작자의 LuaJIT 대한 코멘트는

유연성과 고성능을 겸비하면서 거기에 적합하지 않을 정도로 적은 메모리 밖에 사용하지 않습니다. VM에 사용하는 것이 겨우 120K 정도로 JIT 컴파일러에 필요한 것은 80K정도입니다.…

 

2009년은 오랫동안 기다리고 있었던 LuaJIT 2.0의 최초의 릴리스를 한 해가 되었습니다. 이 버전에서는 VM은 철저하게 성능을 추구하기 위해 완전하게 고쳐 써져 그 결과 어셈블러에서 쓰여진 고속 인터 프린터와 최신 기술을 이용한 JIT 컴파일러가 완성 되었습니다.

 

또 혁신적인 트레이스 컴파일러도 통합되고 있고 선진적인 SSA 베이스의 최적화와 연구 최종 단계 처리에서 고도로 조정된 코드 생성을 실현하고 있습니다. 이것에 의해서 동적 언어에 특징적인 오버헤드가 큰 폭으로 삭감 되었습니다. 그 결과  성능은 종래는 오프 라인의 정적 언어 컴파일러의 성능이라고 생각되고 있는 수준에 가까워지고 있습니다.”

 

Lua는 여러가지 애플리케이션에 짜넣을 수 있지만 한편으로 게임 개발자에게도 받아 들여지고 있다. 고성능에 더하여 한 번 게임을 중단하여 여러가지 파라미터를 만진 뒤 게임을 재개할 경우에 리로드 하기 위한 정지가 거의 없어도 되는 것이 Lua가 받아 들여지고 있는 큰 이유다. World of Warcraft이나 League of Legends, Star War 시리즈나 외의 여러가지 게임에서 개발 시에 Lua를 사용하고 있다. 그 외에도 여러가지 타입의 애플리케이션이 Lua를 이용하거나 Lua를 사용하기 위한 구현이 되고 있다. 예를 들면 Adobe Photoshop Lightroom이나 Apache HTTP Server(mod_lua 모듈), MySQL Proxy, nmap  그리고 밖에도 많이 있다. Lua로 쓰여진 웹 프레임웍도 최저 둘은 존재한다. KeplerOrbit이다.

 

 

출처 : http://www.infoq.com/jp/news/2010/01/LuaJIT-2.0

 

저작자 표시
신고
by 흥배 2010.01.29 09:00

규칙 9

인라인 함수를 사용하여 작성할 수 있는 내용이라면 매개 변수가 있는 매크로를 사용하지 않는.



이유는 다음과 같다.

전 처리기 명령 #define을 이용하는 것은 위험하다. 특히 매개 변수가 있는 매크로에 따른 위험이 크다. 위 그림에 나와있는 문장과 같이 괄호가 광범위 하게 걸치기 때문에 "MAX (i + +, j + +)"와 같은 호출에 의도하지 않게 2배 증가가 실행될 가능성을 배제할 수 없다.


이외에도 부호 있는 데이터와 부호 없는 데이터 비교와 같은 매크로의 잘못된 사용에 대한 위험이 있다. 매크로의 경우 함수와 달리 컴파일러 인수의 데이터 형식 검사가 작동하지 않는다. 또한 "inline" 원래 C + + 언어 키워드 이었지만 "ISO / IEC 9899:1999"에서 C 언어 표준에 추가 되었다.




규칙 10

변수를 선언할 때 ", (쉼표)"를 사용하지 않는다.


변수 y를 포인터 형으로 하고 싶은지 어떤지 알기 어렵다.


이유는 다음과 같다.

변수 선언을 각각 독립적인 문장으로 작성하는 수고는 적다. 대조적으로 컴파일러와 코드 관리 담당자가 위 그림과 같은 기술이 의도하는 내용을 오해 해 버리는 위험이 높다.



출처 : http://eetimes.jp/article/23004

신고
by 흥배 2010.01.14 08:30

규칙 6

정수 비트 길이와 바이트가 문제가 될 때 char 또는 short, int, long, long long 같은 데이터 형식을 사용하지 않고 고정 길이 데이터 형식을 이용한다.



C 언어의 표준으로 규정되어 있는 부호 및 부호 없는 고정 길이 정수는 위와 같다.

이유는 다음과 같다. ISO가 개발한 C 언어 표준 "ISO / IEC 9899"에서는 char 또는 short, int, long, long long 같은 데이터 형식의 길이(비트 길이)에 대한 처리 계에 마다 정의하는 것이 허용되며 이식성 문제를 일으킨다.


1999년에 개정된 "ISO / IEC 9899:1999"에서도 이 문제의 잠재적인 원인은 해결되지 않았지만 표 1에 표시한 비트 길이를 고유하게 정의한 데이터 형식이 추가되었다. 이 새로운 형식은 "stdint.h"라는 헤더 파일에 정의되어있다.

(흥배 : Visual C++을 사용하는 경우 C99 표준이 구현되어 있지 않기 때문의 위의 표에 나타난 데이터 형을 사용할 수 없습니다. 그러나 Windows의 경우 64비트가 나오면서 위 표와 비슷하게 데이터 길이를 표시하는 방법을 사용하기를 권장하고 있습니다. 즉 short는 INT16, int는 INT32 등으로 대신 사용할 수 있습니다. 저는 64비트 프로그래밍을 시작한 작년부터 short, int 등을 사용하지 않고 INT16, INT32를 사용하고 있습니다. )




규칙 7

"& (AND )", "|( OR )", "~( 비트 반전 )", "^( XOR )", "<<( 왼쪽 시프트 )", ">>( 오른쪽 이동) " 같은 비트 연산자를 부호 있는 정수 값에 적용하지 않는다.



이유는 C 언어 표준이 예를 들면 "2의 보수를 사용"과 같이 부호 있는 정수 데이터의 표현 방식을 규정하고 있지 않기 때문이다. 부호 있는 정수 값에 비트 연산을 실시한 결과는 처리 계에 의존하고 있는 실정이다.




규칙 8

부호 있는 정수와 부호 없는 정수를 결합하거나 비교 하지 않는다. 이 원칙을 지키기 위해 부호 없는 10 진수 정수의 끝에는 "u"를 붙인다.



이유는 다음과 같다. 부호 있는 정수 변수에 저장된 이진 데이터 처리에 대한 자세한 내용은 C 언어 표준은 처리 기관에 의존하게 되어 있다. 게다가 부호 있는 정수와 부호 없는 정수를 결합한 결과로 발생하는 버그는 실제로 연산 데이터의 내용에 의존하기 때문에 발견이 어렵다.

(흥배 : 저는 딱히 u를 붙이지는 않지만 저는 언제나 VC++에서 경고 레벨을 ‘4’로 설정합니다. 경고 레벨 4에서는 부호 있는 정수와 부호 없는 정수를 같이 사용하면 바로 경고가 나오기 때문에 문제를 사전에 방지합니다)



출처 : http://eetimes.jp/article/23004


신고
by 흥배 2010.01.11 08:30

규칙 3

함수나 변수를 그것이 정의된 모듈 외부에 공개할 필요가 없는 경우는 static 키워드를 사용하여 선언한다.


이유는 다음과 같다. C 언어의 static 키워드는 여러 가지 의미가 있다. 모듈 수준에서 전역 변수와 함수를 static 키워드를 붙여서 선언하는 경우 다른 모듈의 함수를 사용하여 잘못된 접근으로부터 보호할 수 있다. 이러한 static 키워드 사용은 캡슐화로 연결한다.




규칙 4

다음과 같은 경우는 항상 volatile 수정자를 사용하여 선언한다.


  1. 모든 인터럽트 서비스 루틴에서 사용되는 전역 변수를 선언할 때
    .
  2. 2개 이상의 작업에서 사용되는 전역 변수를 선언할 때.
  3. 메모리 매핑된 I / O 방식을 채택한 주변 장치 레지스터 셋에 접근하기 위한 포인터 변수를 선언할 때. 예 "timer_t volatile const * p_timer"


이유는 다음과 같다. 컴파일러가 병렬로 실행되는 여러 스레드에 의해 변경될 수 있는 변수와 레지스터인 경우에도 읽기 / 쓰기 코드가 불 필요하다고 판단하여 코드 자체를 삭제하도록 최적화 할 수 있다.


예를 들면 다음과 같은 경우이다.

한 스레드 "A"가 특정 조건의 경우 해당 변수의 값을 변경한다고 하자. 다른 스레드 "B"는 변수를 폴링 하고 있으며 값이 변경되었을 때 어떤 처리를 한다. 이 때 스레드 B의 사이에 변수의 값을 변경하는 코드가 작성되어 있지 않으면 컴파일러는 해당 변수의 값은 변경되지 않는 것으로 판단하여 최적화할 수 있다. 그러면 컴파일 된 오브젝트 코드에서는 변수를 폴링 하는 코드가 제거 되어 버리기도 한다.


volatile 수정자를 적절히 사용하면 이러한 컴파일러 최적화 기능이 무효화 되어 코드 전체에 걸친 발견하기 어려운 버그 제거로 연결한다.




규칙 5

주석을 중첩시키지 않는다.


그리고 비록 일시적이라도 주석 블록을 해제하는 용도(주석)로 주석을 사용하지 않는다.

일시적으로 코드 블록을 해제하려면 전처리기 조건부 컴파일 기능을 사용한다.

예 "# if 0 ... # endif"


이유는 중첩 주석을 사용하던가 주석에서 코드 블록을 해제 하거나 하면 컴파일 하여 생성되는 최종적인 실행 모듈에서 무효로 했던 코드가 들어가 버릴 위험이 생긴다.



출처 : http://eetimes.jp/article/23004


신고
by 흥배 2010.01.08 10:30

왜 코딩 규칙이 필요할까?


코딩 규칙은 소프트웨어 개발자가 코드 작성에 대한 규칙을 정리한 것이다.

소프트웨어 개발 업체인 팀과 기업 단위에서 그런 코딩 규칙을 적용하면 많은 이익을 얻을 수 있다.

예를 들어 소프트웨어의 안정성과 이동성을 강화한 최소한의 수고 것만으로 그 소프트웨어를 재사용 할 수 있게 된다. 또 코드 내용을 검토하고 설명하는 데 필요한 시간을 줄일 수 있다.


코딩 규칙을 적용함으로써 얻을 수 있는 이익 중 가장 큰 장점은 버그를 줄일 수 있는 것이다. 소프트웨어 개발 비용을 낮추기 위한 중요한 전략은 컴파일러와 링커, 소스 코드의 정적 분석 도구 등이 자동으로 버그를 제거하도록 코드를 작성하는 것 즉 코드를 실행 전에 버그를 최대한 발생하지 않게 하는 것이다.


소스 코드에 적절한 의견을 써 놓으면 그 코드에 참여하는 모든 소프트웨어 개발자가 소프트웨어를 구성하는 변수와 함수 모듈의 올바른 사용법과 의미를 쉽게 이해할 수 있다.




여러 코딩 규칙


C 언어를 위한 코딩 규칙은 얼마든지 있다. 예를 들면 유럽의 자동차 업계의 MISRA (Motor Industry Software Reliability Association)가 발표한 자동차 소프트웨어 개발에 C 언어를 사용하는 것에 대한 지침 "Guidelines for the Use of the C Language in Critical Systems (MISRA - C : 2004)"가 있다. MISRA – C가 높은 안전성이 요구되는 기기의 설계에 대하여 통찰력이 있으며 이 지침은 C에서 더 안전한 소프트웨어를 작성할 수 있도록 규정 되어있다.


코딩 규칙과 MISRA - C는 공통점이 있지만 차이점도 있다. 코딩 규칙은 주로 작성하는 방법에 중점을 두고 있다. 그것에 비해 MISRA - C는 버그를 발생시키지 않기 위하여 중요한 규칙을 규정 하고 있다.


따라서 필자가 속한 팀은 필요에 직면하여 자신의 코딩 규칙을 개발했다. 이 코딩 규칙은 버그를 만들지 않는 코드를 작성하는 관점에서 완전히 새롭게 만든 것이다.




버그를 만들지 않기 위한 규칙


규칙 1

if 문, else 절, switch 문, while 문, do 문, for 문 다음의 코드 블록을 항상 중괄호 "{}"로 한다.


코드가 1 줄이거나 아무 것도 기술하지 않는다고 해도 중괄호로 한다

이유는 다음과 같다. 예를 들면 if 문장에 적용 조건이 성립했을 때 처리해야 할 내용이 처음에는 "A" 1개의 문장으로 작성할 수 있다 하더라도 변경으로 추가하여 "A"와 "B"의 2개의 문장이 되어버렸다.


이 때 첫 번째 "A"를 중괄호로 묶고 있지 않았다면 "B"를 추가할 때 중괄호를 사용하는 것을 잊어버렸다면 "B"라는 작업이 if 문은 조건 성립 여부에 관계없이 항상 실행되는 것이다. 즉 새로운 버그를 낳은 것으로 이어진다.

이러한 어이없는 버그는 항상 코드 블록을 중괄호로 묶는 방식으로 하면 미연에 방지할 수 있다.




규칙 2

다음과 같은 경우는 항상 const 한정자를 사용하여 선언한다.


  1. 변수 초기화 후에 해당 값을 변경할 수 없다면 그 변수를 선언할 때 const 한정자를 붙인다.
  2. 함수에 값 참조(포인터)를 전달하고(call - by - reference) 그 값을 함수에서 변경할 수 없는 경우 이 함수를 선언할 때 인수에 const 한정자를 붙인다. 예 : "char const * p_data"
  3. 구조체 또는 공용 구조체의 멤버 중 변경할 수 없는 구성원은 const 한정자를 붙인다. 예를 들면 메모리 매핑된 I / O 방식을 채용한 주변 장치 레지스터에 접근하기 위한 구조체 멤버 등이다.
  4. #define에 정의된 숫자 상수의 데이터 형식을 엄격하게 하는 경우 const 한정자를 사용하여 선언한다.


이러한 이유는 컴파일러의 기능을 사용하여 데이터를 읽기 전용으로 하여 의도하지 않은 쓰기로부터 데이터를 보호하기 위해서이다.



출처 : http://eetimes.jp/article/23004

신고
by 흥배 2010.01.06 13:30
하드웨어 관련 사이트에 있던 글이라서 C++이 아닌 C 언어를 사용한 경우입니다.
C++이 C 언어와 비슷한 부분이 많기 때문에 거의 C++에도 다 적용되는 규칙입니다.

저는
규칙 1, 5, 6, 7, 8, 9, 10은 지키고 있습니다.
규칙 2는 아직은 반반 인 것 같습니다. 가능하면 const도 붙입니다.
규칙 3은 C++에서는 별로 필요 없을 것 같습니다.
규칙 4는 Windows에서 동기화 객체를 사용할 때 적용되므로 사용할 경우가 없더군요.

 

규칙 1
if 문, else 절, switch 문, while 문, do 문, for 문 다음의 코드 블록을 항상 중괄호 "{}"로 한다.


규칙 2
다음과 같은 경우는 항상 const 한정자를 사용하여 선언한다


규칙 3
함수나 변수를 그것이 정의된 모듈 외부에 공개할 필요가 없는 경우는 static 키워드를 사용하여 선언한다


규칙 4
다음과 같은 경우는 항상 volatile 수정자를 사용하여 선언한다


규칙 5
주석을 중첩시키지 않는다.



규칙 6
정수 비트 길이와 바이트가 문제가 될 때 char 또는 short, int, long, long long 같은 데이터 형식을 사용하지 않고 고정 길이 데이터 형식을 이용한다


규칙 7
"& (AND )", "|( OR )", "~( 비트 반전 )", "^( XOR )", "<<( 왼쪽 시프트 )", ">>( 오른쪽 이동) " 같은 비트 연산자를 부호 있는 정수 값에 적용하지 않는다

규칙 8
부호 있는 정수와 부호 없는 정수를 결합하거나 비교 하지 않는다. 이 원칙을 지키기 위해 부호 없는 10 진수 정수의 끝에는 "u"를 붙인다


규칙 9
인라인 함수를 사용하여 작성할 수 있는 내용이라면 매개 변수가 있는 매크로를 사용하지 않는다


규칙 10
변수를 선언할 때 ", (쉼표)"를 사용하지 않는다.




각 규칙의 자세한 설명은 다음 글에서 포스팅하겠습니다.

출처 : http://eetimes.jp/article/23004
저작자 표시
신고
by 흥배 2010.01.06 08:30

32비트 OS에서는 구조체는 4바이트 정렬을 하고, 64비트 OS에서는 8바이트 정렬을 합니다.


네트웍 통신으로 구조체의 데이터를 보낼 때는 구조체의 각 멤버를 하나씩 배열에 인코딩 하던가, 또는 progma pack(1)을 사용하여 1바이트 정렬된 구조체를 보냅니다.


VC++ 프로젝트의 설정을 자세히 보지 않아서 그 동안 구조체 정렬은 progma pack(1)만 사용했는데 VC++의 프로젝트 설정에서도 정할 수 있다는 것을 근래에 알았습니다.


다만 VC++ 프로젝트 설정에서 정하면 모든 구조체에 다 적용 되어버리므로 실제 사용할 일은 없을 것 같습니다.



출처 : 네이버 ‘온라인서버제작자모임’의 규야님으로부터

신고
by 흥배 2010.01.04 08:30

근래에 회사에서 만들고 있는 게임의 서버 애플리케이션에 LFH을 적용하면서 관련 자료를 좀 모아 보았습니다.


LFH ( Low fragmentation Heap )

1. 단편화 방지를 위해서 만들어진 것이지만 멀티코어 환경에서 특히 좋다.

2. 코어가 하나 있을 때는 오히려 10% 성능 하락도 있다( 신뢰 여부는 측정 불가 ^^; )

3. CRT에서는 크게 성능 향상을 볼 수 없다.
   (nhn Japan 블로그 글에서 CRT도 LFH를 적용했는지 정확하게 모르겠음
    CRT도 LFH 적용을 위해서는 CRT 힙 핸들을 HeapSetInformation에 적용해야 한다 )

4. LFH가 극상의 성능을 내기 위해서 Private Heap과의 조합이 최상이다.

5. Windows Server 2008/Vista 기본적으로 사용되도록 되어 있음
   : 이 때문에 메모리 측정(Private Bytes)를 할 때 정보가 좀 틀릴 수도 있음

6. LFH는 Windows XP, Windows 2000 Professional with SP4, Windows Server 2003 이상 가능



참고

1. 책
  Windows via C/C++ 672 페이지

2. 웹
http://workspace.office.live.com/?wa=wsignin1.0#jacking75/프로그래밍%20문서/CHB001%20-%20About%20Heap.docx

http://kslive.tistory.com/49

http://www.cyworld.com/jupihistory/2870669

http://blog.naver.com/mmouse77?Redirect=Log&logNo=50014020705

http://blog.naver.com/neuk?Redirect=Log&logNo=150012867627

http://re-thinkthings.spaces.live.com/Blog/cns!1C5AE98DA3645F42!587.entry   (일본어 )

윈도우즈의 LFH와 Hoard의 비교
http://devnote.net/55


NHN Japan 블로그에 있는 글 ( 성능 측정 그래프도 있음 )
http://techlog.nhncorp.jp/index.php/low-fragmentation-heap/#more-21
  (일본어)




사용 방법

1. 프로세스 힙에 LFH 적용
ULONG ulEnableLFH = 2;
HeapSetInformation (
        GetProcessHeap(), 
        HeapCompatibilityInformation, 
        &ulEnableLFH, 
        sizeof(ulEnableLFH));

2. CRT 힙에 LFH 적용
intptr_t hCrtHeap = _get_heap_handle();
ULONG ulEnableLFH = 2;
if (HeapSetInformation((PVOID)hCrtHeap,
                           HeapCompatibilityInformation,
                           &ulEnableLFH, sizeof(ulEnableLFH)))
        puts("Enabling Low Fragmentation Heap succeeded");
    else
        puts("Enabling Low Fragmentation Heap failed");
    return 0;


3. 프로세스의 모든 힙에 적용

HANDLE Heaps[1025];
DWORD Count = GetProcessHeaps( 1024, Heaps );
for( DWORD i = 0; i < Count; ++i )
{
     ULONG  HeapFragValue = 2;

     if( HeapSetInformation( Heaps[i], HeapCompatibilityInformation, &HeapFragValue, sizeof(HeapFragValue) ) )
    {
          .............
    }
    else
    {
         ...................
    }
}


제가 적용한 프로젝트에서는 프로세스에서 생성한 힙이 총 9개이며 세번째는 무조건 실패를 합니다.

이유는 이 힙에는 HEAP_NO_SERIALIZE flag가 설정 되어 있기 때문입니다.

HEAP_NO_SERIALIZE flag는 멀티 스레드에서 그 힙에 동시에 접근하여 할당, 해제를 가능하게 하기 위한 설정입니다.
( 참고   http://support.microsoft.com/kb/929136/ja  )


모든 힙에 적용하므로 따로 CRT 힙에는 LFH를 적용하지 않아도 된다.   

모든 프로세스의 힙에 LFH를 적용 후 따로 CRT 힙에 LFH를 적용하면 실패합니다.

이유는 이미 적용을 했기 때문이다. 저는 9번째가 CRT 힙이었습니다.




Windows Heap과 관련된 볼만한 글입니다.

Analyzing the heap(s) of a Win32 program



 

이 글은 스프링노트에서 작성되었습니다.

신고
by 흥배 2009.05.21 22:00
| 1 |

티스토리 툴바