공유 상태가 성능을 저하시키는 이유는 무엇입니까?


19

나는 동시 프로그래밍의 아무 것도없는 원칙 아래서 일하고있다. 기본적으로 모든 작업자 스레드에는 동일한 상태의 변경 불가능한 읽기 전용 복사본이 있으며 이들 스레드는 절대로 참조로 공유되지 않습니다 . 일반적으로, 이것은 실제로 잘 작동했습니다.

이제 누군가가 모든 스레드가 동시에 액세스 하는 잠금없는 싱글 톤 캐시 ( 예 : 정적 사전 )를 도입했습니다 . 시작 후에 사전이 변경되지 않으므로 잠금이 없습니다. 스레드 안전성 문제는 없었지만 이제 성능이 저하되었습니다.

문제는 ... 잠금이 없기 때문에이 싱글 톤을 도입하면 성능이 저하되는 이유는 무엇입니까? 이것을 설명 할 수있는 표지 아래에서 정확히 무슨 일이 일어나고 있습니까?

확인하기 위해이 새로운 싱글 톤에 액세스하는 것이 유일한 변경 사항이며 캐시에 대한 호출을 주석 처리하여이를 확실하게 다시 만들 수 있습니다.


8
코드에서 프로파일 러를 가리 켰습니까?
Timo Geusch

2
CLR 및 Windows 커널을 프로파일 링하지 않는 한 프로파일 링은이 질문에 대답하지 않을 것입니다 (일반 프로그래머에게는 쉬운 일이 아닙니다).
Igby Largeman

1
@JoeGeeky 좋아, 여기에 나를 위해 할 수있는 유일한 일은 +1과 호의입니다! 그것들은 결국 같은 수준의 간접 지향적이며 어쨌든 프로세서 캐시에 적합해야하기 때문에 이상하게 보인다 ...
Max

2
FWIT 나는 몇 개의 스레드를 생성하고 타이머를 실행했습니다. 클래스, singleton, lockedSingleton 및 dict <string, string>을 인스턴스화했습니다. 각각의 첫 인스턴스화 후, 연속 실행은 주어진 객체에 대해 약 2000ns가 걸렸습니다. 사전은 2 배 느리게 실행되었으며 생성자 코드로 인해 발생할 수 있습니다 ... 잠금 자체보다 느립니다. 스레드 대기열 및 기타 오버 헤드에 대한 모든 GC, OS 처리를 고려할 때 ...이 질문에 실제로 대답 할 수 있는지 확실하지 않습니다. 그러나 내 결과 에서이 문제는 싱글 톤과 관련이 있다고 생각하지 않습니다. MSDN에서와 같이 구현 된 경우에는 컴파일러 최적화를 제외합니다.
P.Brian.Mackey

1
@JoeGeeky-또 다른 생각 : 캐시를 사용하면 간접 수준이 추가됩니까? 자주 액세스하는 경우 추가 포인터 디 레프 (또는 MSIL equiv)를 추적하면 로컬 비 간접 복사본보다 시간이 추가 될 수 있습니다.
sdg December

답변:


8

불변 상태는 변경 가능한 것과 캐시 라인을 공유 할 수 있습니다. 이 경우 근처의 변경 가능 상태로 변경하면 코어에서이 캐시 라인을 다시 동기화해야 할 수 있으므로 성능이 저하 될 수 있습니다.


3
이것은 false sharing설명 하는 시나리오 처럼 들립니다 . 이를 분리하려면 L2 캐시를 프로파일 링해야합니다. 불행히도, 이들은 참조 유형이므로 버퍼 공간을 추가하는 것은 실제로 발생하는 경우 옵션이 아닙니다.
JoeGeeky

3

내가 만들 것 확실히 그 Equals()GetHashCode()당신이 어떤 예기치 않은 스레딩 친화적 인 부작용이없는 사전에 키로서 사용하는 객체의 방법. 프로파일 링은 여기서 크게 도움이 될 것입니다.

우연히 키가 문자열이라면 아마도 거기에 있습니다. 소문은 문자열이 불변의 객체처럼 행동하지만 특정 최적화를 위해 내부적으로 변경 가능한 방식으로 구현되며 멀티 스레딩과 관련된 모든 것이 내장되어 있다는 소문이 있습니다 .

문제를 사전의 단일성 또는 단일성에 있는지 여부를 확인하기 위해 싱글 톤 대신 일반 참조로 사용하는 스레드에 사전을 전달하려고합니다. (가능한 원인 제거)

나는 그것의 사용이 놀라운 결과를 산출하는 경우를 대비 ConcurrentDictionary하여 정규 대신에 시도 할 것 Dictionary입니다. ConcurrentDictionary당신의 규칙보다 훨씬 더 나쁘게 수행 하는 것으로 판명 된다면 당면한 문제에 대해 추측 할 것이 많이있다 Dictionary.

위의 어느 것도 문제를 지적하지 않으면 가비지 수집기가 가비지 수집기에서 여부를 알아 내려고하기 때문에 가비지 수집 스레드와 나머지 스레드 간의 이상한 경합으로 인해 성능이 저하된다고 생각합니다. 당신의 사전에있는 객체들은 당신의 쓰레드에 의해 접근되는 동안 폐기되거나 안될 필요가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.