2012-11-01 2 views
78

가능한 최상의 성능으로 C#에서 스레드 안전 카운터를 얻는 방법은 무엇입니까?C# 스레드 안전 fast (est) 카운터

이수록 이것은 간단하다 :

public static long GetNextValue() 
{ 
    long result; 
    lock (LOCK) 
    { 
     result = COUNTER++; 
    } 
    return result; 
} 

를하지만 빠른 대안이 있습니까? Interlocked.Increment

답변

138

20

난 당신이하여 System.Threading 라이브러리에 .NET의 연동 증가에 내장을 사용하는 것이 좋습니다.

다음 코드는 참조로 긴 변수를 증가하고 완전하게 스레드 안전된다

Interlocked.Increment(ref myNum); 

출처 : http://msdn.microsoft.com/en-us/library/dd78zt0c.aspx 다른 사람에 의해 권장

66

에서, Interlocked.Incrementlock()보다 더 나은 성능을 제공합니다. Increment이 "버스 잠금"문으로 바뀌고 변수가 직접 증가 (x86)되거나 "추가"(x64)되는 IL 및 어셈블리를 살펴보십시오.

이 "bus lock"문은 호출 CPU가 작업을 수행하는 동안 다른 CPU가 버스에 액세스하지 못하도록 버스를 잠급니다. 자, C# lock() 성명서의 일리노이를 살펴보십시오. 섹션을 시작하거나 종료하려면 Monitor으로 전화가 걸립니다.

다른 말로하면 .Net lock() 문은 .Net Interlocked.Increment 이상을 수행합니다.

그래서 변수를 증가 시키려면 모두 Interlock.Increment이 더 빠릅니다. 인터 로킹 된 모든 메소드를 검토하여 사용 가능한 다양한 원자 조작을보고 사용자의 필요에 맞는 작업을 찾으십시오. 여러 개의 상호 관련 증가/감소와 같은 더 복잡한 작업을 수행하거나 정수보다 복잡한 자원에 대한 액세스를 직렬화하려는 경우 lock()을 사용하십시오.

+0

구현 세부 정보에 대해 – fsimonazzi

+0

-1 컨텍스트를 추가하는 경우의 Upvote. 잠금이 원자 연산보다 느린 것은 사실이지만 IL과는 아무런 관련이 없습니다. 이러한 함수 호출은 본질적으로 일리노이에 필요하지 않은 의미론이 아니라면 원자 연산보다 훨씬 빠를 것입니다. – Puppy