本文首发于个人博客https://kezunlin.me/post/8d877e63/,欢迎阅读!

cpp caffe net run in multiple threads

Guide

set_mode

Caffe fails to use GPU in a new thread ???

see here

the `Caffe::mode_` variable that controls this is thread-local,
so ensure you’re calling `caffe.set_mode_gpu()` in each thread
before running any Caffe functions. That should solve your issue. Caffe set_mode GPU 在多线程下失效
在main thread中设置GPU模式,在worker thread中调用网络进行检测,
GPU模式不起效,默认仍然使用CPU模式,所以速度很慢,和GPU相比慢了
10倍左右。 解决方案:在子线程中set_mode,然后调用网络进行检测。
(1)创建网络在main thread。static 网络存储在全局静态数据区。
worker thread可以直接使用。
(2) 在worker thread中检测,需要在子线程中set_mode,然后调用网络进行检测。 结论:
(1)caffe的set_mode所在的线程必须和使用nets进行forward的线程相同。否则默认使用CPU模式,速度会很慢。
(2)caffe的nets初始化可以在main thread也可以在worker thread。

code example

#include <iostream>
#include <string>
#include <thread> #include <gtest/gtest.h>
#include <glog/logging.h> #include <boost/date_time/posix_time/posix_time.hpp> // opencv
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp> using namespace std; #include "algorithm/algorithm.h"
using namespace kezunlin::algorithm; #pragma region net-demo void topwire_demo(bool run_in_worker_thread)
{
if (run_in_worker_thread) {
CaffeApi::set_mode(true, 0, 1234);// set in worker thread-1, use GPU-0
} // do net detect
// ...
} void railway_demo(bool run_in_worker_thread)
{
if (run_in_worker_thread) {
CaffeApi::set_mode(true, 0, 1234);// set in worker thread-1, use GPU-0
} // do net detect
// ...
} void sidewall_demo(bool run_in_worker_thread)
{
if (run_in_worker_thread) {
CaffeApi::set_mode(true, 0, 1234);// set in worker thread-1, use GPU-0
} // do net detect
// ...
} void lockcatch_demo(bool run_in_worker_thread)
{
if (run_in_worker_thread) {
CaffeApi::set_mode(true, 0, 1234);// set in worker thread-1, use GPU-0
} // do net detect
// ...
} #pragma endregion #pragma region worker-thread-demo void worker_thread_topwire_demo(bool run_in_worker_thread)
{
std::thread thr(topwire_demo, run_in_worker_thread);
thr.join();
} void worker_thread_railway_demo(bool run_in_worker_thread)
{
std::thread thr(railway_demo, run_in_worker_thread);
thr.join();
} void worker_thread_sidewall_demo(bool run_in_worker_thread)
{
std::thread thr(sidewall_demo, run_in_worker_thread);
thr.join();
} void worker_thread_lockcatch_demo(bool run_in_worker_thread)
{
std::thread thr(lockcatch_demo, run_in_worker_thread);
thr.join();
} #pragma endregion enum DETECT_TYPE {
SET_IN_MAIN_DETECT_IN_MAIN, // 主线程set_mode,主线程检测,40ms左右,使用GPU
SET_IN_WORKER_DETECT_IN_WORKER, // 子线程set_mode,子线程检测,40ms左右,使用GPU
SET_IN_MAIN_DETECT_IN_WORKER // 主线程set_mode,子线程检测,400ms左右,慢了10倍左右,没有使用GPU
}; void thread_demo()
{
DETECT_TYPE detect_type = SET_IN_MAIN_DETECT_IN_MAIN;
detect_type = SET_IN_WORKER_DETECT_IN_WORKER;
detect_type = SET_IN_MAIN_DETECT_IN_WORKER; init_algorithm_api(); switch (detect_type)
{
case SET_IN_MAIN_DETECT_IN_MAIN:
topwire_demo(false);
railway_demo(false);
sidewall_demo(false);
lockcatch_demo(false);
break;
case SET_IN_WORKER_DETECT_IN_WORKER:
worker_thread_topwire_demo(true);
worker_thread_railway_demo(true);
worker_thread_sidewall_demo(true);
worker_thread_lockcatch_demo(true);
break;
case SET_IN_MAIN_DETECT_IN_WORKER:
worker_thread_topwire_demo(false);
worker_thread_railway_demo(false);
worker_thread_sidewall_demo(false);
worker_thread_lockcatch_demo(false);
break;
default:
break;
} free_algorithm_api();
} void test_algorithm_api()
{
thread_demo();
} TEST(algorithn_test, test_algorithm_api) {
test_algorithm_api();
}
  • SET_IN_MAIN_DETECT_IN_MAIN, // 主线程set_mode,主线程检测,40ms左右,使用GPU
  • SET_IN_WORKER_DETECT_IN_WORKER, // 子线程set_mode,子线程检测,40ms左右,使用GPU
  • SET_IN_MAIN_DETECT_IN_WORKER // 主线程set_mode,子线程检测,400ms左右,慢了10倍左右,没有使用GPU

Reference

History

  • 20180712: created.

Copyright

caffe网络在多线程中无法使用GPU的解决方案 | cpp caffe net run in multiple threads的更多相关文章

  1. .netcore中无法使用System.Drawing --解决方案

    问题重现: 无法正常使用  解决方法: 安装System.Drawing.Common的NuGet就能正常使用了 操作之后: 这个是.netcoe中的解决办法,.net framework解决方案中添 ...

  2. Java多线程中的常用方法

    本文将带你讲诉Java多线程中的常用方法   Java多线程中的常用方法有如下几个 start,run,sleep,wait,notify,notifyAll,join,isAlive,current ...

  3. 为什么多线程、junit 中无法使用spring 依赖注入?

    为什么多线程.junit 中无法使用spring 依赖注入? 这个问题,其实体现了,我们对spring已依赖太深,以至于不想自己写实例了. 那么到底是为什么在多线程和junit单元测试中不能使用依赖注 ...

  4. 网络与多线程---OC中多线程使用方法(一)

    小编在此之前,通过一个小例子,简单的形容了一下进程与线程之间的关系,现在网络编程中的多线程说一下!!! *进程的基本概念 每一个进程都是一个应用程序,都有自己独立的内存空间,一般来说一个应用程序存在一 ...

  5. boost中asio网络库多线程并发处理实现,以及asio在多线程模型中线程的调度情况和线程安全。

    1.实现多线程方法: 其实就是多个线程同时调用io_service::run for (int i = 0; i != m_nThreads; ++i)        {            boo ...

  6. c#初学-多线程中lock用法的经典实例

    本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义     lock 关键字可以用来确保代码块完成运行,而不会被 ...

  7. iOS多线程中,队列和执行的排列组合结果分析

    本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...

  8. iOS开发网络篇—多线程断点下载

    iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  9. 多线程中lock用法的经典实例

    多线程中lock用法的经典实例 一.Lock定义     lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.它可以把一段代码定义为互斥段(critical section),互斥段在一 ...

随机推荐

  1. Maven -- 使用Myeclipse创建Maven项目

    使用Myeclipse创建Maven项目有如下几种方式: 1.创建Maven Java项目 1.1 选择新建Maven项目 1.2.选择创建简单项目 1.3.填写项目信息 1.4.创建成功后项目目录结 ...

  2. kubectl get 后按2次tab键命令补全的失效原因分析

    kubectl get 后按2次tab键命令补全的失效原因分析 2019/10/28 Chenxin a.bash客户端工具 在centos用户下, cd ~;echo "source &l ...

  3. 树莓派apt报错:E: '\Release' 这个值对 APT::Default-Release 是无效的,因为在源里找不到这样的发行

    E: '\jessie' 这个值对 APT::Default-Release 是无效的,因为在源里找不到这样的发行 开始尝试了各种方法, 换apt源, 改/etc/apt/apt.conf.d/10d ...

  4. 百万年薪python之路 -- 模块

    1.自定义模块 1.1.1 模块是什么? 模块就是文件,存放一堆常用的函数和变量的程序文件(.py)文件 1.1.2 为什么要使用模块? 1.避免写重复代码,从文件级别组织程序,更方便管理 2.可以多 ...

  5. 是可忍孰不可忍!!nodepad++作者台独分子,恶毒言论!!!

    本来用了两年这个软件吧,不带任何情感的,单纯辅助工具.直到今天,在GitHub上,发现了这个作者以及一些同党都是一群尼玛生在中国骂中国的狗币. https://github.com/notepad-p ...

  6. Java基于回调的观察者模式详解

    本文由“言念小文”原创,转载请说明文章出处 一.前言 什么是回调?回调如何使用?如何优雅的使用?本文将首先详解回调的原理,然后介绍回调的基本使用方法,最后介绍基于回调的“观察者模式”实现,演示如何优化 ...

  7. mysql慢日志分析组件安装

    1.pt-query-digest 安装 cd /usr/bin wget percona.com/get/pt-query-digest chmod u+x pt-query-digest yum ...

  8. seq2seq+attention解读

    1什么是注意力机制? Attention是一种用于提升Encoder + Decoder模型的效果的机制. 2.Attention Mechanism原理 要介绍Attention Mechanism ...

  9. 使用VS2013操作MYSQL8 (ADO.NET方式 & EF6)

    今天有时间测试了一下通过.net环境操作MYSQL数据库,测试过程及结果记录如下: 1.MYSQL安装 (1)我是从MYSQL官网下载的最新版,即MYSQL8.0,在MySql官网的下载页面,找到“M ...

  10. python 线程、进程与协程

    一.什么是线程?什么是进程? 第一,进程是一个实体.每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region).数据区域(data region)和堆栈(stack regio ...