我试图使用Intel TBB并行一个内循环(3中的第二个),但是,只有当内部2个循环的大小很大时,我才能获得可观的回报。
TBB是否为主循环的每一次迭代生成新线程?有减少开销的办法吗?
tbb::task_scheduler_init tbb_init(4); //I have 4 cores
tbb::blocked_range<size_t> blk_rng(0, crs_.y_sz, crs_.y_sz/4);
boost::chrono::system_clock::time_point start =boost::chrono::system_clock::now();
for(unsigned i=0; i!=5000; ++i)
{
tbb::parallel_for(blk_rng,
[&](const tbb::blocked_range<size_t>& br)->void
{
:::值得注意的是,openMP (我正在尝试删除的!)没有这个问题。
我正在编制下列文件:
英特尔ICC 12.1 at -03 -xHost -mavx
在英特尔2500 K (4核)上
编辑:我真的可以改变循环的顺序,因为out循环测试需要替换为基于循环结果的谓词。
发布于 2012-02-16 12:13:31
不,TBB不会为每次调用parallel_for生成新线程。实际上,与OpenMP并行区域(每个区域可能启动一个新线程组)不同,TBB在销毁所有task_scheduler_init对象之前使用同一个线程组;在隐式初始化(省略task_scheduler_init )的情况下,在程序结束之前使用相同的工作线程。
因此,性能问题是由其他原因引起的。根据我的经验,最可能的原因是:
schedule(static)工作非常好,每一次精确地重复相同的分区,而TBB的工作窃取调度程序具有很大的随机性。将blocked_range粒度设置为problem_ size /num_线程可以确保每个线程只做一件工作,但并不保证工件的分布相同;affinity_partitioner应该在这方面有所帮助。https://stackoverflow.com/questions/9299474
复制相似问题