TBB 的特殊性
本文的法则是以线程为调度单位的。
如果你使用的是 TBB ,那么请将 “线程” 对应为 “任务”,而将本文的“任务” 对应为“载荷”( payloads)。
因为 TBB 是以任务为调度单位的:
- 每个 “任务” 是并发运行的最小单位,必须保证数据独立或线程安全。
- TBB 采用 “任务窃取” 算法来保证线程的复杂均衡,所以若干任务可能被同一线程或不同线程运行。
经验法则
以 tasksPerThread 按需分配线程
- tasksPerThread:均匀性。如果每个线程分配的任务数不均匀,那么任务数最多的线程就会成为瓶颈。
- 按需分配线程:如果任务可以很快完成,那么没有必要开启过多的线程,否则调度开销也不可小觑。
以空间换时间
为了任务能并发运行,进行任务分隔时,必须尽可能减少数据共享。
所以不要吝惜空间,为每个任务单独开辟内存(不论是为输入还是输出目的)都是值得且必要的。
长临界区使用 lock + 条件变量
如果一个任务的临界区比较大,意味着该任务执行时,其他线程在短时间内无法进入临界区。
与其让这些线程忙等,不如释放 CPU 进入阻塞 / 休眠。