2011-02-03 4 views
5

내 프로젝트 중 하나에서 중요한 병목으로 std::deque<T>::clear()에 대한 호출을 확인했습니다.전용 스레드에서 STL 지우기

template <class T> 
void SomeClass::parallelClear(T& c) 
{ 
    if (!c.empty()) 
    { 
     T* temp = new T; 
     c.swap(*temp); // swap contents (fast) 

     // deallocate on separate thread 
     boost::thread deleteThread([=]() { delete temp; }); 

     // Windows specific: lower priority class 
     SetPriorityClass(deleteThread.native_handle(), BELOW_NORMAL_PRIORITY_CLASS); 
    } 
} 

void SomeClass:clear(std::deque<ComplexObject>& hugeDeque) 
{ 
    parallelClear(hugeDeque); 
} 

이 (VisualC++ 2010) 잘 작동하는 것 같다,하지만 난 모든 주요 결함을 간과 궁금 :

나는 때문에 전용, 우선 순위가 낮은 스레드에서이 작업을 이동하기로 결정했다. 위의 코드에 대한 의견을 환영합니다.

추가 정보 :

SomeClass:clear()는 GUI 스레드에서 호출, 사용자 인터페이스는 호출이 반환 될 때까지 응답하지 않습니다. 반면에 hugeQueue은 지워진 후 몇 초 동안 해당 스레드가 액세스하지 않을 것입니다.

+0

디버거를 연결하지 않고 실행해도 속도가 느립니까? –

+0

STL 컨테이너 자체는 스레드로부터 안전하지 않으므로 다중 스레드 환경에서 컨테이너 작업을 수행하기 전에 코드에서이를 전제로 사용해야합니다. – DumbCoder

+0

예. 실제로 사용하고있는 deque에는 int가 아닌 수백만 개의 객체가 포함되어 있습니다. –

답변

2

이것은 힙에 대한 액세스가 일련 화된다는 것을 보증하는 경우에만 유효합니다. Windows 이 기본적으로 기본 힙에 대한 액세스를 직렬화하지만이 동작을 해제 할 수 있으며 플랫폼이나 라이브러리간에 유지된다는 보장이 없습니다. 따라서, 스레드에 따라 공유되는 힙과 힙이 액세스하기에 스레드로부터 안전하다는 점에 명시 적으로주의해야한다는 점에 따라주의해야합니다.

개인적으로 할당/할당 취소 패턴을 일치시키는 사용자 지정 할당자를 사용하면 스레드 최적화가 오버 헤드가 거의 발생하지 않는다는 것을 기억하십시오.

편집 : GUI/워커 스레드 스타일 스레딩 디자인을 사용하는 경우 실제로는 을 작성하고 작업자 스레드에서이 큐를 제거해야합니다.

+0

@DeadMG : 하나는 시스템 단위로 직렬화를 끌 수 있습니까? 아니면 컴파일 타임 설정입니까? –

+0

그래서이 사용자 정의 할당 기에서 전용 힙을 사용하면 정리할 때 한꺼번에 할당을 해제 할 수 있습니까? –

+0

@Daniel : 내가 아는 한, 런타임에 설정을 변경할 수 있습니다. 사용자 지정 할당 자에 관해서는 할당 패턴에 대해 충분히 알지 못합니다. 그러나 매우 큰 단일 개체와 일련의 할당이있는 경우에는 전체 힙 할당을 해제하는 것이 좋습니다. 물론, 당신은 여전히 ​​관련 객체를 파괴해야합니다. – Puppy

1

응용 프로그램의 전체 성능을 향상시킬 수 있는지 확실하지 않습니다. Windows 표준 힙 (낮은 조각화 힙)은 할당 정보를 한 스레드에서 다른 스레드로 자주 전송하기 위해 배치되지 않습니다. 이 작업은 가능하지만 처리에 상당한 오버 헤드가 발생할 수 있습니다.

보물 메모리 할당의 문서는 출발점이에 깊은합니까 수 있습니다 : http://www.cs.umass.edu/~emery/hoard/hoard-documentation.html

귀하의 접근 방식은 비록 응답 성 개선 등 다른 포스터에 의해 언급 된 것들 외에도

+0

답장을 보내 주셔서 감사합니다. 필자의 경우, 힙은 일반적으로 스레드 A에서 1,000 번, 스레드 B에서 동일한 양 (A가 할당 한 객체 할당 해제) 등으로 액세스됩니다. 그래서 나는 자주 바꾸지 않을거야. 그러나 특정 할당자를 사용하여 대안을 확인합니다 (응용 프로그램의 나머지 부분은 이미 구현되어 있으며 자체의 특정 메모리 관리 루틴을 사용합니다). –

0

컬렉션에 포함 된 개체에 스레드 선호도가 있는지 고려해야합니다. 예를 들어 단일 스레드 아파트의 COM 개체는 이러한 종류의 트릭에 적합하지 않을 수 있습니다.