Skip to content

Intel TBB — 并行框架

Intel Threading Building Blocks(oneTBB)是工业级 C++ 并行编程框架,提供并行算法、并发容器、任务调度,让多核利用变得简单。

安装

bash
# Ubuntu
sudo apt install libtbb-dev

# vcpkg
vcpkg install tbb

# CMake
find_package(TBB REQUIRED)
target_link_libraries(myapp PRIVATE TBB::tbb)

并行算法

cpp
#include <tbb/tbb.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_reduce.h>
#include <tbb/parallel_sort.h>
#include <vector>

// parallel_for:并行循环
std::vector<double> data(1000000);
tbb::parallel_for(
    tbb::blocked_range<size_t>(0, data.size()),
    [&](const tbb::blocked_range<size_t>& r) {
        for (size_t i = r.begin(); i < r.end(); ++i) {
            data[i] = std::sqrt(i * 3.14159);
        }
    }
);

// 简化写法(C++11 range-based)
tbb::parallel_for(size_t(0), data.size(), [&](size_t i) {
    data[i] = std::sqrt(i * 3.14159);
});

// parallel_reduce:并行归约
double sum = tbb::parallel_reduce(
    tbb::blocked_range<size_t>(0, data.size()),
    0.0,  // 初始值
    [&](const tbb::blocked_range<size_t>& r, double init) {
        for (size_t i = r.begin(); i < r.end(); ++i) {
            init += data[i];
        }
        return init;
    },
    std::plus<double>{}  // 合并函数
);

// parallel_sort:并行排序(比 std::sort 快 2-4x)
tbb::parallel_sort(data.begin(), data.end());
tbb::parallel_sort(data.begin(), data.end(), std::greater<double>{});

并行流水线

cpp
#include <tbb/pipeline.h>

// 三阶段流水线:读取 → 处理 → 写入
tbb::parallel_pipeline(
    /*max_tokens=*/16,

    // 阶段 1:串行输入(生产者)
    tbb::make_filter<void, std::string>(
        tbb::filter_mode::serial_in_order,
        [&](tbb::flow_control& fc) -> std::string {
            if (input_exhausted) {
                fc.stop();
                return {};
            }
            return read_next_line();
        }
    ) &

    // 阶段 2:并行处理
    tbb::make_filter<std::string, ProcessedData>(
        tbb::filter_mode::parallel,
        [](const std::string& line) -> ProcessedData {
            return process(line);  // CPU 密集型,并行执行
        }
    ) &

    // 阶段 3:串行输出(消费者)
    tbb::make_filter<ProcessedData, void>(
        tbb::filter_mode::serial_in_order,
        [&](const ProcessedData& data) {
            write_result(data);
        }
    )
);

并发容器

cpp
#include <tbb/concurrent_vector.h>
#include <tbb/concurrent_hash_map.h>
#include <tbb/concurrent_queue.h>

// concurrent_vector:线程安全的动态数组
tbb::concurrent_vector<int> cv;
tbb::parallel_for(0, 1000, [&](int i) {
    cv.push_back(i);  // 线程安全
});

// concurrent_hash_map:线程安全哈希表
tbb::concurrent_hash_map<std::string, int> chm;

// 写操作
{
    tbb::concurrent_hash_map<std::string, int>::accessor acc;
    chm.insert(acc, "key");
    acc->second = 42;
}

// 读操作
{
    tbb::concurrent_hash_map<std::string, int>::const_accessor acc;
    if (chm.find(acc, "key")) {
        std::cout << acc->second << "\n";
    }
}

// concurrent_queue:线程安全队列
tbb::concurrent_queue<int> cq;
cq.push(42);
int val;
if (cq.try_pop(val)) {
    std::cout << val << "\n";
}

// concurrent_bounded_queue:有界队列(阻塞)
tbb::concurrent_bounded_queue<int> cbq;
cbq.set_capacity(100);
cbq.push(42);  // 满时阻塞
cbq.pop(val);  // 空时阻塞

任务调度

cpp
#include <tbb/task_group.h>

// task_group:并发执行多个任务
tbb::task_group tg;

tg.run([] { compute_part1(); });
tg.run([] { compute_part2(); });
tg.run([] { compute_part3(); });

tg.wait();  // 等待所有任务完成

// 嵌套并行(自动负载均衡)
tbb::parallel_for(0, 100, [](int i) {
    tbb::parallel_for(0, 100, [i](int j) {
        process(i, j);
    });
});

性能调优

cpp
// 控制线程数
tbb::global_control gc(
    tbb::global_control::max_allowed_parallelism, 4);  // 最多 4 线程

// 分区策略
// auto_partitioner(默认):自动调整粒度
// simple_partitioner:固定粒度
// static_partitioner:静态分配,无负载均衡

tbb::parallel_for(
    tbb::blocked_range<size_t>(0, n, /*grain_size=*/1000),
    [&](const tbb::blocked_range<size_t>& r) { /* ... */ },
    tbb::simple_partitioner{}
);

// 亲和性分区(NUMA 优化)
tbb::affinity_partitioner ap;
for (int iter = 0; iter < 100; ++iter) {
    tbb::parallel_for(range, body, ap);  // 复用上次的线程分配
}

关键认知

TBB 的核心是工作窃取调度器,自动负载均衡,无需手动管理线程。parallel_for + parallel_reduce 覆盖 80% 的并行场景。并发容器比手动加锁的 STL 容器性能更好。affinity_partitioner 在循环迭代中复用线程亲和性,对缓存友好的算法有显著提升。

系统学习 C++ 生态,深入底层架构