【原】C++11并行计算 — 数组求和
- 时间:
- 浏览:0
- 来源:极速快3_快3倍率_极速快3倍率
本文转载请注明出处 —— 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 = 50000000000; // 单任务管理器常用最好的法律妙招 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 * 50000, 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 * 50000, parallelMethodSum); } @end
0x02 - 结果分析
Xcode8.2.1+苹果4 机手机7模拟器+1~50000000000数列之和:
任务管理器数目 | 2 | 4 | 8 |
多任务管理器耗时 | 1921.2550026ms | 981.855008ms | 684.50050035ms |
单任务管理器耗时 | 3171.6950034ms | 3472.517014ms | 3447.206974ms |
Xcode8.2.1+苹果4 机手机7模拟器+1~500000数列之和:
任务管理器数目 | 2 | 4 | 8 |
多任务管理器耗时 | 0.279963ms | 0.212014ms | 0.297010ms |
单任务管理器耗时 | 0.038981ms | 0.027955ms | 0.035008ms |
可见多任务管理器一种也须要消耗一定的资源,什么都都可以都可以 在系统规模较大的情况表下都可以取得显著的性能提升。
0x03 - 注意事项
1. thread调用类的成员函数:
thread memberFuncThread(&ClassName::MemberFuncName, this, arg1, arg2...);
2. thread传递引用参数:
须要使用std::ref进行包装,详见thread - 传递引用参数。