2010-11-18 4 views
7

몇 가지 질문이 있습니다. 휘발성스레드 동기화에 대한 몇 가지 질문

  1. 는 변수의 최신 값을 읽을 수 있도록 읽어 보시기 바랍니다. 은 모든 CPU가 에 대한 캐시 된 값을 플러시하도록하는 것을 의미합니다. 그 변수 만 전부입니까? 따라서 모든 CPU가 에 강제로 캐시 된 쓰기를 수행하고 주 메모리에서 최신 버전을 얻으면이 메모리가 메모리 장벽입니까?

  2. 휘발성 쓰기는 주 메모리의 변수에 값을 쓰도록하십시오. 모든 CPU의 변수에 대한 모든 캐시 된 값이 무효화된다는 의미입니까?

  3. 휘발성 키워드를 사용하는 경우 메모리 장벽을 사용하고 있습니까?

  4. Interloked는 작업에서 읽기/수정/쓰기를 수행합니다. Interlocked는 이 예를 들어 이고 변수의 최신 버전이 증가하고 다른 CPU는 이 변경된 것을 확인합니까? 나는 메모리 장벽을 사용하고 있기 때문에 그렇게 생각한다. 하지만 확실하지는 않다. 그렇다면 Interloked가 을 수행하고있는 을 말할 수 있습니다. VolatileRead/modify/VolatileWrite 기본적으로?

  5. 메모리 장벽을 사용할 때 은 모든 CPUS의 모든 변수 또는 주변의 모든 변수에 영향을 줍니까? 그것은 thread를 대기 가있는 경우 두 개의 메모리 장벽과 "컨텍스트 스위치" 의 원인,하지만 연동의 장점은 무엇 때문에

  6. 잠금은 비싸다? 그냥 "컨텍스트 전환"을 피하기 위해?

  7. ReaderWriterLockSlim 및 재귀와는 어떤 차이가 있습니까? 나는 이해하지 못했습니다 무엇이 문제입니까.

자세히 알 수 있듯이 지금은 완전히 혼란스러워하고 있습니다.

미리 감사드립니다.

+4

위의 질문은 훌륭한 답변이지만 별도의 게시물로 요청해야합니다. 이 게시물을 삭제하고 여러 개의 작은 게시물로 나누는 것이 좋습니다. – jason

+2

나는 이유에 대해 자세히 설명해야한다고 생각한다. 1. 긴 게시물은 독자들이 끝내지 못하게한다 (잠재적 인 응답자를 삭제한다). 2. 이주하는 사람은이 질문 중 하나에 대한 답변을 알고 있지만 전부는 아니며 불완전한 답변을 게시해서는 안된다고 생각합니다. 3. 많은 질문을 가진 긴 질문은 응답하는 데 많은 시간이 필요합니다 (따라서 더 많은 응답자를 방해합니다). 이 게시물을 어기면 더 좋아지고 더 많은 반응을 얻습니다. – jason

+1

위의 오타를 유감스럽게 생각합니다. "migrate know the answere"을 ""답을 알고있을 것 "으로 바꾸십시오. – jason

답변

7

질문에 대답하기 전에 나는 메모리 장벽이 CPU 그 이상에 영향을 미친다는 것을 지적해야합니다. 응용 프로그램이 실행될 때 실제로 두 개의 메모리 모델이 있습니다. 하나는 하드웨어 수준이고 다른 하나는 소프트웨어 수준입니다. 개발자는 두 요소의 가장 약한 조합을 코딩해야합니다. CLR과 x86 아키텍처에서 이것은 일반적으로 x86 아키텍처가 실제로 매우 강력한 메모리 모델을 갖고 있기 때문에 CLR이 더 중요하다는 것을 의미합니다. 즉, volatile 키워드 및 기타 메모리 장벽 메커니즘은 JIT가 코드를 생성하는 방법에도 영향을줍니다.

1.휘발성 읽기는 변수의 최신 값을 읽도록합니다. 은 모든 CPU가 에 대한 캐시 된 값을 플러시하도록하는 것을 의미합니다. 그 변수 만 전부입니까? 따라서 모든 CPU가 캐시 된 쓰기를 플러시하고 주 메모리에서 최신 버전 을 가져 오도록하려면이 메모리가 장벽입니까?

기술적으로 휘발성 읽기는 사용자가 변수의 최신 값을 읽는 것을 보장하지 않습니다. 실제로 의미하는 것은 휘발성 메모리보다 먼저 다른 읽기 또는 쓰기가 발생할 수 없다는 것입니다. 그러나 그 효과는 다른 메모리가 읽히기 전에 인 경우 인 경우 읽기가 주 메모리에서 발생해야한다는 것입니다. 둘째, 아니오, 휘발성 읽기는 다른 쓰기에 영향을 미치지 않으므로 모든 CPU가 쓰기 캐시를 플러시하지 않습니다. 셋째, 휘발성 동작은 메모리 장벽으로 간주됩니다.

2.Volatile write를 사용하면 주 메모리의 변수에 값을 쓸 수 있습니다. 모든 CPU에서 해당 변수에 대한 캐시 된 값이 모두 으로 삭제됩니다.

휘발성 읽기와 유사하게 휘발성 쓰기는 기술적으로 주문하는 방법입니다. 휘발성 메모리 이후에 다른 읽기 또는 쓰기가 발생하지 않도록합니다. 문제의 글이 즉시 커밋됨을 의미하지는 않습니다. 이 스레드는 해당 스레드를 실행하는 CPU에만 영향을줍니다. 흥미롭게도 x86 아키텍처는 실제로 모두을 volatile로 처리합니다. 그러나 CLR은 (적어도 ECMA 사양은 아닙니다.) 그래서 글쓰기에 여전히 휘발성 연산을 사용해야합니다. 이것은 하드웨어 및 소프트웨어 레벨 모두에서 가장 약한 메모리 모델 요소를 코딩하는 한 가지 예입니다.

3. 휘발성 키워드를 사용할 때 메모리 장벽을 사용하고 있습니까?

예. 메모리 장벽에는 두 가지 유형이 있습니다. 전체 담장과 반 울타리. 하프 펜스 (half fence)는 의미있는 (volatile 읽기) 또는 release semantics (volatile write)를 얻을 수 있지만 동시에 둘 다 얻을 수는 없습니다. 전체 울타리 (예 : Thread.MemoryBarrier 경유) 모두.

4.Interloked는 원자 단위로 읽기/수정/쓰기를 수행합니다. Interlocked는 이 예를 들어 변수의 최신 버전을 증가시키고 다른 CPU가이 변경 사항을 보게한다는 것을 보장합니까? 나는 을 사용한다고 가정하기 때문에 메모리 장벽이 있지만 확실하지는 않습니다. 그래서 우리는 Interloked가 을하고 있다고 말할 수 있습니다. VolatileRead/modify/VolatileWrite 원자 적으로?

예프. 그리고 연동 된 증가 및 감소 연산을 수행 할만한 가치가있는 것은 CAS 연산으로 구현할 수 있습니다. .NET에서는 작업이 완료 될 때까지 루프에서 Interlocked.CompareExchange 메서드를 사용합니다. 그래도 Interlocked.IncrementInterlocked.Decrement 메서드가 네이티브 CPU 명령어를 사용하지만, 나는 그것에 대해 잘못 준비하고 있습니다.

5. 메모리 장벽을 사용할 때 모든 CPUS의 모든 변수 또는 주변 변수에 영향을 줍니까?

모든 메모리 액세스에는 영향을 미치지 만 해당 스레드를 실행하는 CPU에서만 영향을받습니다. 이 스레드가 대기에있는 경우 두 개의 메모리 장벽과 "컨텍스트 스위치"의 원인,하지만 장점이 연동의 무엇 때문에

6.Locking는 비싸다? 단지 "컨텍스트 전환"을 피하기 위해서입니까?

기본적으로 네. 인터럽트 된 작업으로 스레드가 차단되지 않습니다.

7. ReaderWriterLockSlim과 재귀성은 무엇입니까? 나는 문제가 무엇인지 이해하지 않았다.

잠금을 해제하지 않고 동일한 스레드에서 잠금을 두 번 획득 할 수 없습니다. Joe Duffy's blog에 대한 자세한 정보가 있습니다.

+0

부끄러운 줄 알았는데 한 번만 투표 할 수 있습니다. 내가 이해할 수없는 것은 왜 메모리 장벽이 하나의 CPU에만 영향을 미치는지, 다른 것들은 어떻게 될까요? 내 말은, CPU1이 캐시에 변수의 복사본을 가지고 CPU2의 메모리 장벽에 변수를 쓴다면 CPU1이 메모리 장벽을 수행하지 않는 한 CPU1이 변경 사항을 볼 수 없다는 것을 의미합니까? 그리고 다시 한 번 감사드립니다. – vtortola

+1

@bitbitbit : 그건 정확히 내가 말하는거야! 이것이 바로 잠금없는 코딩 전략이 옳다는 것을 믿을 수 없게 만드는 이유입니다. –

+0

좋습니다! 이제는 모든 것이 더 분명합니다. 다시 한번 감사드립니다. – vtortola

1

잠금을 사용하는 모든 스레드는 다른 스레드가 임의의 시간 동안 잠금을 유지할 위험을 감수해야합니다. Threading.Interlocked.CompareExchange 호출은 성공했는지 여부에 관계없이 거의 즉시 반환됩니다. 고의적으로 무거운 경합의 조건을 제외하고는 짧은 스핀 락도 빠르게 반환됩니다. 스레드가 잠금을 획득 한 다음 해제되어 다른 것들을 해제하기 전에 다른 스레드가 잠금을 획득하기 전에 다른 스레드가 완료 될 때까지 기다려야합니다. CompareExchange 스핀 록과 같은 위험 요소는 없습니다. 다른 스레드가 스핀 록을 적극적으로 치지 않는 한 스핀 록은 신속하게 완료됩니다.