문제

우리는 성능 문제에 빠지고 있으며, 하나의 잠재적 범인은 휘발성 싱글 톤을 중앙 집중화하는 것입니다. 특정 코드는 양식입니다

class foo {
  static volatile instance;
  static object l = new object();

  public static foo Instance {
    if (instance == null)
      lock(l) {
        if (instance == null)
          instance = new foo();
      }

    return foo();
  }
}

이것은 8 방향 상자에서 실행 중이며 컨텍스트가 초당 500,000의 조율로 전환되는 것을보고 있습니다. 일반적인 시스템 리소스는 괜찮습니다 -25% CPU UTIL, 25% 메모리 UTIL, 낮은 IO, 페이징 없음 등.

휘발성 필드를 사용하면 메모리 장벽이나 모든 종류의 CPU 캐시 재 장전이 유발됩니까? 아니면 그 필드에 대해서만 메인 메모리를 따라가나요?

도움이 되었습니까?

해결책

lock 메모리 장벽을 유발하므로 잠금 장치에서 항상 인스턴스에 액세스하는 경우 휘발성이 필요하지 않습니다.

에 따르면 이 지역:

C# 휘발성 키워드는 시맨틱을 획득하고 릴리스하는 시합을 구현하며, 이는 읽기에 대한 읽기 메모리 장벽과 쓰기에 대한 쓰기 메모리 장벽을 의미합니다.

다른 팁

휘발성이없는 한 가지는 컨텍스트 스위치를 유발하는 것입니다. 초당 500,000 개의 컨텍스트 스위치가 보이면 스레드가 무언가를 차단하고 휘발성이 있음을 의미합니다. ~ 아니다 그 범인.

슬프게도, 싱글 톤은 거의 모든 것에 대해 나쁜 랩을 취합니다 :)

이것은 내 전문 지식 도메인이 아니지만, 최적화 목적으로 읽기/쓰기 (변수)를 재정렬하지 않는 컴파일러/런타임 이외의 휘발성에 대해 특별한 것은 없다.

편집 : 나는 수정했다. 휘발성은 메모리 장벽을 도입 할뿐만 아니라, 진행되는 일 (그리고 우연히 성능)에 따라 관련된 특정 CPU에 달려 있습니다. 보다 http://dotnetframeworkplanet.blogspot.com/2008/11/volatile-field-and-memory-barrier-look.html

이것이 당신이 여전히 자물쇠가 필요한 이유입니다.

이미 답변되었을 수있는 질문 :

  1. 싱글 톤 인스턴스는 실제로 무엇을하고 있습니까? 인스턴스 코드를 리팩토링해야 할 수도 있습니다 ...
  2. 실행 프로세스의 스레드 수는 얼마입니까? 비정상적으로 높은 스레드 카운트가 있으면 8 웨이 상자는 도움이되지 않습니다.
  3. 예상보다 높으면 왜?
  4. 시스템에서 다른 무엇이 실행되고 있습니까?
  5. 성능 문제가 일관성이 있습니까?

여기서 귀하의 예에서, 휘발성은 "둔화"의 주제가되어서는 안됩니다. 그러나 잠금 장치 ()에는 특히 잠금 장치에 대한 논쟁이 많은 경우 커널에 큰 왕복이 포함될 수 있습니다.

이 경우 싱글 톤을 잠글 필요가 없습니다.

class Foo {
  static Foo instance = new Foo();
  public static Foo FooInstance() {
    return instance ;
  }
}

물론, '인스턴스'가 많은 다른 스레드에서 사용되는 경우 FOO의 모든 메소드/속성이 준비되지 않는 한 여전히 () FOO를 변경하는 모든 것을 잠그면해야합니다. 예를 들어

 class Foo {
      static Foo instance = new Foo();
      object l = new object();
      int doesntChange = 42;
      int canChange = 123;
      public static Foo FooInstance() {
        return instance ;
      }
      public void Update(int newVal) {
         lock(l) { // you'll get a lot of trouble without this lock if several threads accesses the same FOO. Atleast if they later on read that variable 
            canChange = newVal;
         }

      public int GetFixedVal() {
         return doesntChange; //no need for a lock. the doesntChange is effectivly read only
      }
    }

싱글 톤에 휘발성을 사용할 필요가 없습니다. 정확히 한 번 설정하고 코드를 잠그므로 세트를 잠그십시오. 보다 싱글 톤에 관한 Jon Skeet의 기사 더 많은 정보를 위해서.

짧은 대답은 예, 메모리 장벽을 생성하는 것입니다 (모든 것을 플러시하고 단일 변수뿐만 아니라 메인 메모리로 이동). 컨텍스트 전환의 원인은 아닙니다.

또한 다른 사람들이 언급했듯이 여기서 휘발성이 필요하다고 생각하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top