中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

網(wǎng)站建設(shè)彳金手指排名設(shè)計外包網(wǎng)站

網(wǎng)站建設(shè)彳金手指排名,設(shè)計外包網(wǎng)站,用織夢建設(shè)網(wǎng)站的步驟,企業(yè)網(wǎng)站制作及cms技術(shù)需求:圖像識別中,注冊的樣本多了會影響計算速度,成為性能瓶頸,其中一個優(yōu)化方法就是使用多線程。例如,注冊了了3000個特征,每個特征4096個float??梢园?000個特征比對放到4個線程中進行計算,然…

需求:圖像識別中,注冊的樣本多了會影響計算速度,成為性能瓶頸,其中一個優(yōu)化方法就是使用多線程。例如,注冊了了3000個特征,每個特征4096個float??梢园?000個特征比對放到4個線程中進行計算,然后再把結(jié)果進行合并。實現(xiàn)思路:

1. 根據(jù)系統(tǒng)性能和需求配置線程池的大小,創(chuàng)建線程池,將比較任務(wù)平均分配到各個線程

2. 工作線程啟動后在一個condition_variable上wait,注意:鎖的范圍不能太大了,否則多個線程會變成串行

3. 調(diào)用者調(diào)用識別接口,接口更新目標特征,通知各個工作線程,在另外一個condition_variable上wait,并且滿足完成計數(shù)器的值等于線程數(shù)

4. 工作線程完成后將計數(shù)器加一,并且通知調(diào)用線程

5. 調(diào)用線程收集到所有線程的結(jié)果后再對結(jié)果進行合并返回

后續(xù):

1. 代碼進行優(yōu)化,更優(yōu)雅的實現(xiàn)

測試結(jié)果:

線程數(shù)

時間

1

71362ms

2

36292ms

4

19420ms

8

18465ms

16

18433ms

32

18842ms

64

19324ms

128

19388ms

256

21853ms

512

26150ms

1024

35593ms

代碼如下:

#include <iostream>

#include <string>

#include <cstring>

#include <mutex>

#include <unordered_map>

#include <list>

#include <utility>

#include <algorithm>

#include <string>

#include <vector>

#include <thread>

#include <chrono>

using namespace std;

using namespace chrono;


?

double get_mold(const vector<double> &vec)

{

int n = vec.size();

double sum = 0.0;

for(int i = 0; i < n; ++i)

{

sum += vec[i] * vec[i];

}

return sqrt(sum);

}

double cosine_distance(const vector<double> &base, const vector<double> &target)

{

int n = base.size();

double tmp = 0.0;

for(int i = 0; i < n; ++i)

{

tmp += base[i] * target[i];

}

double simility = tmp / (get_mold(base) * get_mold(target));

return simility;

}


?

class Recognizer

{

public:

Recognizer(int num_threads) :

num_threads_(num_threads),

is_run_calculate_thread_(true),

is_doing_recognize(false),

result_count(0)

{

recognize_result = std::vector<RecognizeResult>(num_threads);

this->load_feature();

this->init_threads();

}

~Recognizer()

{

is_run_calculate_thread_ = false;

cv_.notify_all();

for(std::thread &th : threads_)

th.join();

}

int do_recognize(const vector<double> &feature);

private:

class CigaretteItem

{

public:

int cigarette_id_;

std::string cigarette_name_;

std::vector<double> feature_;

CigaretteItem(int cigarette_id, std::string cigarette_name, const std::vector<double> &cigarette_feature)

{

cigarette_id_ = cigarette_id;

cigarette_name_ = cigarette_name;

feature_ = std::vector<double>(cigarette_feature.size());

for(int i = 0; i < cigarette_feature.size(); i++)

{

feature_[i] = cigarette_feature[i];

}

}

};

class RecognizeResult

{

public:

int cigarette_id_;

std::string cigarette_name_;

double score_;

};

private:

int num_threads_;

bool is_run_calculate_thread_;

bool is_doing_recognize;

std::vector<CigaretteItem> ciagarette_list_;

std::vector<double> target_feature_;

std::mutex cv_mtx_;

std::condition_variable cv_;

std::vector<RecognizeResult> recognize_result;

std::vector<std::thread> threads_;

int result_count;

std::mutex result_count_mtx_;

std::mutex result_cv_mtx_;

std::condition_variable result_cv_;


?

private:

Recognizer(const Recognizer&) = delete;

Recognizer& operator=(const Recognizer&) = delete;

void load_feature();

void init_threads();

void calculate_most_similarity(const int thread_id, const int start_index, const int end_index);

};


?

void Recognizer::load_feature()

{

for(int i = 0; i < 3000; i++)

{

vector<double> fea = vector<double>(4096);

for(int i = 0; i < 4096; ++i)

fea[i] = (double)(rand() % 998 + 1) / 1000.00;

ciagarette_list_.emplace_back(i+1, "cigarette", fea);

}

}

void Recognizer::init_threads()

{

for(int i = 0; i < num_threads_; i++)

{

int step = this->ciagarette_list_.size() / this->num_threads_;

int start_index = i * step;

int end_index = (i+1) * step;

if(i == num_threads_ - 1){

end_index = ciagarette_list_.size();

}

std::cout << "thread" << i << " starts at " << start_index << "; ends at " << end_index << std::endl;

threads_.emplace_back(&Recognizer::calculate_most_similarity, this, i, start_index, end_index);

}

}

void Recognizer::calculate_most_similarity(const int thread_id, const int start_index, const int end_index)

{

while(is_run_calculate_thread_)

{

{

std::unique_lock<std::mutex> lock(cv_mtx_);

cv_.wait(lock);

}

//cout << "thread" << thread_id << " is running" << endl;

double max_score = -1.00;

int max_score_index = -1;

for(int i = start_index; i < end_index; ++i){

double score = cosine_distance(ciagarette_list_[i].feature_, target_feature_);

if(score > max_score)

{

max_score = score;

max_score_index = i;

}

}

recognize_result[thread_id].cigarette_id_ = ciagarette_list_[max_score_index].cigarette_id_;

recognize_result[thread_id].cigarette_name_ = ciagarette_list_[max_score_index].cigarette_name_;

recognize_result[thread_id].score_ = max_score;

{

std::unique_lock<std::mutex> lock(result_count_mtx_);

result_count += 1;

}

result_cv_.notify_one();

//std::cout << "thread" << thread_id << " finish one task" << endl;

}

//std::cout << "thread" << thread_id << " finished." << std::endl;

}

int Recognizer::do_recognize(const vector<double> &feature)

{

if(is_doing_recognize)

return -1;

is_doing_recognize = true;

this->target_feature_ = feature;

//cout << "cv_.notify_all()" << endl;

cv_.notify_all();

std::unique_lock<std::mutex> lock(result_cv_mtx_);

result_cv_.wait(lock, [this](){return this->num_threads_ == this->result_count;});

//std::cout << "all threads finish computing similarity" << endl;

int max_score_cigarette_id = -1;

std::string max_score_cigarette_name = "";

double max_score = -1.0;

for(int i = 0; i < num_threads_; ++i)

{

if(recognize_result[i].score_ > max_score)

{

max_score_cigarette_id = recognize_result[i].cigarette_id_;

max_score_cigarette_name = recognize_result[i].cigarette_name_;

max_score = recognize_result[i].score_;

}

}

//cout << "cigarette_id=" << max_score_cigarette_id << ", cigarette_name=" << max_score_cigarette_name << ", score=" << max_score << endl;

this->result_count = 0;

is_doing_recognize = false;

return 0;

}


?

int main(void)

{

Recognizer recognizer{1024};

std::this_thread::sleep_for(std::chrono::seconds(1));

const int loops = 400;

auto start_time = system_clock::now();

for(int i = 0; i < loops; i++)

{

//cout << endl;

std::vector<double> target_feature = std::vector<double>(4096);

for(int i = 0; i < 4096; ++i)

{

//target_feature[i] = (double)(rand() % 998 + 1) / 1000.000;

target_feature[i] = (double)(i % 1000 + 1) / 1000.00;

}

recognizer.do_recognize(target_feature);

//if((i+1) % 20 == 0)

// cout << "i=" << i << endl;

}

auto end_time = system_clock::now();

auto duration = duration_cast<milliseconds>(end_time - start_time);

cout << "eplased_time:" << duration.count() << "ms" << endl;

std::this_thread::sleep_for(std::chrono::seconds(2));

return 0;

}

http://www.risenshineclean.com/news/9342.html

相關(guān)文章:

  • 贛楠臍橙網(wǎng)絡(luò)營銷推廣方式凱里seo排名優(yōu)化
  • wordpress個人網(wǎng)站域名電子商務(wù)平臺
  • 工行網(wǎng)站跟建設(shè)網(wǎng)站區(qū)別汕頭網(wǎng)站建設(shè)公司哪個好
  • 免費網(wǎng)站的手機版本源碼模板廣告軟文案例
  • 建設(shè)電影推薦網(wǎng)站的項目背景獨立站推廣
  • wordpress淘寶優(yōu)惠券插件寧波免費seo排名優(yōu)化
  • 網(wǎng)站建設(shè)行業(yè)發(fā)展洛陽網(wǎng)站建設(shè)
  • wordpress圖片播放優(yōu)化大師官網(wǎng)下載安裝
  • 嵐山網(wǎng)站建設(shè)互聯(lián)網(wǎng)營銷推廣公司
  • 網(wǎng)站流量高iis如何做負載均衡搜狗競價
  • 手機上怎么制作app網(wǎng)站更新seo
  • 合肥建設(shè)網(wǎng)站制作哪個好灰色關(guān)鍵詞代發(fā)可測試
  • 17網(wǎng)站一起做網(wǎng)店2018各網(wǎng)站收錄
  • 網(wǎng)站建設(shè)源碼百度平臺電話
  • 模板網(wǎng)站也可以做優(yōu)化廣東公司搜索seo哪家強
  • 有沒有做公司網(wǎng)站的seo網(wǎng)站建設(shè)
  • 深圳企業(yè)網(wǎng)站建設(shè)報價百度一下百度搜索官網(wǎng)
  • 為推廣網(wǎng)站做的宣傳活動企業(yè)推廣網(wǎng)站
  • 網(wǎng)站建設(shè)規(guī)范想做個網(wǎng)絡(luò)推廣
  • 成都住建局官網(wǎng)商品住房登記系統(tǒng)成都優(yōu)化網(wǎng)站哪家公司好
  • 專業(yè)的聊城網(wǎng)站建設(shè)什么是seo搜索優(yōu)化
  • 長春建站塔山雙喜客戶資源買賣平臺
  • 網(wǎng)站快速排名是怎么做的北京百度網(wǎng)站排名優(yōu)化
  • wordpress網(wǎng)站怎么建設(shè)海南百度推廣開戶
  • 大網(wǎng)站制作公司熱點事件
  • 虛擬主機空間發(fā)布網(wǎng)站谷歌排名網(wǎng)站優(yōu)化
  • 官方模板windows優(yōu)化工具
  • 武威市住房和建設(shè)局網(wǎng)站江門關(guān)鍵詞優(yōu)化公司
  • 萬網(wǎng)網(wǎng)站電話上海seo推廣方法
  • 網(wǎng)頁微信截圖快捷鍵天津seo網(wǎng)站管理