采用std::thread 替换 openmp
内容转换的,具体详见博客:https://cloud.tencent.com/developer/article/1094617 及对应的code:https://github.com/cpuimage/ParallelFor/blob/master/ParallelFor.cpp
#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; static size_t thread_cnt = ;
if (thread_cnt == )
{
thread_cnt = std::thread::hardware_concurrency();
}
size_t entry_per_thread = (exclusiveTo - inclusiveFrom) / thread_cnt; if (entry_per_thread < )
{
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()
{
int N = ;
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 -;
}
for (int i = ; i < N; i++)
{
a1[i] = i;
a2[i] = i;
b[i] = i;
}
double beforeTime = bench([&] {
for (int i = ; i < N; i++)
{
test_scale(i, a1, b);
}
}); std::cout << " \nbefore: " << int(beforeTime * ) << "ms" << std::endl;
double afterTime = bench([&] {
ParallelFor(, N, [a2, b](size_t i)
{
test_scale(i, a2, b);
});
});
std::cout << " \nafter: " << int(afterTime * ) << "ms" << std::endl; for (int i = ; 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 ;
}
要使用OPENMP,加个编译选项/openmp 或者定义一下 _OPENMP 即可。
建议c++11编译。
示例代码比较简单。
这里举例的是ncnn代码修改例子,具体如下:
#pragma omp parallel for
for (int q=; 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);
}});
采用std::thread 替换 openmp的更多相关文章
- 用std::thread替换实现boost::thread_group
thread_group是boost库中的线程池类,内部使用的是boost::thread. 随着C++ 11标准的制定和各大编译器的新版本的推出(其实主要是VS2012的推出啦……),本着能用标准库 ...
- Effective Modern C++ Item 37:确保std::thread在销毁时是unjoinable的
下面这段代码,如果调用func,按照C++的标准,程序会被终止(std::terminate) void func() { std::thread t([] { std::chrono::micros ...
- Microsoft C++ 异常: std::system_error std::thread
第一次使用std::thread,把之前项目里面的Windows的thread进行了替换,程序退出的然后发生了std::system_error. 经过调试,发现std::thread ,join了两 ...
- std::thread(2)
个线程都有一个唯一的 ID 以识别不同的线程,std:thread 类有一个 get_id() 方法返回对应线程的唯一编号,你可以通过 std::this_thread 来访问当前线程实例,下面的例子 ...
- C++ std::thread 多线程中的异常处理
环境: VS2019 包含头文件: #include <iostream>#include<thread>#include<exception> 线程函数采用try ...
- std::thread
std::shared_ptr<std::thread> m_spThread; m_spThread.reset(new std::thread(std::bind(&GameS ...
- C++11 并发指南------std::thread 详解
参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Int ...
- C++ 11 笔记 (五) : std::thread
这真是一个巨大的话题.我猜记录完善绝B需要一本书的容量. 所以..我只是略有了解,等以后用的深入了再慢慢补充吧. C++写多线程真是一个痛苦的事情,当初用过C语言的CreateThread,见过boo ...
- Cocos2dx 3.0 过渡篇(二十六)C++11多线程std::thread的简单使用(上)
昨天练车时有一MM与我交替着练,聊了几句话就多了起来,我对她说:"看到前面那俩教练没?老色鬼两枚!整天调戏女学员."她说:"还好啦,这毕竟是他们的乐趣所在,你不认为教练每 ...
随机推荐
- oracle修改用户密码过期时间
Oracle默认在default概要文件中设置了“PASSWORD_LIFE_TIME=180天”,导致密码过期,程序无法使用,业务进程会提示无法连接数据库等字样. --查询默认密码过期时间 SELE ...
- hibernate 在做更新和删除的时候一定要把事务开启
在做更新和删除的时候一定要把事务开启 在做更新和删除的时候一定要把事务开启 在做更新和删除的时候一定要把事务开启 重要的事情说三遍!!! curd之前配置文件 <property name=&q ...
- PHP位运算符(转)
例子 名称 结果 $a & $b And(按位与) 将在 $a 和 $b 中都为 1 的位设为 1. $a | $b Or(按位或) 将在 $a 或者 $b 中为 1 的位设为 1. $a ^ ...
- android使用全局变量传递数据
android中Application是用来保存全局变量的,在package创建的时候就存在了,到所有的activity都被destroy掉之后才会被释放掉.所以当我们需要全局变量的时候只要在appl ...
- TFS创建登录用户并连接TFS
简单使用 1.创建TFS组(Windows的组) 2.在“TFS管理控制台”中设置“组成员资格” 3.给“Team Foundation Administrators”组设置“属性” 4.给“Team ...
- 解决C# WINFORM程序只允许运行一个实例的几种方法详解
要实现程序的互斥,通常有下面几种方式,下面用 C# 语言来实现: 方法一: 使用线程互斥变量. 通过定义互斥变量来判断是否已运行实例. 把program.cs文件里的Main()函数改为如下代码: u ...
- 连接oracle时报错:ORA-28001: the password has expired
调试Web项目的时候出现异常: java.sql.SQLException: ORA-28001: the password has expired 网上查了一下,是Oracle11g密码过期的原因 ...
- C++ 资源管理之 RAII
RAII,它是“Resource Acquisition Is Initialization”的首字母缩写.也称为“资源获取就是初始化”,是c++等编程语言常用的管理资源.避免内存泄露的方法.它保证在 ...
- Atitit.多媒体区----web视频格式的选择总结
Atitit.多媒体区----web视频格式的选择总结 1. 因为现阶段不同的浏览器支持的视频格式是不同的 1 2. 各浏览器Html5 Video支持的影音格式: 2 3. 解决方案是什么?Flas ...
- wechat talk
https://github.com/13770344697/nanjingzhongan https://github.com/fayuanliu/wxRobot https://github.co ...