【原】C++11并行计算 — 数组求和
本文转载请注明出处 —— 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 - 传递引用参数。
【原】C++11并行计算 — 数组求和的更多相关文章
- Java并发和多线程2:3种方式实现数组求和
本篇演示3个数组求和的例子. 例子1:单线程例子2:多线程,同步求和(如果没有计算完成,会阻塞)例子3:多线程,异步求和(先累加已经完成的计算结果) 例子1-代码 package cn.fansuni ...
- JavaScript 系列--JavaScript一些奇淫技巧的实现方法(三)数字取整,数组求和
一.前言 简短的sleep函数,获取时间戳:https://www.mwcxs.top/page/746.html 数字格式化 1234567890 --> 1,234,567,890:argr ...
- js数组去重 数组拼接 替换数组中的指定值 递归数组 判断数组中是否存在指定值 数组求和 根据条件判数组值
这是学习过程中记录的一些关于数组操作的常用属性或方法,记录一下方便以后使用. // 数组去重 var arr1 = [1,1,2,3,4,5,6,3,2,4,5,'a','b','c','a',6,7 ...
- C# 使用SIMD向量类型加速浮点数组求和运算(1):使用Vector4、Vector<T>
作者: 目录 一.缘由 二.使用向量类型 2.1 基本算法 2.2 使用大小固定的向量(如 Vector4) 2.2.1 介绍 2.2.2 用Vector4编写浮点数组求和函数 2.3 使用大小与硬件 ...
- js数组求和
array1.reduce(callbackfn[, initialValue]) callback : 函数执行在数组中每个值 initialValue : 对象作为第一个参数回调的第一次调用使用 ...
- 《Intel汇编第5版》 数组求和
一.LOOP指令 二.间接寻址 三.汇编数组求和 INCLUDE Irvine32.inc includelib Irvine32.lib includelib kernel32.lib includ ...
- Javascript数组求和的方法总结 以及由斐波那契数列得到的启发
一次面试中,面试官要求用三种不同的Javascript方法进行一个数字数组的求和,当时思来想去只想到了使用循环这一种笨方法,因此面试比较失败,在这里总结了六种Javascript进行数组求和的方法,以 ...
- [java大数据面试] 2018年4月百度面试经过+三面算法题:给定一个数组,求和为定值的所有组合.
给定一个数组,求和为定值的所有组合, 这道算法题在leetcode应该算是中等偏下难度, 对三到五年工作经验主要做业务开发的同学来说, 一般较难的也就是这种程度了. 简述经过: 不算hr面,总计四面, ...
- 个人项目-数组求和(语言:C++)
prog1详细要求: [第一版本程序Prog1要求:] + 给定一个数组,实现数组元素求和:,具体要求:实现对一维数组(a[100])的所有元素相加运算. + 数据准备:a)数组长度:100:b)数组 ...
随机推荐
- hdu 6058 Kanade's sum(模拟链表)
Kanade's sum Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- springboot jpa 批量保存数据--EntityManager和 JpaRepository
1: 项目里面使用springboo-boot-start-data-jpa操作数据库,通过源码,在repository上继承JpaRepository 可以实现保存操作,其中源码接口为: <S ...
- qml 知识积累
本文仅仅只是记录,怕日后遗忘. ListView相关应用 https://www.cnblogs.com/SaveDictator/p/8192391.html ListView 清空操作 https ...
- UITextField 限制用户输入小数点后位数的方法
UITextField 限制用户输入小数点后位数的方法 位数限制: limited 在UITextField的代理方法中添加类似如下代码 - (BOOL)textField:(UITextField ...
- LeetCode之Regular Expression Matching
[题目描述] Implement regular expression matching with support for '.' and '*'. '.' Matches any single ch ...
- New Concept English there (1)Typing speed exercise
Today,I start learn new concept english there,Mainly for listening practice and typing speed exercis ...
- Shell 命令行统计 apache 网站日志访问IP以及IP归属地
Shell 命令行统计 apache 网站日志访问IP以及IP归属地 我的一个站点用 apache 服务跑着,积攒了很多的日志.我想用 shell 看看有哪些人访问过我的站点,并且他来自哪里. 因为日 ...
- Android gradle 安装成功,但是报虚拟机过大的错误处理方法
一.这个是项目中遇到的问题,记下来,以后再出现方便查看. 1.首先看图吧. 虚拟机内容过大 解决办法: 在.gradle目录下更改配置文件gradle.properjties 里面的 将标记的改成51 ...
- 在ROS Kinetic和Gazebo 8中使用智能汽车仿真演示
在ROS Kinetic和Gazebo 8中使用智能汽车仿真演示 智能车无人驾驶技术是目前人工智能和机器人技术的研究热点,有许多开源平台可以使我们零基础零成本入门无人驾驶技术.本文分享一下目前ROS官 ...
- Leetcode 814. Binary Tree Pruning
dfs 要点是这一句: return node.val==1 or node.left or node.right 完整代码: # Definition for a binary tree node. ...