C++ Parallel STL

考虑一个算法,代码如下:

#include <algorithm>

void process(int& x){
    //do some calculate
}

int main()
{
    int arr[100000];
    std::for_each( arr, arr+100000, [](auto & x){ process(x); });
}

for_each对于每一个数组arr的成员,都去调用了process(int& x)。这个过程是单线程(main所在的主线程)进行的。

如果想增加性能,让多线程并行的处理,需要做一些改造。例如,创建线程1处理0-30000项,创建线程2处理30001-60000项,主线程处理剩余项。

在C++17中,可以请求算法库做并行处理。怎么请求呢?代码如下:

#include <execution>
//...
int main(){
    int arr[100000];
    std::for_each( std::execution::par, arr, arr+10000, [](auto & x){ process(x); });
}

新的重载函数多出了个指定策略的参数std::execution::par。这个参数意味着算法库可能会偷偷的创建后台线程辅助完成for_each算法。

另外还有std::execution::seq,和std::execution::par_unseq。这些都是算法库预定义的常量。

因为标准库算法都会涉及到对容器和元素的读写操作,在多线程条件下,就会有数据竞争问题。数据竞争的解决,是库的用户责任。这意味着有时候就需要用互斥量,内存模型等机制保护数据的完整性。

例如:下面这段代码,程序可能要挂掉了。在多线程环境下,对共享的资源v的插入会出现不可预知的错误。

int a[] = {0,1,3,4,5,6,7,8,9};
std::vector<int> v;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
  v.push_back(i*2+1); // 错误:数据竞争
});

最直接的解决方式,加锁保护,代码如下:

int a[] = {0,1,3,4,5,6,7,8,9};

std::vector<int> v;
std::mutex m;

std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
  std::lock_guard<std::mutex> guard(m);  //互斥量保护v
  v.push_back(i*2+1); 
});
  

有三种并行策略,各个含义如下:

std::execution::seq
调用者线程单线程方式,以不确定的顺序访问元素
std::execution::par
多线程(由库隐式的创建线程)方式,在每个线程中,以不确定的顺序访问元素
std::execution::par_unseq
multiple threads and may be vectorized - calls are unsequenced with respect to each other and possibly interleaved

我完全没懂,需要再研究。什么是“不确定顺序的“(indeterminately sequenced)?什么是“向量化的”(vectorized)?什么是交互的“interleaved”?都是什么鬼?

转载于:https://www.cnblogs.com/thomas76/p/8554668.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值