2011-08-30 3 views
4

나는 개발 한 오픈 소스 프로젝트에 대해 다음 코드를 최적화하거나 무거운 작업을 다른 스레드로 옮겨 더 성능을 향상시킬 방법을 찾고있다.스레드 안전 큐가 좋은 접근 방법입니까?

void ProfilerCommunication::AddVisitPoint(ULONG uniqueId) 
{ 
    CScopedLock<CMutex> lock(m_mutexResults); 
    m_pVisitPoints->points[m_pVisitPoints->count].UniqueId = uniqueId; 
    if (++m_pVisitPoints->count == VP_BUFFER_SIZE) 
    { 
     SendVisitPoints(); 
     m_pVisitPoints->count=0; 
    } 
} 

위의 코드는 OpenCover 프로파일 방문 할 때마다 포인트가 호출 (C로 작성 .NET 용 오픈 소스 코드 검사 도구 ++)에 의해 사용된다. 뮤텍스는 호스트 프로세스를 신호 할 때 일부 공유 메모리 (여러 프로세스 32/64 비트와 C++/C#간에 공유 된 64K 블록)를 보호하는 데 사용됩니다. 분명히 이것은 각 계측 포인트에 대해 상당히 무거 우므로 영향을 더 가볍게 만들고 싶습니다.

위의 방법으로 푸시 된 큐와 데이터를 팝하고 공유 메모리를 채우는 스레드를 사용하려고합니다.

Q. 사용할 수있는 C++ (Windows STL)에 스레드 안전 큐가 있습니까? 또는 하나의 큐를 다른 큐로 대체하지 않으려면 잠금이 필요없는 큐가 있습니까? 사람들은 내 접근 방식을 합리적으로 생각합니까?


편집 1 : 난 그냥 포함 폴더에 concurrent_queue.h을 발견했다 -이 내 대답이 될 수 ...?

+0

같은 것은이 없습니다 대기열에서 여러 작성자와 여러 독자가있는 경우 안전 잠금 대기열을 잠글 수 있습니다. 그러나 단일 독자와 단일 작가가있는 경우 간단하게 안전하게 밟을 수 있으며 대부분의 구현에는이 규칙이 적용됩니다. –

+0

[허브 셔터의 대기 시간 구현] (http://drdobbs.com/cpp/212201163) (기사에 액세스하려면 무료 계정을 만들어야 함)을 확인하십시오. 그것은 원자 변수를 사용합니다. –

+0

concurrent_queue를 발견 했으므로 VS2010에 있습니까? – RedX

답변

1

좋아, 내가 내 자신의 대답을 추가 할 것입니다 - concurrent_queue 아주 잘 나는 동시 큐 (그리고 작업과 처음 C++ 람다 식 :)) 나는 오래 지출하지 않았다 구현이 MSDN article에 설명 된 정보를 사용하여

작동 그것이 스파이크이기 때문에 생각.

inline void AddVisitPoint(ULONG uniqueId) { m_queue.push(uniqueId); } 

... 
// somewhere else in code 

m_tasks.run([this] 
{ 
    ULONG id; 
    while(true) 
    { 
     while (!m_queue.try_pop(id)) 
      Concurrency::Context::Yield(); 

     if (id==0) break; // 0 is an unused number so is used to close the thread/task 
     CScopedLock<CMutex> lock(m_mutexResults); 
     m_pVisitPoints->points[m_pVisitPoints->count].UniqueId = id; 
     if (++m_pVisitPoints->count == VP_BUFFER_SIZE) 
     { 
      SendVisitPoints(); 
      m_pVisitPoints->count=0; 
     } 
    } 
}); 

결과 : 계측없이

  • 응용 프로그램 = 옛 계측 핸들러 새로운 장비 핸들러 = 38.6
  • 응용 프로그램과 9.3
  • 응용 프로그램 = 16.2
+0

그리고 지금 뮤텍스 처리를 향상시킬 수 있다고 확신합니다. 그러나 중요한 경로에 더 이상 중요하지 않으므로 이것은 중요하지 않습니다. –

+0

이것이 유일한 것으로 투표 된 것입니다. 자신의 대답) –

0

Here it mentions not all container operations are thread safe on Windows. Only a limited number of methods. 그리고 나는 C++ 표준이 threadsafe 컨테이너에 대해 언급하지 않는다. 나도 틀렸지 만 아무 것도 나오지 않은 표준을 확인했습니다.

+0

방금 ​​전에보고있었습니다. http://blogs.msdn.com/b/nativeconcurrency/archive/2009/11/23/the-concurrent -queue-container-in-vs2010.aspx도 마찬가지입니다 - 제가 C#에서 –

0

클라이언트의 통신을 별도의 스레드로 오프로드 할 수 있습니까? 그런 다음 검사 점은 스레드 로컬 저장소를 사용하여 히트를 기록하고 전체 스레드가 참조로 전달 될 때 로컬 스레드와 통신해야합니다. 그런 다음 통신 쓰레드는 더 이상 핫 경로에 있지 않기 때문에 실제 콜렉터로 데이터를 전달하는 데 시간이 걸릴 수 있습니다.

+0

과 비슷한 이름의 클래스를 사용하여 재미 있습니다 - 그냥 공유 메모리에 대한 호출에서 데이터를 얻고 있습니다 - 런타임으로 공유 메모리를 사용하여 종료 할 수 있습니다 프로필러는 경고없이 언제든지 가능하므로 최대한 많은 데이터를 캡처하고 호스트에서 읽을 수 있습니다. –

0

잠금 해제 대기열을 사용할 수 있습니다. 허브 셔터는 기사가 here입니다.

+0

concurrent_queue가 해당 기준을 충족시킬 것으로 보입니다 - 어떻게 생각하십니까? –