C++17 并行算法探究

C++17 终于把并行计算引入到了 STL,且更新成本极低,只是把 大多数迭代算法函数 多加了一个并行版本的重载,实现了并行、并发两个维度上的性能优化。

比如,对一组数据做一个加倍的 transform:

  • 串行版本,同以前:
    1
    std::transform(std::execution::seq, iter_begin, iter_end, output_iter, [](int val) { return val * 2; });
  • 并行版本,多以线程池方式实现:

    1
    std::transform(std::execution::par, iter_begin, iter_end, output_iter, [](int val) { return val * 2; });
  • 并行 + 并发版本,同时以线程池和 SIMD 相关方法实现:

    1
    std::transform(std::execution::par_unseq, iter_begin, iter_end, output_iter, [](int val) { return val * 2; });

单独的并发版本 std::execution::unseq 已经加入到 C++20 标准。

但是,C++17 并行算法离可实际应用还差了十万八千里。

首先,编译器实现进度不理想。LLVM 彻底没展开此项工作 ;MSVC 仅完成部分算法的并行实现,即 std::execution::par_unseqstd::execution::par 完全等效,还是个半成品,常用的如 replace_copy_if 甚至并行版本都没实现;三去其二,GCC 即便完全支持,对跨平台开发的意义也不是很大了。

其次,如前所述,单独的并发版本是在 C++20 标准化的。个人认为这个才是杀器,应用面最广。并行要考虑线程切换、共享数据加锁等等负面因素,对一些小而频繁的数据加工,甚至有副作用。比如,直播音效的实现,为了保证低延时根本不允许缓存大块数据后再处理。并发的应用粒度小得多,对直播等场景不会造成负面影响。这大概也是编译器厂商不是那么热心的缘故之一吧……

一句话总结,C++17 并行算法暂时没必要关注。

评论