У меня есть следующий код, который путает меня много:C++ создание потоков большая голова
float OverlapRate(cv::Mat& model, cv::Mat& img) {
if ((model.rows!=img.rows)||(model.cols!=img.cols)) {
return 0;
}
cv::Mat bgr[3];
cv::split(img, bgr);
int counter = 0;
float b_average = 0, g_average = 0, r_average = 0;
for (int i = 0; i < model.rows; i++) {
for (int j = 0; j < model.cols; j++) {
if((model.at<uchar>(i,j)==255)){
counter++;
b_average += bgr[0].at<uchar>(i, j);
g_average += bgr[1].at<uchar>(i, j);
r_average += bgr[2].at<uchar>(i, j);
}
}
}
b_average = b_average/counter;
g_average = g_average/counter;
r_average = r_average/counter;
counter = 0;
float b_stde = 0, g_stde = 0, r_stde = 0;
for (int i = 0; i < model.rows; i++) {
for (int j = 0; j < model.cols; j++) {
if((model.at<uchar>(i,j)==255)){
counter++;
b_stde += std::pow((bgr[0].at<uchar>(i, j) - b_average), 2);
g_stde += std::pow((bgr[1].at<uchar>(i, j) - g_average), 2);
r_stde += std::pow((bgr[2].at<uchar>(i, j) - r_average), 2);
}
}
}
b_stde = std::sqrt(b_stde/counter);
g_stde = std::sqrt(g_stde/counter);
r_stde = std::sqrt(r_stde/counter);
return (b_stde + g_stde + r_stde)/3;
}
void work(cv::Mat& model, cv::Mat& img, int index, std::map<int, float>& results){
results[index] = OverlapRate(model, img);
}
int OCR(cv::Mat& a, std::map<int,cv::Mat>& b, const std::vector<int>& possible_values)
{
int recog_value = -1;
clock_t start = clock();
std::thread threads[10];
std::map<int, float> results;
for(int i=0; i<10; i++)
{
threads[i] = std::thread(work, std::ref(b[i]), std::ref(a), i, std::ref(results));
}
for(int i=0; i<10; i++)
threads[i].join();
float min_score = 1000;
int min_index = -1;
for(auto& it:results)
{
if (it.second < min_score) {
min_score = it.second;
min_index = it.first;
}
}
clock_t end = clock();
clock_t t = end - start;
printf ("It took me %d clicks (%f seconds) .\n",t,((float)t)/CLOCKS_PER_SEC);
recog_value = min_index;
}
Что делает приведенный выше код является только простым оптическими распознаванием символов. У меня есть один оптический символ в качестве входного сигнала и сравниваю его с 0 - 9 десятью стандартными символьными моделями, чтобы получить наиболее похожий, а затем вывести признанное значение.
Когда я выполняю вышеуказанный код без использования десяти потоков, работающих одновременно, время составляет 7 мс. НО, когда я использую десять потоков, он опускается до 1 или 2 секунд для одного оптического распознавания символов.
В чем причина? Отладочная информация говорит о том, что создание потоков потребляет много времени, что составляет этот код:
threads[i] = std::thread(work, std::ref(b[i]), std::ref(a), i, std::ref(results));
Почему? Благодарю.
Вы спрашиваете: «Почему для создания потока требуется много времени?» ? – ZivS
Разрешено ли 'work' изменять' model' или 'img'? Как поточно-безопасный вы считаете «результатом», так как вы изменяете его в каждом потоке? – kfsone
Попробуйте синхронизировать только создание потоков отдельно, а цикл вызова подключается отдельно, и, конечно, сохраняйте время для полной функции. Затем вы сможете сузить, какая часть кода занимает время. –