std算法和副作用的并行实现
Parallel implementations of std algorithms and side effects
在阅读std::transform
的标准文档时,我注意到在C++11之前,函子参数被要求没有副作用,而从C++11开始,该要求的限制性降低了——"op和binary_op不得使迭代器或子范围无效,也不得修改范围中的元素"。参见
http://en.cppreference.com/w/cpp/algorithm/transform
以及本标准第25.3.4节。cppreference.com上的网页也提到,"这些要求的目的是允许并行或无序实现std::transform
"。
我不明白这段代码在C++11:中是否合法
std::vector<int> v(/* fill it with something */), v_transformed;
int foo = 0;
std::transform(v.begin(),v.end(),std::back_inserter(v_transformed),[&foo](const int &n) -> int {
foo += 1;
return n*2;
});
显然,如果std::transform
在后台被并行化,我们将有多个对foo += 1
的并发调用,这将是UB。但函子本身似乎并没有违反标准中列出的要求。
其他标准算法也可以问这个问题(我认为std::for_each
除外,它明确表示迭代要按顺序执行)。
我误解什么了吗?
就我对C++11规范的理解而言,所有标准库函数都必须按顺序执行所有操作,前提是它们的效果对用户可见。特别是,所有"突变序列操作"都必须按顺序执行。
该标准的相关部分为§17.6.5.9/8:
除非另有规定,否则C++标准库函数应仅在当前线程内执行所有操作,前提是这些操作的效果对用户可见(1.10)。
当前定义算法的方式必须按顺序执行,除非实现能够证明并行执行不会改变语义。我可以想象未来会添加明确允许并发执行的算法,但它们将是不同的算法。
因此,C++11现在允许std::transform
进行并行化,但这并不能保证您自己的代码可以安全地进行并行化。现在,是的,我想你必须保护你的数据变量。如果实现真的将std::transform
并行化,我可以想象会有很多MT错误由此产生。
- 如何使用 winsock2 实现与 c++ 的多个并行连接?
- C++如何正确实现并行IF流读取
- 使用openmp实现并行广度优先搜索
- C++17 并行算法已经实现了吗?
- 将执行从一个线程移动到另一个线程,以实现任务并行性并在将来调用
- 在C++中使用OpenMP实现递归函数的并行化
- 串行代码的并行MPI实现
- std算法和副作用的并行实现
- std::async 使用相同的线程,我的代码没有实现并行性
- 如何实现mysql的DISTINCT关键字,使用线程并行获取不同的值
- 什么样的数据结构可以实现并行处理
- 用openmp实现循环并行化的嵌套c++
- c++ 17并行硬件实现
- 如何在一个套接字上实现并行请求和响应的非阻塞客户端-服务器通信模型,而不存在数据竞争
- 如何使用OpenMP / MPI实现并行Dijkstra算法
- 用特征c++实现Jacobi算法的并行化
- 并行线程执行以实现性能
- 英特尔TBB concurrent_queue是如何工作的?它是否实现了细粒度的并行性
- 实现并行异常以获得错误树
- 在c++中并行实现lisp风格的函数到列表的映射,在使用线程后没有cout就会失败