由于实用需要,实现一个跨平台的多线程并行库,摆脱windows的ppl,并且兼顾效率和跨平台性,特点如下:
- 采用C++11跨平台,调度性能和windows ppl库相近;
- 使用了其他大神的 线程池代码,实现线程高效复用;
- 支持STL容器、C数组、指针多种方式传递容器目标对象做并行;
- 代码可自行完善功能;
先看测试结果:
- 测试所用的执行函数体执行时间极端
{ i += 1;}
,目的是,测试比较多线程的调度性能; - 由于数据量不大,主执行过程短,且windows平台VC编译器对串行有优化,所有串行的速度还是很快(不过没有可比性);
- 对于连续空间排列容器(数组、vector)代码执行效率比windows PPL库略慢一些,不过调度效率尚可;
- 对于非连续空间容器(本例采用unordered_map)代码执行效率比windows PPL库快一些;
- 综合来说,若兼顾性能和考虑跨平台,代码效率还算是达标的。
下面是并发执行效果:(指定并发30个任务,实现了并行)
(指定cpu硬件核心线程数个并发任务,也实现了并行)
并行过程cpu出现极高峰值段(并行实现)
测试代码:
int main(){
std::mutex cs;
const int sii = 50000;
const int cycle = 5000;
int con[sii] = {
2 };
vector<int> con2(sii, 2);
unordered_map<int, int> con3;
map<int, int> con4;
for (int i = 0; i < sii; ++i)con3[i] = 2, con4[i] = 2;
auto incre = [&](int& i) {
i += 1; };
auto ttt0 = clock();
for (size_t i = 0; i < cycle; i++)
for (size_t j = 0; j < sii; j++)
incre(con[j]);
auto ttt1 = (clock() - ttt0) / double(CLOCKS_PER_SEC); ttt0 = clock();
for (size_t i = 0; i < cycle; i++)
parallel(&con[0],0, sii, incre); //传首指针
auto ttt2 = (clock() - ttt0) / double(CLOCKS_PER_SEC);
ttt0 = clock();
for (size_t i = 0; i < cycle; i++)
parallel_iter(con2.begin(), con2.end(), incre);
auto ttt3 = (clock() - ttt0) / double(CLOCKS_PER_SEC); ttt0 = clock();
for (size_t i = 0; i < cycle; i++)
concurrency::parallel_for_each(con2.begin(), con2.end(), incre);
auto ttt6 = (clock() - ttt0) / double(CLOCKS_PER_SEC); ttt0 = clock();
for (size_t i = 0; i < cycle; i++)
parallel_iter(con3.begin(), con3.end(), [](pair<const int, int>& i) {
i.second += 1; });
auto ttt4 = (clock() - ttt0) / double(CLOCKS_PER_SEC); ttt0 = clock();
for (size_t i = 0; i < cycle; i++)
concurrency::parallel_for_each(con3.begin(), con3.end(), [](pair<const int, int>& i) {
i.second += 1; });
auto ttt5 = (clock() - ttt0) / double(CLOCKS_PER_SEC); ttt0 = clock();
for (size_t i = 0; i < cycle; i++)
parallel_iter(con4.begin(), con4.end(), [](pair<const int, int>& i) {
i.second += 1; });
auto ttt7 = (clock() - ttt0) / double(CLOCKS_PER_SEC); ttt0 = clock();
for (size_t i = 0; i < cycle; i++)
concurrency::parallel_for_each(con4.begin(), con4.end(), [](pair<const int, int>& i) {
i.second += 1; });
auto ttt8 = (clock() - ttt0) / double(CLOCKS_PER_SEC); ttt0 = clock();
cout << "\n[ 数据量 " << sii << " ][ 循环次数 " << cycle << " ] -> 执行时间统计 ---------------"
<< endl << "串行 : " << ttt1 << " 秒"
<< endl << "数组 : " << ttt2 << " 秒"
<< endl << "vector : " << ttt3 << " 秒"
<< endl << "vector (Win PPL) : " << ttt6 << " 秒"
<< endl << "unordered_map : " << ttt4 << " 秒"
<< endl << "unordered_map(Win PPL) : " << ttt5 << " 秒"
<< endl << "map : " << ttt7 << " 秒"
<< endl << "map (Win PPL) : " << ttt8 << " 秒";
size_t tCounts2 = 30;