개체의 시각적 감지를 위해 노력하고 있으며 Opencv의 계단식 분류기를 사용합니다. 그것은 잘 작동하지만 너무 느립니다. 나는 Vtune을 사용하여 모든 핫스팟을 얻었으며 140 초에 걸친 실행 (CPU 시간, 실제는 약 60 초)에 123 초의 오버 헤드 시간이 있다는 것을 알았습니다. cvCascadeClassifier는 TBB를 사용하여 더 빠르지 만 모든 TBB 스레드는 필요한 것보다 더 많이 기다리는 것으로 보입니다.효율적으로 TBB 스레드의 결과를 병합하는 방법
void operator()(const Range& range) const
{
Ptr<FeatureEvaluator> evaluator = classifier->featureEvaluator->clone();
Size winSize(cvRound(classifier->data.origWinSize.width * scalingFactor), cvRound(classifier->data.origWinSize.height * scalingFactor));
int y1 = range.start * stripSize;
int y2 = min(range.end * stripSize, processingRectSize.height);
for(int y = y1; y < y2; y += yStep)
{
for(int x = 0; x < processingRectSize.width; x += yStep)
{
if ((!mask.empty()) && (mask.at<uchar>(Point(x,y))==0)) {
continue;
}
double gypWeight;
int result = classifier->runAt(evaluator, Point(x, y), gypWeight);
#if defined (LOG_CASCADE_STATISTIC)
logger.setPoint(Point(x, y), result);
#endif
if(rejectLevels)
{
if(result == 1)
result = -(int)classifier->data.stages.size();
if(classifier->data.stages.size() + result < 4)
{
mtx->lock();
rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor), winSize.width, winSize.height));
rejectLevels->push_back(-result);
levelWeights->push_back(gypWeight);
mtx->unlock();
}
}
else if(result > 0)
{
mtx->lock();
rectangles->push_back(Rect(cvRound(x*scalingFactor), cvRound(y*scalingFactor),
winSize.width, winSize.height));
mtx->unlock();
}
if(result == 0)
x += yStep;
}
}
}
나는 문제가 결과의 병합에서 오는 생각 : 코드가있다. 뮤텍스 잠금이 너무 많아서 스레드가 너무 자주 대기해야합니다. 이 부분의 코드는 많은 시간을 필요로하며 스레드가 거의 없습니다 (제 경우에는 3 개). 각 스레드에 대해 로컬 벡터를 만들려고했는데 (Rect 형식이 매우 작기 때문에 목록으로 시도하지 않았 음) 결국 모든 벡터를 병합했습니다. 이 솔루션은 오버 헤드 시간 (CPU 시간의 140s에서 10 초 미만)을 줄이지 만 더 많은 것을 원합니다.
이것은 내 질문입니다. 다른 TBB 스레드의 결과를 효율적으로 병합 할 수 있습니까 (일명 오버 헤드 시간 감소)?
편집 : 내 경우, 나는 연결하는 동안 오류를 발견했습니다. 로컬 벡터를 만들고 뮤텍스와 함께 끝에서 병합하면 잘 작동합니다. 이제 140 초의 CPU 시간에 0.1 초의 오버 헤드가 발생했습니다. 아주 작은 요소가 거의없는 특별한 경우입니다. 안톤의 대답은 당신이 TBB concurrent_vector를 사용하려고 할 수 있습니다