【C++】C++ 并行算法(Parallel Algorithms)介绍

C++ 并行算法:原理与实现

C++17 引入了 并行算法(Parallel Algorithms),通过在标准库算法中增加执行策略(Execution Policy),实现对多核处理器的自动并行化。


一、核心原理
  1. 执行策略(Execution Policy)

    • std::execution::seq:顺序执行(默认)
    • std::execution::par:并行执行(线程级并行)
    • std::execution::par_unseq:并行+向量化(线程级+指令级并行)
  2. 工作方式

    • 算法自动将数据分块
    • 线程池处理不同数据块
    • 结果合并(如 reduce
  3. 约束

    • 操作必须无数据竞争
    • 元素访问可并发
    • par_unseq 要求操作无同步操作

二、关键头文件
#include     // 标准算法
#include     // 执行策略
#include        // 容器
#include       // 数值算法

三、常用并行算法示例
1. 并行排序 (sort)
std::vector<int> data(1000000); // 大数据集

// 使用并行策略排序
std::sort(std::execution::par, data.begin(), data.end());
2. 并行变换 (transform)
std::vector<int> src(1000000, 1);
std::vector<int> dst(src.size());

// 并行处理:每个元素x2
std::transform(std::execution::par,
               src.begin(), src.end(),
               dst.begin(),
               [](int x) { return x * 2; });
3. 并行归约 (reduce)
std::vector<int> data(1000000, 2); // 全2

// 并行求和(比accumulate更高效)
int sum = std::reduce(std::execution::par, 
                      data.begin(), data.end());
// 结果:2000000
4. 并行遍历 (for_each)
std::vector<int> data(1000000);

// 并行初始化
std::for_each(std::execution::par,
              data.begin(), data.end(),
              [](int& x) { x = rand(); });
5. 并行计数 (count_if)
std::vector<int> data{1, 5, 3, 2, 4};

// 并行统计偶数个数
int count = std::count_if(std::execution::par,
                         data.begin(), data.end(),
                         [](int x) { return x % 2 == 0; });
// 结果:2

四、性能对比测试
#include 

auto test_performance() {
    std::vector<int> data(50'000'000, 1);

    // 顺序执行
    auto start_seq = std::chrono::high_resolution_clock::now();
    std::sort(std::execution::seq, data.begin(), data.end());
    auto end_seq = std::chrono::high_resolution_clock::now();

    // 并行执行
    auto start_par = std::chrono::high_resolution_clock::now();
    std::sort(std::execution::par, data.begin(), data.end());
    auto end_par = std::chrono::high_resolution_clock::now();

    return std::make_pair(
        end_seq - start_seq,
        end_par - start_par
    );
}
// 典型结果(8核CPU):并行比顺序快3-6倍

五、注意事项
  1. 线程安全

    // 错误!存在数据竞争
    int shared = 0;
    std::for_each(par, data.begin(), data.end(), [&](int) { shared++; });
    
    // 正确:使用原子操作
    std::atomic<int> safe_count(0);
    std::for_each(par, data.begin(), data.end(), [&](int) { safe_count++; });
    
  2. 异常处理

    • 并行算法中抛出未捕获异常会调用 std::terminate
  3. 编译器支持

    • GCC: 需链接 -ltbb (Intel TBB库)
    • MSVC: /std:c++17 或更高
    • Clang: 需支持C++17

六、底层机制
  1. 实现依赖

    • 通常基于 Intel TBB (Threading Building Blocks)
    • 编译器自动管理线程池
  2. 工作窃取(Work Stealing)

    • 空闲线程从其他线程"窃取"任务
    • 实现负载均衡

七、适用场景
  • 大数据集(>10,000元素)
  • 计算密集型操作
  • 独立元素处理(无数据依赖)

总结

C++并行算法通过简洁的接口实现高效并行:

  1. 添加执行策略参数(如 std::execution::par
  2. 保证操作无数据竞争
  3. 编译器自动处理线程管理
原始算法
添加执行策略
编译器生成并行代码
自动线程池管理
多核并行执行

合理使用并行算法,可在现代多核CPU上轻松获得3-10倍的性能提升!

你可能感兴趣的:(C++,c++,开发语言)