성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
글쓰기
제목
이름
암호
전자우편
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'>[부연] CAS Lock <strike>Lock-Free</strike> 알고리즘은 과연 빠른가?</h1> <p> 아래와 같은 글이 있군요. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Lock-Free 알고리즘은 과연 빠른가? ; <a target='tab' href='http://little-thread.blogspot.kr/2014/08/lock-free.html'>http://little-thread.blogspot.kr/2014/08/lock-free.html</a> </pre> <br /> 결론은 CAS Lock <strike>lock-free</strike>보다 CriticalSection을 쓴 것이 더 빠르다는 것입니다.<br /> <br /> 그런데, 약간 테스트 상에 공정성이 위배되는 것이 있습니다. CriticalSection은 블록으로 썼으면서,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ULONGLONG t0 = ::GetTickCount64(); for (int i = 0; i < TEST_LOOP; i++) { <span style='color: blue; font-weight: bold'>::EnterCriticalSection(&cs);</span> volatile LONG* p = v; for (int j = 0; j < cntTest; j++) { _asm mov eax, p; _asm inc[eax]; p++; } <span style='color: blue; font-weight: bold'>::LeaveCriticalSection(&cs);</span> } </pre> <br /> CAS Lock <strike>lock-free</strike> 쪽은 매순간 lock을 거는 방식을 썼습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > ULONGLONG t1 = ::GetTickCount64(); for (int i = 0; i < TEST_LOOP; i++) { volatile LONG* p = v; for (int j = 0; j < cntTest; j++) { _asm mov eax, p; <span style='color: blue; font-weight: bold'>_asm lock inc[eax];</span> p++; } } ULONGLONG t2 = ::GetTickCount64(); for (int i = 0; i < TEST_LOOP; i++) { volatile LONG* p = v; for (int j = 0; j < cntTest; j++) { <span style='color: blue; font-weight: bold'>::InterlockedIncrement(p);</span> p++; } } </pre> <br /> CAS Lock <strike>lock-free</strike>를 블록으로 사용하는 방법은 조금 미루고 바로 위에 소개한 2개의 테스트를 좀 볼까요? 우선 _asm으로 인라인 시킨 경우 실행시 기계어가 이렇고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > mov eax,dword ptr [ebp-0C0h] lock inc byte ptr [eax] </pre> <br /> InterlockedIncrement의 경우 결국 다음과 같은 기계어로 인라인 되므로,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > mov eax,dword ptr [ebp-0F4h] mov ecx,1 lock xadd dword ptr [eax],ecx </pre> <br /> 별반 큰 차이가 없습니다. 재미있는 것은 기계어가 오히려 1개 더 늘었는데도 "<a target='tab' href='http://little-thread.blogspot.kr/2014/08/lock-free.html'>Lock-Free 알고리즘은 과연 빠른가?</a>" 글에 공개된 수치를 보면 InterlockedIncrement의 성능이 근소하게 빠르다는 점입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > test = 1 : lock = 202, lock_free 1 = 110, lock_free 2 = 78 test = 2 : lock = 234, lock_free 1 = 171, lock_free 2 = 172 test = 3 : lock = 218, lock_free 1 = 250, lock_free 2 = 234 test = 4 : lock = 234, lock_free 1 = 343, lock_free 2 = 281 test = 5 : lock = 234, lock_free 1 = 437, lock_free 2 = 358 test = 6 : lock = 234, lock_free 1 = 515, lock_free 2 = 421 test = 7 : lock = 250, lock_free 1 = 593, lock_free 2 = 499 test = 8 : lock = 250, lock_free 1 = 686, lock_free 2 = 562 test = 9 : lock = 265, lock_free 1 = 733, lock_free 2 = 624 test = 10 : lock = 281, lock_free 1 = <span style='color: blue; font-weight: bold'>811</span>, lock_free 2 = <span style='color: blue; font-weight: bold'>702</span> </pre> <br /> <hr style='width: 50%' /><br /> <br /> 그나저나, CAS Lock <strike>lock-free</strike>를 블록으로 사용하는 방법이 뭘까요? 예전에 이에 대해 한번 소개해 드렸었지요. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > CAS Lock <strike>lock-free</strike> 방식이 과연 성능에 얼마나 도움이 될까요? ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1458'>http://www.sysnet.pe.kr/2/0/1458</a> </pre> <br /> 저 역시 위의 글에서 C#의 경우 lock 코드가 CAS Lock <strike>lock-free</strike>보다 더 빠르다고 결론을 내렸었습니다. 따라서 저 글의 코드를 유사하게 가져다가 테스트를 할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > volatile unsigned int _lockVariable = 0; ULONGLONG t3 = ::GetTickCount64(); for (int i = 0; i < TEST_LOOP; i++) { volatile LONG* p = v; <span style='color: blue; font-weight: bold'> while (::InterlockedCompareExchange(&_lockVariable, 1, 0) != 0) { }</span> for (int j = 0; j < cntTest; j++) { _asm mov eax, p; _asm inc[eax]; p++; } <span style='color: blue; font-weight: bold'>_lockVariable = 0;</span> } </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;' > test = 1 : lock = 203, lock_free 1 = 78, lock_free 2 = 78, lock_free 3 = 250 test = 2 : lock = 188, lock_free 1 = 125, lock_free 2 = 125, lock_free 3 = 265 test = 3 : lock = 203, lock_free 1 = 204, lock_free 2 = 187, lock_free 3 = 266 test = 4 : lock = 218, lock_free 1 = 250, lock_free 2 = 235, lock_free 3 = 281 test = 5 : lock = 219, lock_free 1 = 312, lock_free 2 = 297, lock_free 3 = 297 test = 6 : lock = 234, lock_free 1 = 360, lock_free 2 = 359, lock_free 3 = 313 test = 7 : lock = 234, lock_free 1 = 422, lock_free 2 = 422, lock_free 3 = 328 test = 8 : lock = 266, lock_free 1 = 500, lock_free 2 = 484, lock_free 3 = 359 test = 9 : lock = 266, lock_free 1 = 547, lock_free 2 = 547, lock_free 3 = 375 test = 10 : <span style='color: blue; font-weight: bold'>lock = 281</span>, lock_free 1 = 609, lock_free 2 = 594, <span style='color: blue; font-weight: bold'>lock_free 3 = 391</span> </pre> <br /> 오호~~~ 그래도 CriticalSection보다 성능이 낮군요. 그러나 이것은 DEBUG 빌드의 결과물입니다. Release 빌드로 하면 상황이 역전됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > test = 1 : lock = 187, lock_free 1 = 78, lock_free 2 = 47, lock_free 3 = 109 test = 2 : lock = 204, lock_free 1 = 125, lock_free 2 = 109, lock_free 3 = 94 test = 3 : lock = 203, lock_free 1 = 187, lock_free 2 = 157, lock_free 3 = 78 test = 4 : lock = 203, lock_free 1 = 250, lock_free 2 = 203, lock_free 3 = 109 test = 5 : lock = 219, lock_free 1 = 313, lock_free 2 = 265, lock_free 3 = 94 test = 6 : lock = 203, lock_free 1 = 391, lock_free 2 = 312, lock_free 3 = 94 test = 7 : lock = 219, lock_free 1 = 453, lock_free 2 = 359, lock_free 3 = 110 test = 8 : lock = 218, lock_free 1 = 516, lock_free 2 = 406, lock_free 3 = 125 test = 9 : lock = 219, lock_free 1 = 594, lock_free 2 = 453, lock_free 3 = 125 test = 10 : <span style='color: blue; font-weight: bold'>lock = 219</span>, lock_free 1 = 671, lock_free 2 = 500, <span style='color: blue; font-weight: bold'>lock_free 3 = 141</span> </pre> <br /> 보시는 바와 같이 새롭게 추가한 "lock_free 3" 번의 결과는 CriticalSection 보다 성능이 더 좋습니다.<br /> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=874&boardid=331301885'>첨부한 코드</a>는 "<a target='tab' href='http://little-thread.blogspot.kr/2014/08/lock-free.html'>Lock-Free 알고리즘은 과연 빠른가?</a>" 글에 공개된 것에 블록 방식의 lock-free 코드를 추가한 것입니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
5692
(왼쪽의 숫자를 입력해야 합니다.)