성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Reordering on an Alpha processor ;...
[정성태] 공유 감사합니다. ^^ 참고로, WPF에서 WindowsF...
[Tom Lee] 답변 감사합니다. 나름의 해결책 연구해보고 여기에도 공유해봅니다...
[정성태] 아래의 글을 보면, MoveWindow 하면 될 듯한데요. ^^...
[Tom Lee] 안녕하세요 올려주신 글 참고하여 WPF 어플리케이션 안에 Uni...
[정성태] A graphical depiction of the steps ...
[정성태] 질문을 주셔서 출판사 측에 문의를 했습니다. 약 한 달 정도 후...
[Thorondor
] @정성태 개인 블로그인데도 거의 커뮤니티 급 인 것 같아요. 요...
[정성태] Roll A Lisp In C - Reading ; https...
[정성태] Java - How to use the Foreign Funct...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>WELL512 난수 발생 알고리즘 - C#</h1> <p> <br /> 랜덤 함수에 대한 재미있는 글이 있어서 소개합니다. ^^ (스타 크래프트등의 게임에서 random seed 값을 일치시켜서 서로 다른 클라이언트들끼리의 동기화를 했다는 아이디어도 재미있습니다. ^^)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 표준 rand() 함수보다 유용한 랜덤 생성 알고리즘 - MT, WELL ; <a target='tab' href='http://www.gamedevforever.com/114'>http://www.gamedevforever.com/114</a> </pre> <br /> 이런 건 널리 퍼뜨려야 한다고 생각하는 차원에서 위에서 소개된 WELL512의 C# 버전도 간단하게 포팅해 보았습니다. (이미 위의 글을 쓰신 분이 C++로 잘 포팅해 주셔서 뭐 별로 할 건 없었습니다. ^^)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public class Well512 { static uint[] state = new uint[16]; static uint index = 0; static Well512() { Random random = new Random((int)DateTime.Now.Ticks); for (int i = 0; i < 16; i++) { state[i] = (uint)random.Next(); } } internal static uint Next(int minValue, int maxValue) { return (uint)((Next() % (maxValue - minValue)) + minValue); } public static uint Next(uint maxValue) { return Next() % maxValue; } public static uint Next() { uint a, b, c, d; a = state[index]; c = state[(index + 13) & 15]; b = a ^ c ^ (a << 16) ^ (c << 15); c = state[(index + 9) & 15]; c ^= (c >> 11); a = state[index] = b ^ c; d = a ^ ((a << 5) & 0xda442d24U); index = (index + 15) & 15; a = state[index]; state[index] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28); return state[index]; } } </pre> <br /> 위에서는 초기 state 배열을 Random으로 초기화 시키고 있지만, 원래는 랜덤값에 대한 일치를 목적으로 사용하는 것이기 때문에 개발자가 임의로 넣어주어야 합니다.<br /> <br /> 아래는 간단하게 Random과 Well512의 난수 비교를 한 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void Main(string[] args) { Random random = new Random((int)DateTime.Now.Ticks); for (int i = 0; i < 10; i++) { int rand1 = random.Next(); ulong rand2 = Well512.Next(); Console.WriteLine(i + ": " + rand1 + ", " + rand2); } Console.WriteLine(); for (int i = 0; i < 10; i++) { int rand1 = random.Next(10); ulong rand2 = Well512.Next(10); Console.WriteLine(i + ": " + rand1 + ", " + rand2); } Console.WriteLine(); for (int i = 0; i < 10; i++) { int rand1 = random.Next(5, 15); ulong rand2 = Well512.Next(5, 15); Console.WriteLine(i + ": " + rand1 + ", " + rand2); } // perf // Random PerfOfRandom(random, 10); PerfOfMT(10); PerfOfRandom(random, 100000000); PerfOfMT(100000000); } </pre> <br /> 출력 결과는 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 0: 1730630173, 3099563570 1: 817418037, 2432892948 2: 834912966, 646458163 3: 637659925, 3393587455 4: 789744846, 1702337066 5: 1836434216, 82224553 6: 747279096, 1371995332 7: 681895050, 3383000384 8: 1976598118, 2439882382 9: 520252988, 4048663526 0: 6, 3 1: 1, 5 2: 9, 1 3: 8, 6 4: 5, 9 5: 1, 7 6: 2, 8 7: 9, 2 8: 4, 1 9: 7, 7 0: 10, 9 1: 14, 14 2: 8, 12 3: 12, 11 4: 13, 13 5: 12, 14 6: 5, 7 7: 12, 12 8: 14, 11 9: 12, 5 10 elapsed: 0 // JIT 컴파일 고려 10 elapsed: 0 // JIT 컴파일 고려 <span style='color: blue; font-weight: bold'>100000000 elapsed: 1747 - System.Random 100000000 elapsed: 2897 - Well512</span> </pre> <br /> Random과 비교한 성능이 의외군요. 물론 루프 횟수가 워낙 크기 때문에 저 정도의 성능 차이는 무시할 수 있을 정도라고 여겨집니다. 사실, 결과적으로 보면 Well512 클래스 자체가 닷넷에서는 크게 의미가 없어 보입니다. 왜냐하면, C++의 rand() 함수가 전역적인 반면 닷넷의 System.Random 타입은 인스턴스가 지역적으로 관리될 수 있기 때문에 두 기기 간의 동기화를 맞추는 데 전혀 문제가 없습니다.<br /> <br /> 그렇지만, 굳이 활용도를 생각해 본다면 서로 다른 언어간의 동기화를 맞출 일이 있는 경우겠지요. WELL 소스 코드가 간단하기 때문에 자바로도 포팅이 가능하기 때문입니다.<br /> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=708&boardid=331301885'>첨부된 파일은 위의 코드를 포함한 예제 프로젝트</a>입니다.)<br /> <br /> 그나저나... 게임 개발자들로부터 배울 것들이 정말 많군요. 지난번 글도 그렇고. ^^ 요즘 들어서 그들의 열정과 지식에 대한 탐구에 놀라게 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 홀 펀칭(Hole Punching)을 이용한 Private IP 간 통신 - C# ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1226'>http://www.sysnet.pe.kr/2/0/1226</a> </pre> </p><br /> <br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6079
(왼쪽의 숫자를 입력해야 합니다.)