本文转载请注明出处 —— polobymulberry-博客园

0x00 - 前言


最近想优化ORB-SLAM2,准备使用并行计算来提高其中ORB特征提取的速度。之前对并行计算方面一窍不通。借此机会,学习一下基本的并行编程。

在选择并行编程的工具时,需要考虑以下问题:即该工具尽量不要使用与平台相关的API,如iOS端的GCD(Grand Central Dispatch),因为希望程序具有很强的移植性。一开始我想到的只有两种选择,一个是以TBB和OpenMP为首的第三方线程库,另一个是原生线程库。其中TBB和OpenMP对于Xcode的支持不是很好,原生线程库又依赖于系统平台,所以尝试后都放弃了。后来想到C++11已经从语言层面支持了多线程开发,也就是提供了thread库,于是抱着试一试学一学的态度就入坑了。

并行计算中一个很经典的案例就是数组求和,网络上有很多介绍C++11的thread使用、源码分析的文章,不过使用C++11进行数组求和并行计算的示例却很少,所以才有了这篇博文。

0x01 - 代码解析


在iOS系统使用C++11进行开发。

//
//  ViewController.m
//  TestDispatch
//
//  Created by poloby on 2017/1/7.
//  Copyright © 2017年 polobymulberry. All rights reserved.
//

#import "ViewController.h"
#include <iostream>
#include <thread>using namespace std;// 作为求和函数的参数
// 封装了求和函数的输入和输出
typedef struct ThreadArg {long long base;     // 从base~base+length数列求和long long length;long long sum;      // 将上述数列的和存储在sum中
}ThreadArg;void sum(ThreadArg *arg)
{long long begin = arg->base;long long end = arg->base + arg->length;long long sum = 0;// 不要直接使用for(long long i = arg->base; i < arg->base + arg->length)// 也不要使用arg->sum += i;// 因为指针的读取比普通栈的读取需要多花费一些时间for (long long i = begin; i < end; ++i) {sum += i;}arg->sum = sum;
}@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// 计算1~count数列之和const long long count = 1000000000;// 单线程常用方法NSDate *commonMethodDate = [NSDate date];long long commonMethodSum = 0;for (long long i = 0; i < count; ++i) {commonMethodSum += i;}// 计算单线程使用时间double commonMethodDuration = [[NSDate date] timeIntervalSinceDate:commonMethodDate];NSLog(@"Common method spend time = %fms, sum = %lld", commonMethodDuration * 1000, commonMethodSum);// 并行计算方法// 将1~count数列平均分为threadCount组,求解每组数列之和,再将其相加得到总和NSDate *parallelMethodDate = [NSDate date];// 设置并行线程数目const int threadCount = 2;thread threads[threadCount];ThreadArg args[threadCount];// 初始化线程及其参数for (int i = 0; i < threadCount; ++i) {long long offset = (count / threadCount) * i;args[i].base = offset;args[i].length = MIN(count - offset, count / threadCount);threads[i] = thread(sum, &args[i]);}// 启动线程并等待线程退出for (int i = 0; i < threadCount; ++i) {threads[i].join();}long long parallelMethodSum = 0;// 将每组数列之和相加得到总和for (int i = 0; i < threadCount; ++i) {parallelMethodSum += args[i].sum;}// 计算多线程使用时间double parallelMethodDuration = [[NSDate date] timeIntervalSinceDate:parallelMethodDate];NSLog(@"Parallel method spend time = %fms, sum = %lld", parallelMethodDuration * 1000, parallelMethodSum);
}@end

0x02 - 结果分析


Xcode8.2.1+iPhone7模拟器+1~1000000000数列之和:

线程数目 2 4 8
多线程耗时 1921.253026ms 981.853008ms 684.603035ms
单线程耗时 3171.698034ms 3472.517014ms 3447.206974ms

Xcode8.2.1+iPhone7模拟器+1~10000数列之和:

线程数目 2 4 8
多线程耗时 0.279963ms 0.212014ms 0.297010ms
单线程耗时 0.038981ms 0.027955ms 0.032008ms

可见多线程本身也需要消耗一定的资源,所以只有在系统规模较大的情况下才能取得显著的性能提升。

0x03 - 注意事项


1. thread调用类的成员函数:

thread memberFuncThread(&ClassName::MemberFuncName, this, arg1, arg2...);

2. thread传递引用参数:

需要使用std::ref进行包装,详见thread - 传递引用参数。

转载于:https://www.cnblogs.com/polobymulberry/p/6262032.html

【原】C++11并行计算 — 数组求和相关推荐

  1. OpenCL 学习step by step (11) 数组求和(reduction)

    本篇教程中,我们学习一下如何用opencl有效实现数组求和,也就是通常所说的reduction问题. 在程序中,我们设置workgroup size为256,kernel的输入.输出缓冲参数都用uin ...

  2. 整数数组中最大子数组求和02

    设计思路: 在"整数数组中最大子数组求和01"的基础上完成本次实验. 本次实验的关键在于如何判断结束. 经设计,程序结束条件有两种:1.截取部分有重复:2.循环完整两次. 满足其中 ...

  3. java数组求和递归,js数组去重 数组拼接 替换数组中的指定值 递归数组 判断数组中是否存在指定值 数组求和 根据条件判数组值...

    // 数组去重 var arr1 = [1,1,2,3,4,5,6,3,2,4,5,'a','b','c','a',6,7,8,3,5,7,8,34] // console.log(Array.fro ...

  4. 11. 旋转数组的最小数字(剑指 Offer 题解Java版)

    文章目录 11. 旋转数组的最小数字 题目描述 题目链接 解题思路 可以借助下图理解过程 代码 11. 旋转数组的最小数字 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. ...

  5. 分治法之一维数组求和问题

    分治法的设计思想 分治者,分而治之也①.分治法(divide and conquer method)将一个难以直接解决的大问题划分成一些规模较小的子问题,分别求解各个子问题,再合并子问题的解得到原问题 ...

  6. java 数组怎么求和_java数组求和怎么解决?有哪些方式?

    Java经典题目之一,数组的各种求和,今天小编就用一些例子带大家了解一下其中详情. 基础求和#include using namespace std; //数组求和 //方法一:时间复杂度为O(n), ...

  7. 《LeetCode力扣练习》剑指 Offer 11. 旋转数组的最小数字 Java

    <LeetCode力扣练习>剑指 Offer 11. 旋转数组的最小数字 Java 一.资源 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 给你一个可能存在 ...

  8. python【蓝桥杯vip练习题库】ADV-303 数组求和

    试题 算法提高 数组求和 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输入n个数,围成一圈,求连续m(m<n)个数的和最大为多少? 输入格式 输入的第一行包含两个整数n, ...

  9. 剑指 Offer 11. 旋转数组的最小数字 简单

    剑指 Offer 11. 旋转数组的最小数字 题目 解题思路 方法(一)直接遍历法 方法(二)二分查找法 题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组 ...

最新文章

  1. python实现tcp发包_python 多线程tcp udp发包 Dos工具。
  2. Tomcat 系统架构
  3. 部署Oracle数据库
  4. 2020年12月份学习总结,PMP与信息系统项目管理师的回顾
  5. 如何能让mediawiki实现共享
  6. linux3.10修复i2c adapter无法使用dts创建device
  7. Java基础(一):简介和基础数据类型
  8. android 截图 tftp,TFTP全自动智能路由刷固件软件
  9. 开源开放|数据地平线通过OpenKG开放全行业因果事理、大规模实时事理等7类常识知识库...
  10. 【毕业设计】深度学习YOLO安检管制物品识别与检测 - python opencv
  11. 实力肯定!Coremail邮件网关荣获金融信创优秀解决方案奖
  12. 远程 PC 访问软件
  13. java得到选择的复选框_java怎么获取复选框的值_java学习记录20200817
  14. 解决‘parent.relativePath‘ of POM com.myfun:taskWeb:0.0.1-SNAPSHOT (D:\project wo
  15. 一款免杀远控,马子体积小
  16. 基于SSM实现的物流管理系统【附源码】(毕设)
  17. 高血压患者的饮食宜忌等
  18. 74HC595D介绍与实现(C语言与verilog实现)
  19. Android底层驱动开发(四)
  20. MS9132 USB 3.0转HDMI 输出投屏芯片

热门文章

  1. pytest框架快速入门-pytest运行时参数说明,pytest详解,pytest.ini详解
  2. 图书推荐系统(附源码链接)
  3. 解决Pixel手机时间不能自动同步
  4. 2020.03.18模拟赛17(第三题)
  5. 王道作业Python
  6. 浅谈HEVC中的CTU CU PU TU
  7. easyui combobox、validatebox、datebox必选、禁用、可用问题
  8. 从 .NET 开发人员的角度理解 Excel 对象模型 (From MSDN)
  9. python数据分析的四阶段以及电商数据描述性分析和探索性分析
  10. 爬虫信息后ocr识别