글 검색 결과
- 2012/03/30 [ICON] Icon Generator
- 2012/03/15 rdiff-backup 사용하기
- 2012/01/19 [Python] ExecuteCmd 커맨드 명령어 실행하기
- 2012/01/10 [MS-SQL] DB Schema 모두 제거하기 (2)
- 2011/10/29 MRTG 윈도우 서버에 설치하기 (3)
- 2011/10/28 MRTG Config
- 2011/09/06 MS-SQL Profiler를 대체하는 오픈소스 프로그램
- 2011/09/06 자동 증가 키 RESET(RESEED)
- 2011/08/03 MMORPG에서 좁은 지역에 유저 N명이 모여 있을 때 처리 방법
- 2011/07/28 std::for_each와 Concurrency::parallel_for_each의 속도 비교
- 2011/07/14 Proactor 패턴 개관
- 2011/06/30 추상 팩토리(AbstractFactory) 패턴
- 2011/06/29 TTerminal 2.0(윈도우 원격 터미널 지원 프로그램)을 배포합니다. (2)
- 2011/06/14 JIRA 이슈 트래커 설치하기
- 2011/06/11 Boost Graph Library(BGL)를 이용한 Dijkstra's shortest path (6)
rdiff-backup 사용하기
형상 관리 소프트웨어를 사용하면 파일에 대한 History를 유지할 수 있어서
특정 시점으로 복원하는 것이 가능합니다.
이와는 다른 목적으로 단순하게 폴더를 주기적으로 백업하여
특정 시점으로 되돌려 주는 기능이 필요할 경우에는
형상 관리 소프트웨어를 도입하는데 다소 부담이 됩니다.
단순 폴더 백업 용도라면 rdiff-backup를 사용하시면 많은 도움이 됩니다.
(한글 폴더 및 한글 파일 이름은 가급적 피하는 것이 좋습니다.)
1.2.8 안정화된 버전을 받습니다. (rdiff-backup-1.2.8-win32.zip)
2. rdiff-backup.exe 사용법
rdiff-backup [OPTIONS] (원본 경로) (백업 경로)
3. PATH에 rdiff-backup 폴더 경로를 추가하거나, %systemroot%에 복사합니다.
4. wscript를 이용하여 cmd 창 보이지 않고 실행하기 (rdiff-backup.vbs)
Set WshShell = WScript.CreateObject("WScript.Shell")
wshShell.run "rdiff-backup.exe d:\source D:\backup", 0, True
wshShell.run "rdiff-bakcup.exe --remove-older-than 6M D:\backup", 0, True
Set WshShell = nothing
(--remove-older-than 6M : 6개월전 백업 삭제하기)
5. rdiff-backup 옵션 설명
- 백업하기
rdiff-backup [OPTIONS] (원본 경로) (백업 경로)
- 복원하기
rdiff-backup -r [복원 시간 옵션] (백업 경로) (복원 경로)
[복원 시간 옵션]
- now : 지금
- 1D : 1일전
- 1W : 1주일전
- 1M : 1달전
- 1Y : 1년전
- 백업된 리스트 보기
rdiff-backup --list-increments (백업 경로)
- 백업된 용량 보기
rdiff-backup --list-increment-sizes (백업 경로)
- 변경된 리스트 보기
rdiff-backup --list-changed-since [복원 시간 옵션] (백업 경로)
- 백업 삭제하기
rdiff-backup --remove-older-than [삭제 옵션] --force (백업 경로)
[삭제 옵션]
- 1B : 1회 백업까지 남기고 삭제
- 1D : 1일전 ...(나머지는 복원 시간 옵션과 동일)
- .svn .git 폴더 제외
rdiff-backup --exclude **/.svn --exclude **/.git (원본 경로) (백업 경로)
- .txt 확장자 제외
rdiff-backup --exclude **.txt (원본 경로) (백업 경로)
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
[Python] ExecuteCmd 커맨드 명령어 실행하기
Python에서 Command 명령어 실행하는 예제
import os
import subprocess
def ExecuteCmd(self, strCmd):
print "[ExecuteCmd] %s" % (strCmd)
pipe = subprocess.Popen(strCmd,
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
pipe.stdin.close()
retOutputList = []
while( pipe.poll() is None ):
out = pipe.stdout.readline()
if( out != '' ):
print out
retOutputList.append(out)
retCode = pipe.poll()
return (retCode, retOutputList)
def main():
(retCode, stdout) = ExecuteCmd('svn --version')
print 'retCode : ' + str(retCode)
print stdout
if __name__ == "__main__":
try:
main()
except os.error, err:
print str(err)
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
[MS-SQL] DB Schema 모두 제거하기
DB에서 Table, Procedure, View를 모두 삭제하는 Query 입니다.
맨 윗줄의 Use [DBName]을 수정하시고 사용하세요.
USE [DBName]
GO
DECLARE @SysObjectCount INT
SELECT @SysObjectCount = COUNT('') FROM SYSOBJECTS WITH(NOLOCK)
-- Drop Views
BEGIN
DECLARE @IndexForView INT
SET @IndexForView = 0
WHILE ( @IndexForView < @SysObjectCount )
BEGIN
DECLARE @VIEW_NAME VARCHAR(MAX)
DECLARE VIEW_LIST CURSOR FOR
SELECT NAME FROM SYSOBJECTS O2 WHERE XTYPE='V'
OPEN VIEW_LIST
FETCH NEXT FROM VIEW_LIST INTO @VIEW_NAME
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'DROPPING VIEW '+@VIEW_NAME
EXEC ('DROP VIEW '+@VIEW_NAME)
FETCH NEXT FROM VIEW_LIST INTO @VIEW_NAME
END
CLOSE VIEW_LIST
DEALLOCATE VIEW_LIST
SET @IndexForView = @IndexForView + 1
END
END
-- Drop Procedures
BEGIN
DECLARE @IndexForProcedure INT
SET @IndexForProcedure = 0
WHILE ( @IndexForProcedure < @SysObjectCount )
BEGIN
DECLARE @PROCEDURE_NAME VARCHAR(MAX)
DECLARE PROCEDURE_LIST CURSOR FOR
SELECT NAME FROM SYSOBJECTS O2 WHERE XTYPE='P'
OPEN PROCEDURE_LIST
FETCH NEXT FROM PROCEDURE_LIST INTO @PROCEDURE_NAME
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'DROPPING PROCEDURE '+@PROCEDURE_NAME
EXEC ('DROP PROCEDURE '+@PROCEDURE_NAME)
FETCH NEXT FROM PROCEDURE_LIST INTO @PROCEDURE_NAME
END
CLOSE PROCEDURE_LIST
DEALLOCATE PROCEDURE_LIST
SET @IndexForProcedure = @IndexForProcedure + 1
END
END
-- Drop Tables
BEGIN
DECLARE @IndexForTable INT
SET @IndexForTable = 0
WHILE ( @IndexForTable < @SysObjectCount )
BEGIN
DECLARE @TABLE_NAME VARCHAR(MAX)
DECLARE TABLE_LIST CURSOR FOR
SELECT NAME FROM SYSOBJECTS O2 WHERE XTYPE='U' AND
NOT EXISTS (
SELECT * FROM SYSFOREIGNKEYS K
JOIN SYSCOLUMNS C1 ON (K.FKEYID = C1.ID AND C1.COLID=K.FKEY)
JOIN SYSCOLUMNS C2 ON (K.RKEYID = C2.ID AND C2.COLID=K.RKEY)
WHERE C2.ID = O2.ID AND C1.ID <> O2.ID
)
OPEN TABLE_LIST
FETCH NEXT FROM TABLE_LIST INTO @TABLE_NAME
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'DROPPING TABLE '+@TABLE_NAME
EXEC ('DROP TABLE '+@TABLE_NAME)
FETCH NEXT FROM TABLE_LIST INTO @TABLE_NAME
END
CLOSE TABLE_LIST
DEALLOCATE TABLE_LIST
SET @IndexForTable = @IndexForTable + 1
END
END
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
-
- hanstar17 @ 2012/01/10 11:02
-

- 오랜만에 보는 업뎃~!^^
add
- 댓글 남기기
MRTG 윈도우 서버에 설치하기
1. MRTG 홈페이지에서 윈도우용 zip 파일 다운로드
4. 제어판->모든 제어판 항목->프로그램 및 기능->윈도우즈 기능 사용/사용안함->기능->기능추가2. ActivePerl 윈도우용 다운로드 및 설치
3. perl 스크립트로 mrtg 실행 확인하기
5. SNMP 서비스 속성 설정
6. SNMP Information 설치
7. IIS 설치
IIS를 추가하고, mrtg 웹 사이트 추가
8. snmp.exe 방화벽에 추가
%SystemRoot%\System32\snmp.exe
위 프로그램을 방화벽에 추가한다.
9. perl 명령어 실행
perl cfgmaker public@192.168.0.3 --global "WorkDir: C:\Inetpub\wwwroot\mrtg" --global "RunAsDaemon: yes" --global "Language: korean" --global "Refresh: 300" --global "WithPeak[_]: dwmy --output mrtg.cfg
perl mrtg mrtg.cfg
perl indexmaker --output=C:\Inetpub\wwwroot\mrtg\index.htm mrtg.cfg --title="Server2008R2 MRTG"
10. 5분마다 다시 실행
mrtg.cfg 파일 맨 마지막 부분에 "RunAsDeamon: yes" 추가 후 저장
WorkDir: C:\Inetpub\wwwroot\mrtg
Language: korean # 한국어 언어 설정
"perl mrtg mrtg.cfg" 실행시 5분마다 mrtg 실행
(단, cmd 창을 닫으면 재실행 안됨)
start /DD:\Util\mrtg\bin wperl mrtg --logging=eventlog mrtg.cfg
11. 서비스로 등록하기
서비스 프로그램으로 등록하려면, 어플리캐이션에서 service 이벤트(start, stop, pause...)를 처리할 수 있는 핸들러가 등록되어 있어야 한다.
서비스 핸들러가 없는 프로그램을 서비스로 등록하기 위해서 Windows Server 2003 Resource Kit Tools을 사용해야 한다.
srvany.exe와 instsrv.exe를 mrtg가 설치된 폴더에 복사한다.
다음의 CMD 명령을 실행한다.
D:\Util\mrtg\bin\instsrv.exe MRTG D:\Util\mrtg\bin\srvany.exe
다음과 같이 레지스트리 파일을 만들고 실행한다.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MRTG\Parameters]
"Application"="C:\\Perl64\\bin\\wperl.exe"
"AppParameters"="D:\\Util\\mrtg\\bin\\mrtg.exe --logging=eventlog D:\\Util\\mrtg\\bin\\mrtg.cfg"
"AppDirectory"="D:\\Util\\mrtg\\bin\\"
12. SNMP 정보 수집을 위한 GetIf 프로그램
6에서 설치한 SNMP-Information의 설치된 위치에서 SMIv1폴더의 MIB파일을
GetIf의 mbis폴더에 복사하여 사용한다.
(사용방법은 다른 웹사이트 참조)
13. SNMP로 Traffic, CPU, RAM, HARD Disk 사용량 측정
14. 결과
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
-
- TTF @ 2011/11/01 02:40
-

-
codeproject에서 DLL을 만들어 SNMP에 추가하는 방법 소개
http://www.codeproject.com/KB/IP/SNMP_Agent_DLL__Part1_.aspx
http://www.codeproject.com/KB/IP/SNMP_Agent_DLL__Part2_.aspx
-
- TTF @ 2011/11/02 02:51
-

-
WMI를 이용한 MRTG - ProcessorLoad 예제
http://isnull.kr/post1022.html
-
- TTF @ 2012/04/24 21:46
-

-
간단하게 사용할 수 있는 STG
http://www.leonidvm.chat.ru
add
- 댓글 남기기
MRTG Config
MRTG 윈도우 서버에 설치하기 : http://www.npteam.net/868
#cpu used percent Target[CPU]: .1.3.6.1.4.1.9600.1.1.5.1.5.6.95.84.111.116.97.108&.1.3.6.1.4.1.9600.1.1.5.1.5.6.95.84.111.116.97.108:public@192.168.0.3 Title[CPU]: CPU used PageTop[CPU]:CPU used %
MaxBytes[CPU]: 100 ShortLegend[CPU]: % YSize[CPU]: 100 YLegend[CPU]: CPU used Legend1[CPU]: CPU used Legend2[CPU]: Legend3[CPU]: Legend4[CPU]: LegendI[CPU]: CPU used LegendO[CPU]: Options[CPU]: growright,gauge Unscaled[CPU]: ymwd #memory available bytes Target[Memory]: (.1.3.6.1.4.1.9600.1.1.2.2.0&.1.3.6.1.4.1.9600.1.1.2.19.0:public@192.168.0.3 * 1024 ) Title[Memory]: Memory Available Bytes PageTop[Memory]:Memory Available Bytes
MaxBytes[Memory]: 8589934592 ShortLegend[Memory]: B kilo[Memory]: 1024 YSize[Memory]: 100 YLegend[Memory]: memory Legend1[Memory]: memory Available Legend2[Memory]: memory Used Legend3[Memory]: Legend4[Memory]: LegendI[Memory]: Available Memory LegendO[Memory]: Used Memory Options[Memory]: growright,gauge,nopercent Unscaled[Memory]: ymwd # HDD.C Avalable Percent Target[HDD.C]: .1.3.6.1.4.1.9600.1.1.1.1.5.2.67.58&.1.3.6.1.4.1.9600.1.1.1.1.5.2.67.58:public@192.168.0.3 Title[HDD.C]: DISK Avalable Percent PageTop[HDD.C]:HDD.C Avalable Percent
MaxBytes[HDD.C]: 100 ShortLegend[HDD.C]: % YLegend[HDD.C]: Disk Avalable Percent Legend1[HDD.C]: Current DISK Available percentage LegendI[HDD.C]: Available(Not used) LegendO[HDD.C]: Options[HDD.C]: growright,nopercent,gauge Unscaled[HDD.C]: ymwd # HDD.D Avalable Percent Target[HDD.D]: .1.3.6.1.4.1.9600.1.1.1.1.5.2.68.58&.1.3.6.1.4.1.9600.1.1.1.1.5.2.68.58:public@192.168.0.3 Title[HDD.D]: DISK Avalable Percent PageTop[HDD.D]:HDD.D Avalable Percent
MaxBytes[HDD.D]: 100 ShortLegend[HDD.D]: % YLegend[HDD.D]: Disk Avalable Percent Legend1[HDD.D]: Current DISK Available percentage LegendI[HDD.D]: Available(Not used) LegendO[HDD.D]: Options[HDD.D]: growright,nopercent,gauge Unscaled[HDD.D]: ymwd # HDD.E Avalable Percent Target[HDD.E]: .1.3.6.1.4.1.9600.1.1.1.1.5.2.69.58&.1.3.6.1.4.1.9600.1.1.1.1.5.2.69.58:public@192.168.0.3 Title[HDD.E]: DISK Avalable Percent PageTop[HDD.E]:HDD.E Avalable Percent
MaxBytes[HDD.E]: 100 ShortLegend[HDD.E]: % YLegend[HDD.E]: Disk Avalable Percent Legend1[HDD.E]: Current DISK Available percentage LegendI[HDD.E]: Available(Not used) LegendO[HDD.E]: Options[HDD.E]: growright,nopercent,gauge Unscaled[HDD.E]: ymwd ### Interface 11 >> Descr: 'Realtek-PCIe-GBE-Family-Controller' | Name: 'ethernet_5' | Ip: '192.168.0.3' | Eth: '' ### Target[192.168.0.3_11]: 11:public@192.168.0.3: SetEnv[192.168.0.3_11]: MRTG_INT_IP="192.168.0.3" MRTG_INT_DESCR="Realtek-PCIe-GBE-Family-Controller" MaxBytes[192.168.0.3_11]: 12500000 Title[192.168.0.3_11]: Traffic Analysis for 11 -- Server2008R2 Options[192.168.0.3_11]: growright PageTop[192.168.0.3_11]:Traffic Analysis for 11 -- Server2008R2
System: Server2008R2 in SERVER2008R2 Maintainer: 00-000-0000 Description: Realtek-PCIe-GBE-Family-Controller ifType: ethernetCsmacd (6) ifName: ethernet_5 Max Speed: 12.5 MBytes/s Ip: 192.168.0.3 (Server2008R2)
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
MS-SQL Profiler를 대체하는 오픈소스 프로그램
MS-SQL에서도 빈번하게 사용하는 기능중에 하나는 바로 Profiler 입니다.
그렇지만 MS-SQL Profiler를 사용하기 위해서는 MS-SQL 2008 Developer 버전을
설치해야 하는 압박(?)을 받습니다.
오픈소스 프로젝트 중에 MS-SQL Profiler를 대체할 간단한 프로그램을 소개합니다.
아주 단순하게 Profiler의 기능을 사용할 수 있으며, 편의성은 아무래도 떨어지는 편입니다.
하지만 오픈소스라는 장점이 있고 설치 압박(?)에서 벗어날 수 있으므로 간단히 사용하기엔 좋은 프로그램입니다.
이제 Run을 실행하면 Profiler가 시작됩니다.
이제 무거운 MS-SQL Profiler를 설치하지 않아도 간단히 Profiler를 실행할 수 있게 되었습니다.
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
자동 증가 키 RESET(RESEED)
truncate table을 할 경우에는 자동 증가 키가 리셋 된다.
자동 증가 키 제약을 풀고 INSERT 하는 방법
delete를 할 경우에는 자동 증가 키가 리셋 되지 않는다.
자동 증가 키 RESET 하는 방법
DBCC CHECKIDENT( [Table Name], RESEED, 0 )
SET IDENTITY_INSERT test ON INSERT [Table Name] (ID, Context) values( 0, 'Context' ) SET IDENTITY_INSERT test OFF
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
MMORPG에서 좁은 지역에 유저 N명이 모여 있을 때 처리 방법
MMORPG에서 좁은 지역에 유저가 N명이
모여 있을 때 처리 방법
(출처 : http:://www.npteam.net/855)
1. 기획적 의도로 해결하는 방법
- 국지전이 일어나는 장소를 여러 곳으로 분할한다.
- 국지전에 참여할 수 있는 최대 인원수를 제한한다.
2. 프로그램적으로 해결하는 방법
- 영향을
미치는 요소들
- 데이터 크기
- 데이터를 보내는 빈도 수
- 전송 특성
- 1:1 패킷 보내기
- 1:N 패킷 보내기
- N:M 패킷 보내기
- 해결방법
- 데이터 크기
- 패킷 데이터의 크기를
최대한 줄인다.
- 패킷에 포함된 기본
정보 단위를 최소화 한다.
( 자료형 단위를 줄이는 방법, 불필요한 정보를 제거하는 방법 ) - 패킷 데이터를 압축한다.
- 패킷 데이터를 압축/해제시 CPU 자원을 사용한다.
- 브로드캐스팅할 경우
패킷이 작아지면 트래픽이 줄어드는 잇점이 있다.
- 데이터를 보내는 빈도 수
- 최대 빈도수를 정한다.
- 클라이언트 응답 속도 250ms일 경우 1초에 4번
- 클라이언트 응답 속도 200ms일 경우 1초에 5번
(이동 패킷과 스킬 사용 패킷을 1초에 4-5번으로 해결하기 어렵다.) - 우선순위 큐를 이용한
패킷 전송
- 전투 관련 패킷을 우선적으로
처리한다.
- 비우선 패킷들 : 로그, 채팅, 환경
오브젝트 처리
- 이미 전송한 명령은 Send 버퍼 Queue에서 삭제한다.
- 동일한 좌표로 계속
이동하는 패킷은 클라이언트에서 한번만 보내도 된다.
- 필요 없는 패킷을 제거하여, 트래픽도 줄이고 서버의 CPU 자원 사용도 줄일 수
있다.
- 전송 특성
- 1:1 패킷 보내기
- 문제점 없음
- 1:N 패킷 보내기
- Send 패킷 버퍼 재활용 필요함.
- N:M 패킷 보내기
- 패킷 압축 필요함.
- Send 패킷 버퍼 재활용 필요함.
- 브로드캐스팅을 게임
서버에서 하지 않고, Front 혹은 Agent 서버로
패스하여 처리한다.
(UDP SuperPeer를 사용할 경우 클라이언트에서 브로드 캐스팅하는 것도 고려해 볼 수 있다.)
3. 그외에 더 생각해 볼 사항
- CPU
자원
- 메모리간 데이터 복사를
최소화 한다.
- C++0x의 std::move를 사용하여 데이터 값 복사를 줄인다.
- Reference
Count 기능을
가진 패킷 컨테이너를 사용한다.
- 메모리간 데이터 복사를
빠르게 한다.
- FastMemcpy와 같이 CPU의 기본 레지스터 이외의 MMX와 같은 크기가 큰
레지스터에 데이터를 unrolling 하여,
Loop를 이용한 데이터 복사 속도 저하를 개선한다.
- 네트워크
자원
- 보장이 필요한 패킷과 보장이
필요 없는 패킷으로 구분하여 처리한다.
- 보장이 필요한 패킷 : 주기적인 시간 간격으로 동기화에 필요한 중요한 정보
예) X, Y, Z, 좌표 + Angle - 보장이 필요 없는 패킷 : 주기적인 시간 간격보다 짧은 간격이면서, 손실되어도
문제 없는 정보
예) Angle 정보 - 보장이 필요한 패킷은 TCP로 보내고, 보장이 필요 없는 패킷은 UDP로 나누어 처리할 수 있다.
(단, 중국의 경우 UDP가 불가능한 상황도 발생한다.)
- 브로드
캐스팅을 주체하는 서버를 구분한다.
- Game 서버가 모든 패킷을 브로드캐스팅
하면, Front 혹은 Agent 서버에 N번의 요청을 전달한다.
- 브로드캐스팅이 필요한 패킷을
각 Front 혹은 Agent 서버에 1회만 보내고(받을 클라이언트 목록을 함께), Front 혹은 Agent 서버에서 처리한다면,
Game 서버에서 N번 요청에 대한 CPU 자원 사용을 줄이고, 내부 네트워크 트래픽도 감소한다.
- 유저
상태에 대한 패킷 처리
- 유저가 전투 상태일 경우
패킷을 먼저 처리하고,
비 전투 상태일 경우 나중에 처리하도록 한다.
예) 마을에 모인 유저인 경우, 패킷이 늦게 처리되어도 문제가 발생하지 않는다.
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
std::for_each와 Concurrency::parallel_for_each의 속도 비교
std:for_each와 Concurrency::parallel_for_each 중에 어떤것이 더 빠른 속도를 낼 것인가?
가정 1. CPU Core가 늘어남에 따라 Single Thread보다는 Multi Thread를 활용하여 CPU 자원을 최대한 활용한다.
가정 2. 컨테이너를 읽기 전용으로 접근할 경우 Lock 객체를 사용하지 않아도 된다.
그러나 위 4가지 가정에서 예측한 것과 다른 값이 도출되었다.
가정 1. CPU Core가 늘어남에 따라 Single Thread보다는 Multi Thread를 활용하여 CPU 자원을 최대한 활용한다.
가정 2. 컨테이너를 읽기 전용으로 접근할 경우 Lock 객체를 사용하지 않아도 된다.
(Race Condition, 스레드간 공유 자원 접근 문제)
가정 3. Thread 갯수가 과도하게 늘어나서 빈번하게 Context Switching이 발생할 경우 속도 저하가 발생한다.
가정 3. Thread 갯수가 과도하게 늘어나서 빈번하게 Context Switching이 발생할 경우 속도 저하가 발생한다.
(Concurrency::parallel_for_each는 Thread 갯수를 스스로 조절한다.)
가정 4. 암달의 법칙(Amdahl's law)으로 직렬화된 작업을 병렬화 작업으로 바꾸더라도 속도 향상에는 한계가 있을 것이다.
위 4가지 가정으로 봤을때, 컨테이너를 이터레이팅 할때 많은 도움은 안되더라도 약간의 속도 향상을 기대하였다.
가정 4. 암달의 법칙(Amdahl's law)으로 직렬화된 작업을 병렬화 작업으로 바꾸더라도 속도 향상에는 한계가 있을 것이다.
위 4가지 가정으로 봤을때, 컨테이너를 이터레이팅 할때 많은 도움은 안되더라도 약간의 속도 향상을 기대하였다.
int _tmain(int argc, _TCHAR* argv[])
{
setlocale( LC_ALL, "Korean" );
std::vector< int > vecContainer;
for( int i = 0; i < 10000; ++i )
{
vecContainer.push_back( i );
}
class fntorPrintElem : public std::unary_function< int, void >
{
public:
explicit fntorPrintElem() {};
void operator() ( const int& elem ) const
{
std::wcout << "";
}
};
// std::for_each 속도 체크 코드 생략...
std::for_each( vecContainer.begin(), vecContainer.end(), fntorPrintElem() );
// Concurrency::parallel_for_each 속도 체크 코드 생략...
Concurrency::parallel_for_each( vecContainer.begin(), vecContainer.end(), fntorPrintElem() );
return 0;
}
그러나 위 4가지 가정에서 예측한 것과 다른 값이 도출되었다.
std::for_each 수행 시간 : 0.004950
Concurrency::parallel_for_each 수행시간 : 0.005819
parallel_for_each를 사용하면, std::for_each를 사용했을때 보다 오히려 성능이 떨어진다.
일반적인 상황에서 Concurrency::parallel_for_each를 사용했을 경우 성능 향상을 보장 받을 수 없다.
그렇다면 parallel_for_each가 더 빠르게 하려면 무엇을 해야 할까?
functor에서 Sleep(1)을 넣어서 측정한 결과는 다음과 같다.
Concurrency::parallel_for_each 수행시간 : 0.005819
parallel_for_each를 사용하면, std::for_each를 사용했을때 보다 오히려 성능이 떨어진다.
일반적인 상황에서 Concurrency::parallel_for_each를 사용했을 경우 성능 향상을 보장 받을 수 없다.
그렇다면 parallel_for_each가 더 빠르게 하려면 무엇을 해야 할까?
functor에서 Sleep(1)을 넣어서 측정한 결과는 다음과 같다.
std::for_each 수행 시간 : 10.019599
Concurrency::parallel_for_each 수행시간 : 3.753167
측정 결과 parallel_for_each가 std::for_each보다 상대적으로 약 2.6배 빠르지만,
std::for_each는 2504배 느려지고, parallel_for_each는 750배 느려졌다.
일반적인 컨테이너를 이터레이팅 하는 상황에서 Concurrency::parallel_for_each로 대체하기만 하면,
속도 향상이 있을 것이라는 기대는 깨졌지만,
네트워크 I/O와 같은 비동기 대기가 발생하는 상황에서
코딩 난이도가 높지 않은 parallel_for_each를 활용하면, 속도 향상에 도움이 될 것으로 예측한다.
Concurrency::parallel_for_each 수행시간 : 3.753167
측정 결과 parallel_for_each가 std::for_each보다 상대적으로 약 2.6배 빠르지만,
std::for_each는 2504배 느려지고, parallel_for_each는 750배 느려졌다.
일반적인 컨테이너를 이터레이팅 하는 상황에서 Concurrency::parallel_for_each로 대체하기만 하면,
속도 향상이 있을 것이라는 기대는 깨졌지만,
네트워크 I/O와 같은 비동기 대기가 발생하는 상황에서
코딩 난이도가 높지 않은 parallel_for_each를 활용하면, 속도 향상에 도움이 될 것으로 예측한다.
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
Proactor 패턴 개관
POSA2 책의 Proactor 항목을 요약 정리 하였습니다.
POSA2 원문에 대한 의역 혹은 오역이 있을 수 있습니다.
Xmind 파일을 첨부합니다.
Xmind 프로그램이 없으신 분은 http://www.xmind.net/downloads 에서 다운로드 받으실 수 있습니다.
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
TTerminal 2.0(윈도우 원격 터미널 지원 프로그램)을 배포합니다.
윈도우 원격 터미널을 지원하는 TTerminal 2.0을 배포합니다.
New BSD License이며, 오픈소스로 배포합니다.
위 링크를 통해 배포하며, 1.0 버전과 달라진 점은 다음과 같습니다.
주요 변경 사항
- VS2010 MFC 기반으로 작성.
- 윈도우 도킹 기능 지원.
버그 수정 사항.
- 기존 SDI -> MDI로 변경.
- 기존 버전에서 터미널 화면이 작아지는 문제점 해결.
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
-
- soomong @ 2011/06/29 15:34
-

- 오픈소스!! 멋져요 ^^b
add
- 댓글 남기기
JIRA 이슈 트래커 설치하기
JIRA는 이슈(Issue)를 관리하는 웹 기반 소프트웨어 입니다.
JIRA를 설치하기 위해서 http://www.atlassian.com/software/jira/에서 JIRA를 다운로드 합니다.
처음 설치하실 때에는 다음 버튼을 눌러서 설치하시고,
이미 설치되어 있는 경우에는 다음 단계에서 주의 하셔야 합니다.
설치를 중지하고 데이터 백업이 올바르게 되었는지 다시 한번 확인합니다.
처음 설치하신다면 위 메시지 박스가 나오지 않습니다.
다음과 같이 진행됩니다.
서비스 모드로 설치할 경우에는 Local System 계정으로 실행됩니다.
잘 모르실 경우에는 다음을 누르시면 됩니다.
JIRA 제목을 입력하시고, 발급 받으신 라이센스 키를 입력합니다.
JIRA를 관리하는 관리자 계정 정보를 입력합니다.
이메일 알림을 받을지 설정하는 페이지 입니다.
알림을 받지 않으실 경우 Disable Email Notifications 버튼을 누르고 진행합니다.
이제 모든 설치가 끝났습니다.
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다
add
- 댓글 남기기
Boost Graph Library(BGL)를 이용한 Dijkstra's shortest path
Boost Graph Library(BGL)은 Graph를 처리하는 범용 그래픽 라이브러리 입니다.
그래프(Graph)는 정점(vertex), 선(edge)으로 이루어져 있습니다.
1차원을 구성하는 점과 선이 기본 요소이기 때문에 1차원 이상의 고차원에 존재하는 모든 표현이 가능합니다.
그래프로 할 수 있는 일이 굉장히 많습니다.
- UML 다이어그램
- Node 기반 그래프(퀘스트 연결 관계 등..)
- C++ 헤더 파일 포함 관계 그래프
- 최단거리 길 찾기
- ...
이번에는 BGL을 이용하여 Dijkstra(다익스트라) 최단거리 알고리즘을 활용해 보겠습니다.
위와 같은 그래프를 BGL Dijkstra Shortest Path 알고리즘을 활용하여 처리한 결과는 다음과 같습니다.
#include "ShortestPath.h"
int _tmain(int argc, _TCHAR* argv[])
{
setlocale( LC_ALL, "Korean" );
CShortestPath ShortestPath;
ShortestPath.BuildGraph();
return 0;
}
main 함수에서 하는 일은 없습니다. CShortestPath 클래스가 핵심입니다.BuildGraph()에서 하는 일은 다음과 같습니다.
- Vertex 추가 / 이름 설정
- Edge 추가 / 이름 / 가중치 설정
- boost::dijkstra_shortest_paths()로 최단 거리 구하기
- PrintShortestPath( vStartVertex )에서 시작 vertex를 지정하고 최단거리 Console로 출력하기
- WriteGraphviz()에서 Graphviz.dot 파일로 그래프 파일 출력하기
void CShortestPath::BuildGraph()
{
//////////////////////////////////////////////////////////////////////////
// Vertex 추가하기
const VertexDescriptor vA = boost::add_vertex( m_Graph );
const VertexDescriptor vB = boost::add_vertex( m_Graph );
const VertexDescriptor vC = boost::add_vertex( m_Graph );
const VertexDescriptor vD = boost::add_vertex( m_Graph );
const VertexDescriptor vE = boost::add_vertex( m_Graph );
// Vertex 이름 설정하기
boost::put( boost::vertex_name, m_Graph, vA, "A" );
boost::put( boost::vertex_name, m_Graph, vB, "B" );
boost::put( boost::vertex_name, m_Graph, vC, "C" );
boost::put( boost::vertex_name, m_Graph, vD, "D" );
boost::put( boost::vertex_name, m_Graph, vE, "E" );
//////////////////////////////////////////////////////////////////////////
// Edge 추가하기
const EdgeDescriptor eAC = boost::add_edge( vA, vC, m_Graph ).first;
const EdgeDescriptor eBB = boost::add_edge( vB, vB, m_Graph ).first;
const EdgeDescriptor eBD = boost::add_edge( vB, vD, m_Graph ).first;
const EdgeDescriptor eBE = boost::add_edge( vB, vE, m_Graph ).first;
const EdgeDescriptor eCB = boost::add_edge( vC, vB, m_Graph ).first;
const EdgeDescriptor eCD = boost::add_edge( vC, vD, m_Graph ).first;
const EdgeDescriptor eDE = boost::add_edge( vD, vE, m_Graph ).first;
const EdgeDescriptor eEB = boost::add_edge( vE, vB, m_Graph ).first;
const EdgeDescriptor eEA = boost::add_edge( vE, vA, m_Graph ).first;
// Edge 이름 설정하기
boost::put( boost::edge_name, m_Graph, eAC, "AC" );
boost::put( boost::edge_name, m_Graph, eBB, "BB" );
boost::put( boost::edge_name, m_Graph, eBD, "BD" );
boost::put( boost::edge_name, m_Graph, eBE, "BE" );
boost::put( boost::edge_name, m_Graph, eCB, "CB" );
boost::put( boost::edge_name, m_Graph, eCD, "CD" );
boost::put( boost::edge_name, m_Graph, eDE, "DE" );
boost::put( boost::edge_name, m_Graph, eEB, "EB" );
boost::put( boost::edge_name, m_Graph, eEA, "EA" );
// Edge에 가중치 설정하기
boost::put( boost::edge_weight, m_Graph, eAC, 1 );
boost::put( boost::edge_weight, m_Graph, eBB, 2 );
boost::put( boost::edge_weight, m_Graph, eBD, 1 );
boost::put( boost::edge_weight, m_Graph, eBE, 2 );
boost::put( boost::edge_weight, m_Graph, eCB, 7 );
boost::put( boost::edge_weight, m_Graph, eCD, 3 );
boost::put( boost::edge_weight, m_Graph, eDE, 1 );
boost::put( boost::edge_weight, m_Graph, eEB, 1 );
boost::put( boost::edge_weight, m_Graph, eEA, 1 );
//////////////////////////////////////////////////////////////////////////
// Shortest Path 구하기
// Property Map 가져오기
boost::property_map< Graph, boost::edge_weight_t >::type mapEdgeWeight = boost::get( boost::edge_weight, m_Graph );
boost::property_map< Graph, boost::vertex_index_t >::type mapVertexIndex = boost::get( boost::vertex_index, m_Graph );
boost::property_map< Graph, boost::vertex_distance_t >::type mapVertexDistance = boost::get( boost::vertex_distance, m_Graph );
boost::property_map< Graph, boost::vertex_predecessor_t >::type mapVertexPredecessor = boost::get( boost::vertex_predecessor, m_Graph );
// 다익스트라 최단거리 알고리즘
const VertexDescriptor vStartVertex = vA;
boost::dijkstra_shortest_paths(
m_Graph,
vStartVertex,
boost::weight_map( mapEdgeWeight ).vertex_index_map( mapVertexIndex ).distance_map( mapVertexDistance ).predecessor_map( mapVertexPredecessor )
);
//////////////////////////////////////////////////////////////////////////
// 최단거리 결과 출력
PrintShortestPath( vStartVertex );
// Dot 파일로 출력
WriteGraphviz();
}기존 BGL 책에 소개된 배열 기반의 예제를 탈피해서,
STL을 주로 사용하시는 분들에 맞게 코드를 작성하였습니다.
다른 기능을 추가하고자 하신다면, boost.org의 Graph 라이브러리 페이지를 참조하세요.
- 이 글의 트랙백 주소
- 이 글에는 트랙백을 보낼 수 없습니다

















MRTG_Service.zip




MMORPG에서_좁은_지역에_유저_N명이_모여_있을때_처리_방법.pdf


Proactor.xmind



















