ncnn刚发布不久,博主在ios下尝试编译。
遇上了openmp的编译问题。
寻找各种解决方案无果,亲自操刀。
采用std::thread 替换 openmp。
ncnn项目地址:
https://github.com/Tencent/ncnn
后来询问ncnn的作者才知道在ios下的编译方法。
至此,当时的临时方案 采用std::thread 替换 openmp。
想想也许在一些特定情况下还是比较适用的,当前方便两者之间进行切换验证。
抽空写了一个示例项目。
项目地址:
https://github.com/cpuimage/ParallelFor
贴上完整代码:
#include <stdio.h> #include <stdlib.h> #include <iostream> #if defined(_OPENMP) // compile with: /openmp #include <omp.h> auto const epoch = omp_get_wtime(); double now() { return omp_get_wtime() - epoch; }; #else #include <chrono> auto const epoch = std::chrono::steady_clock::now(); double now() { return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - epoch).count() / 1000.0; }; #endif template<typename FN> double bench(const FN &fn) { auto took = -now(); return (fn(), took + now()); } #include <functional> #if defined(_OPENMP) # include <omp.h> #else #include <thread> #include <vector> #endif #ifdef _OPENMP static int processorCount = static_cast<int>(omp_get_num_procs()); #else static int processorCount = static_cast<int>(std::thread::hardware_concurrency()); #endif static void ParallelFor(int inclusiveFrom, int exclusiveTo, std::function<void(size_t)> 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; ; ) { thread_cnt = std::thread::hardware_concurrency(); } size_t entry_per_thread = (exclusiveTo - inclusiveFrom) / thread_cnt; ) { for (int i = inclusiveFrom; i < exclusiveTo; ++i) { func(i); } return; } std::vector<std::thread> 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] = * b[i]; } int main() { ; 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); } ; } ; i < N; i++) { a1[i] = i; a2[i] = i; b[i] = i; } double beforeTime = bench([&] { ; i < N; i++) { test_scale(i, a1, b); } }); std::cout << ) << "ms" << std::endl; double afterTime = bench([&] { ParallelFor(, N, [a2, b](size_t i) { test_scale(i, a2, b); }); }); std::cout << ) << "ms" << std::endl; ; 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(); ; }
要使用OPENMP,加个编译选项/openmp 或者定义一下 _OPENMP 即可。
建议c++11编译。
示例代码比较简单。
ncnn代码修改例子如下:
#pragma omp parallel for ; q<channels; q++) { const Mat m = src.channel(q); Mat borderm = dst.channel(q); copy_make_border_image(m, borderm, top, left, type, v); }
改为
ParallelFor(, 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
修改ncnn的openmp异步处理方法 附C++样例代码的更多相关文章
-
vc弹出USB的方法. 附试验通过的代码!
vc弹出USB的方法. 附试验通过的代码! http://blog.sina.com.cn/s/blog_4fcd1ea30100qrzn.html (2011-04-15 10:09:48) boo ...
-
Java 序列化Serializable具体解释(附具体样例)
Java 序列化Serializable具体解释(附具体样例) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描写叙述的过程:反序列化deserializa ...
-
Java向上转型和向下转型(附具体样例)
Java向上转型和向下转型(附具体样例) 熬夜整理的关于Java向上和向下转型的样例,很的通俗易懂哦~~~~ 一 ...
-
10分钟理解Android数据库的创建与使用(附具体解释和演示样例代码)
1.Android数据库简单介绍. Android系统的framework层集成了Sqlite3数据库.我们知道Sqlite3是一种轻量级的高效存储的数据库. Sqlite数据库具有以下长处: (1) ...
-
boost写的异步客户端样例代码修改为支持断开重连的代码
考虑到boost的工业级强度,因此就直接用了,代码的官方示例地址:https://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/examples/ ...
-
MySQL——修改root密码的4种方法(以windows为例)
方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...
-
[MySQL]修改root密码的4种方法(以windows为例)
方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...
-
Swift - 继承UIView实现自定义可视化组件(附记分牌样例)
在iOS开发中,如果创建一个自定义的组件通常可以通过继承UIView来实现.下面以一个记分牌组件为例,演示了组件的创建和使用,以及枚举.协议等相关知识的学习. 效果图如下: 组件代码:Score ...
-
ListView中pointToPosition()方法使用具体演示样例
MainActivity例如以下: package cc.testpointtoposition; import java.util.ArrayList; import java.util.HashM ...
随机推荐
-
Java学习笔记四——运算符
算术运算符 加减乘除(+.-.*./)就不说了. 求余运算符% 描述:第一个操作数除以第二个操作数,得到一个整除的结果后剩下的值就是余数 注意:求余预算的结果不一定总是整数,当操作数是浮点数时,结果可 ...
-
SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework
3.1运行效果: 3.2开发实现: 3.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...
-
iOS复杂动画之抽丝剥茧(Objective-C &; Swift)
一.前言 随着开发者的增多和时间的累积,AppStore已经有非常多的应用了,每年都有很多新的APP产生.但是我们手机上留存的应用有限,所以如何吸引用户,成为产品设计的一项重要内容.其中炫酷的动画效果 ...
-
jquery实现替代iframe的功能
使用iframe能很好的嵌入其他的网页或者网站,但是iframe每次加载都会浪费好多的时间,且会阻止其他元素的加载,搜索引擎也不能识别页面ifram框架中被调用的链接.文本.图片等等内容的. Html ...
-
C# - linq查询现有的DataTable
可以通过linq对现有的DataTable进行查询,并将结果拷贝至新的DataTable中例如: // Query the SalesOrderHeader table for orders plac ...
-
HttpWebRequest get/post方法实现
get请求url #region GetHttp请求 /// <summary> /// GetHttp请求 /// </summary> /// <param name ...
-
【Win 10 应用开发】UI Composition 札记(七):基于表达式的动画
上一篇烂文中,老周给大伙伴们介绍过了几个比较好玩的动画.本篇咱们深化主题,说一说基于表达式的动画.这名字好理解,就是你可以用公式 / 等式来产生动画的目标值.比如,你想让某个可视化对象的高度减半,你的 ...
-
XIB中拖UIScrollView的困难
最近在开发中有一个移植代码的工作,但是呢那块代码是n多年前写的,虽然还没看时就感觉到坑不小,到真正看的时候才发现是个陨石坑.具体的说呢,所有的界面都是xib托的而且没用Auto Layout约束,而且 ...
-
PCL学习笔记1
先贴一段代码,从别处抄来的 #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_type ...
-
elasticsearch 分片(Shards)的理解
分片重要性 Es中所有数据均衡的存储在集群中各个节点的分片中,会影响ES的性能.安全和稳定性, 所以很有必要了解一下它. 分片是什么? 简单来讲就是咱们在ES中所有数据的文件块,也是数据的最小单元块, ...