我试图想出一个使用 OpenMP的英特尔 TBBparallel_for
循环的等效替代品。tbb::blocked_range
在网上搜索,我只找到提到另一个人在做类似的事情;提交给 Open Cascade 项目的补丁,其中 TBB 循环如此出现(但未使用 tbb::blocked_range):
tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);
OpenMP 等价物是:
int i, n = aFaces.size();
#pragma omp parallel for private(i)
for (i = 0; i < n; ++i)
Process (aFaces[i]);
这是我要替换的 TBB 循环:
tbb::parallel_for( tbb::blocked_range<size_t>( 0, targetList.size() ), DoStuff( targetList, data, vec, ptr ) );
它使用DoStuff
类来执行工作:
class DoStuff
{
private:
List& targetList;
Data* data;
vector<things>& vec;
Worker* ptr;
public:
DoIdentifyTargets( List& pass_targetList,
Data* pass_data,
vector<things>& pass_vec,
Worker* pass_worker)
: targetList(pass_targetList), data(pass_data), vecs(pass_vec), ptr(pass_worker)
{
}
void operator() ( const tbb::blocked_range<size_t> range ) const
{
for ( size_t idx = range.begin(); idx != range.end(); ++idx )
{
ptr->PerformWork(&targetList[idx], data->getData(), &Vec);
}
}
};
我基于this reference的理解是,TBB会将阻塞范围划分为更小的子集,并为每个线程提供一个循环范围。因为每个线程都会有自己的DoStuff
类,它有一堆引用和指针,这意味着线程本质上是共享这些资源的。
这是我在 OpenMP 中提出的等效替代方案:
int index = 0;
#pragma omp parallel for private(index)
for (index = 0; index < targetList.size(); ++index)
{
ptr->PerformWork(&targetList[index], data->getData(), &Vec);
}
由于我无法控制的情况(这只是跨越 +5 台计算机的更大系统中的一个组件),使用调试器单步执行代码以查看到底发生了什么......不太可能。我正在努力进行远程调试,但看起来并不是很有希望。我所知道的是,上面的 OpenMP 代码在某种程度上做的事情与 TBB 不同,并且在为每个索引调用 PerformWork 后没有获得预期的结果。
鉴于上述信息,是否有人对为什么 OpenMP 和 TBB 代码在功能上不等效有任何想法?