문제

다중 스레드 응용 프로그램을 디버깅하고 내부 구조를 찾았습니다. CRITICAL_SECTION. 데이터 멤버를 찾았습니다 LockSemaphore Critical_section의 흥미로운 것.

보입니다 LockSemaphore 자동 리세트 이벤트 (이름에서 알 수 있듯이 세마포어가 아님)이며 운영 체제는 처음으로 스레드가 대기 할 때이 이벤트를 조용히 만듭니다. Critcal Section 다른 스레드에 의해 잠겨 있습니다.

이제 중요한 섹션이 항상 더 빠른지 궁금합니다. 이벤트는 커널 객체이며 각 임계 섹션 객체는 이벤트 객체와 연관되어 있습니다. Critical Section MUTEX와 같은 다른 커널 객체에 비해 빠를 수 있습니까? 또한 내부 이벤트 객체는 실제로 중요 섹션의 성능에 어떤 영향을 미칩니 까?

여기의 구조가 있습니다 CRITICAL_SECTION:

struct RTL_CRITICAL_SECTION
{
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;
};
도움이 되었습니까?

해결책

중요한 섹션이 "빠른 섹션"이라고 말하면 "다른 스레드가 아직 잠겨 있지 않은 경우 획득하는 것이 저렴하다"는 것을 의미합니다.

경우에 유의하십시오 ~이다 이미 다른 스레드에 의해 잠겨 있으면 얼마나 빠른지는 거의 중요하지 않습니다.

빠른 이유는 커널에 들어가기 전에 해당에 해당하는 것을 사용하기 때문입니다. InterlockedIncrement 그 중 하나에 LONG 필드 (아마도 LockCount 필드) 그리고 그것이 성공하면 커널에 들어 가지 않고 잠금 장치를 고려합니다.

그만큼 InterlockedIncrement API는 사용자 모드에서 "Lock Inc"Opcode로 구현된다고 생각합니다. 즉, 링 전환을 전혀 사용하지 않고는 비경쟁 중요한 섹션을 획득 할 수 있습니다.

다른 팁

성능 작업에서 "항상"카테고리에 속하는 것은 거의 없다 :) 다른 프리미티브를 사용하여 OS 중요 섹션과 비슷한 것을 직접 구현하면 대부분의 경우 속도가 느려질 확률이 낮습니다.

질문에 대답하는 가장 좋은 방법은 성능 측정에 대한 것입니다. OS 객체의 성능이 있습니다 매우 시나리오에 따라 다릅니다. 예를 들어, 경합이 낮은 경우 중요한 섹션은 일반적으로 '빠른'것으로 간주됩니다. 잠금 시간이 스핀 카운트 시간보다 적은 경우에도 빠르게 간주됩니다.

결정해야 할 가장 중요한 것은 중요한 섹션에서의 경합이 응용 프로그램의 첫 번째 차수 제한 요소인지 여부입니다. 그렇지 않은 경우, 중요한 섹션을 사용하여 정상적인 섹션을 사용하고 응용 프로그램 1 차 병목 현상 (또는 목)에서 작업하십시오.

중요한 섹션 성능이 중요하다면 다음을 고려할 수 있습니다.

  1. '핫'중요 섹션의 스핀 잠금 수를 신중하게 설정하십시오. 성능이 가장 중요하다면 여기의 작업은 그만한 가치가 있습니다. 스핀 잠금 장치는 사용자 모드를 커널 전환으로 피하기 위해 CPU 시간을 분노한 속도로 소비하지만 회전하는 동안 CPU 시간을 사용하지는 않습니다. 잠금 장치가 충분히 오래 유지되면 회전 스레드가 실제 블록으로되어 다른 작업을 수행하기 위해 해당 CPU를 제거합니다.
  2. 독자/작가 패턴이있는 경우 사용을 고려하십시오. 슬림 독자/작가 (SRW) 자물쇠. 여기서 단점은 Vista 및 Windows Server 2008 이상에서만 사용할 수 있다는 것입니다.
  3. 당신은 사용할 수 있습니다 조건 변수 폴링과 경합을 최소화하기위한 비판적 섹션을 사용하면 필요할 때만 실을 깨우십시오. 다시 말하지만, 이들은 Vista 및 Windows Server 2008 이상 제품에서 지원됩니다.
  4. 사용을 고려하십시오 연동 링크 된 목록 (슬리스트)- 이들은 효율적이고 '잠금'입니다. 더 좋은 점은 XP 및 Windows Server 2003 이상 제품에서 지원됩니다.
  5. 코드 검사 - 일부 코드를 리팩토링하고 연동 조작을 사용하거나 동기화 및 통신을 위해 슬리랑을 사용하여 '핫'잠금 장치를 분해 할 수 있습니다.

요약 - 잠금 경합이있는 튜닝 시나리오는 도전적이지만 (그러나 흥미로운!) 작동 할 수 있습니다. 응용 프로그램 성능 측정 및 뜨거운 경로가 어디에 있는지 이해하는 데 집중하십시오. XPERF 도구 Windows 성능 도구 키트 당신의 친구입니다 :) 우리는 방금 Windows 7 용 Microsoft Windows SDK에서 버전 4.5를 출시했습니다. 3.5 SP1 (.ISO가 여기 있습니다, 여기 웹 설치자). Xperf 도구 포럼을 찾을 수 있습니다 여기. v4.5는 Win7, Vista, Windows Server 2008- 모든 버전을 완전히 지원합니다.

Criticatsections는 더 빠르지 만 인터 로크 시멘트/인터 로크 드레임 더. 이 구현 사용 샘플을 참조하십시오 LightweidtLock 전체 사본.

Criticatsections는 짧은 시간 (몇 MS)을 회전시키고 잠금 장치가 무료인지 계속 확인합니다. 스핀 카운트 'Times Out'후에는 커널 이벤트로 돌아갑니다. 따라서 자물쇠 보유자가 빨리 나오는 경우, 값 비싼 커널 코드로 전환 할 필요가 없습니다.

편집 : 내 코드에서 몇 가지 의견을 찾았습니다. 분명히 MS 힙 관리자는 4000의 스핀 카운트를 사용합니다 (MS가 아닌 정수 증가).

다음은 그것을 볼 방법입니다.

경합이 없으면 스핀 잠금 장치는 뮤텍스의 커널 모드로 이동하는 것과 비교할 때 실제로 빠릅니다.

경합이있을 때, 결정은 뮤텍스를 직접 사용하는 것보다 약간 비싸다 (스핀 락 상태를 감지하기위한 추가 작업 때문에).

따라서 가중 평균으로 요약되며, 가중치는 호출 패턴의 세부 사항에 따라 다릅니다. 즉, 논쟁이 거의 없다면, 비판적인 것은 큰 승리입니다. 반면에, 당신은 일관되게 많은 논쟁을 가지고 있다면, 당신은 뮤텍스를 직접 사용하는 것보다 아주 작은 페널티를 지불하게 될 것입니다. 그러나이 경우 뮤텍스로 전환하여 얻을 수있는 것은 작기 때문에 경합을 줄이려는 것이 더 나을 것입니다.

중요한 섹션은 MUTEX보다 빠릅니다. 중요한 섹션이 커널 객체가 아니기 때문입니다. 이것은 현재 프로세스의 글로벌 메모리의 일부입니다. MUTEX는 실제로 커널에 존재하며 MUTEXT 객체의 생성에는 커널 스위치가 필요하지만 중요한 섹션의 경우에는 그렇지 않습니다. 중요한 섹션은 빠르지 만 스레드가 상태를 기다릴 때 중요한 섹션을 사용하는 동안 커널 스위치가 있습니다. 스레드 스케줄링이 커널 측에서 발생하기 때문입니다.

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