博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
修改ncnn的openmp异步处理方法 附C++样例代码
阅读量:5936 次
发布时间:2019-06-19

本文共 3443 字,大约阅读时间需要 11 分钟。

ncnn刚发布不久,博主在ios下尝试编译。

遇上了openmp的编译问题。

寻找各种解决方案无果,亲自操刀。

采用std::thread 替换 openmp。

ncnn项目地址:

后来询问ncnn的作者才知道在ios下的编译方法。

至此,当时的临时方案 采用std::thread 替换 openmp。

想想也许在一些特定情况下还是比较适用的,当前方便两者之间进行切换验证。

抽空写了一个示例项目。

项目地址:

贴上完整代码:

#include 
#include
#include
#if defined(_OPENMP)// compile with: /openmp #include
auto const epoch = omp_get_wtime();double now() { return omp_get_wtime() - epoch;};#else #include
auto const epoch = std::chrono::steady_clock::now();double now() { return std::chrono::duration_cast
(std::chrono::steady_clock::now() - epoch).count() / 1000.0;};#endiftemplate
double bench(const FN &fn) { auto took = -now(); return (fn(), took + now());}#include
#if defined(_OPENMP)# include
#else #include
#include
#endif#ifdef _OPENMPstatic int processorCount = static_cast
(omp_get_num_procs());#elsestatic int processorCount = static_cast
(std::thread::hardware_concurrency());#endifstatic void ParallelFor(int inclusiveFrom, int exclusiveTo, std::function
func){#if defined(_OPENMP)#pragma omp parallel for num_threads(processorCount) for (int i = inclusiveFrom; i < exclusiveTo; ++i) { func(i); } return;#else if (inclusiveFrom >= exclusiveTo) return; static size_t thread_cnt = 0; if (thread_cnt == 0) { thread_cnt = std::thread::hardware_concurrency(); } size_t entry_per_thread = (exclusiveTo - inclusiveFrom) / thread_cnt; if (entry_per_thread < 1) { for (int i = inclusiveFrom; i < exclusiveTo; ++i) { func(i); } return; } std::vector
threads; int start_idx, end_idx; for (start_idx = inclusiveFrom; start_idx < exclusiveTo; start_idx += entry_per_thread) { end_idx = start_idx + entry_per_thread; if (end_idx > exclusiveTo) end_idx = exclusiveTo; threads.emplace_back([&](size_t from, size_t to) { for (size_t entry_idx = from; entry_idx < to; ++entry_idx) func(entry_idx); }, start_idx, end_idx); } for (auto& t : threads) { t.join(); }#endif}void test_scale(int i, double* a, double* b) { a[i] = 4 * b[i];}int main(){ int N = 10000; double* a2 = (double*)calloc(N, sizeof(double)); double* a1 = (double*)calloc(N, sizeof(double)); double* b = (double*)calloc(N, sizeof(double)); if (a1 == NULL || a2 == NULL || b == NULL) { if (a1) { free(a1); }if (a2) { free(a2); }if (b) { free(b); } return -1; } for (int i = 0; i < N; i++) { a1[i] = i; a2[i] = i; b[i] = i; } double beforeTime = bench([&] { for (int i = 0; i < N; i++) { test_scale(i, a1, b); } }); std::cout << " \nbefore: " << int(beforeTime * 1000) << "ms" << std::endl; double afterTime = bench([&] { ParallelFor(0, N, [a2, b](size_t i) { test_scale(i, a2, b); }); }); std::cout << " \nafter: " << int(afterTime * 1000) << "ms" << std::endl; for (int i = 0; i < N; i++) { if (a1[i] != a2[i]) { printf("error %f : %f \t", a1[i], a2[i]); getchar(); } } free(a1); free(a2); free(b); getchar(); return 0;}

要使用OPENMP,加个编译选项/openmp  或者定义一下 _OPENMP 即可。

建议c++11编译。

示例代码比较简单。

ncnn代码修改例子如下:

#pragma omp parallel for        for (int q=0; q

 改为

ParallelFor(0, channels, [&](int  q) {                {                    const Mat m = src.channel(q);                    Mat borderm = dst.channel(q);                    copy_make_border_image(m, borderm, top, left, type, v);                }});

 

本来计划抽点时间把ncnn整体都改一下,发个修改版本出来。

想想还是把做法贴出来,给有需求的人吧。

自己动手丰衣足食。

若有其他相关问题或者需求也可以邮件联系俺探讨。

邮箱地址是: 

gaozhihan@vip.qq.com

转载于:https://www.cnblogs.com/cpuimage/p/8379501.html

你可能感兴趣的文章
zabbix接入百度告警详细攻略
查看>>
在Exchange 2010邮箱迁移时有用的命令行
查看>>
smarty学习
查看>>
11.python并发入门(part11 进程同步锁,以及进程池,以及callback的概念)
查看>>
GitHub简单仓库管理
查看>>
我的友情链接
查看>>
虚拟化技术对比
查看>>
angular的编辑器tinymce
查看>>
mybatis之三:与spring集成
查看>>
第二阶段团队进展报告(1)
查看>>
如何确定一个网站是用Wordpress开发的
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
wdcp 安装
查看>>
C语言运算符优先级相关问题
查看>>
MP4视频播放器代码
查看>>
Nginx 匹配 iphone Android 微信
查看>>
MFC_Combo_Box(组合框)控件的用法
查看>>
ldap
查看>>
我的友情链接
查看>>