本文轉載請註明出處 —— polobymulberry-博客園html
在選擇並行編程的工具時,須要考慮如下問題:即該工具儘可能不要使用與平臺相關的API,如iOS端的GCD(Grand Central Dispatch),由於但願程序具備很強的移植性。一開始我想到的只有兩種選擇,一個是以TBB和OpenMP爲首的第三方線程庫,另外一個是原生線程庫。其中TBB和OpenMP對於Xcode的支持不是很好,原生線程庫又依賴於系統平臺,因此嘗試後都放棄了。後來想到C++11已經從語言層面支持了多線程開發,也就是提供了thread庫,因而抱着試一試學一學的態度就入坑了。ios
並行計算中一個很經典的案例就是數組求和,網絡上有不少介紹C++11的thread使用、源碼分析的文章,不過使用C++11進行數組求和並行計算的示例卻不多,因此纔有了這篇博文。編程
在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
線程數目 | 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 |
thread memberFuncThread(&ClassName::MemberFuncName, this, arg1, arg2...);
2. thread傳遞引用參數:多線程
須要使用std::ref進行包裝,詳見thread - 傳遞引用參數。函數