我决定编写一个算法来利用并行聚合。这是我要转换的单线程代码。
vector<vector<double>> sum;
for (const auto* fold : _obj.GetFolds())
sum.push_back(move(vector<double>(fold->GetSize())));
for (int index : sequence)
{
vector<vector<double>> values = Calculate(vec1[index], vec2[index]);
for (int i = 0; i < sum.size(); i++)
{
for (int j = 0; j < sum[i].size(); j++)
sum[i][j] += values[i][j];
}
}
我查看了 MSDN 页面http://msdn.microsoft.com/en-us/library/gg663540.aspx,其中涵盖了可组合的 parallel_for,以及http://msdn.microsoft.com/en-us/library/dd470426。 aspx#map_reduce_example显示了带有 parallel_reduce 的 parallel_transform,但它们是只有一个计数器的简单示例。
vector<int> sequence = ...
combinable<int> count([]() { return 0; });
parallel_for_each(sequence.cbegin(), sequence.cend(),
[&count](int i)
{
count.local() += IsPrime(i) ? 1 : 0;
});
return count.combine(plus<int>());
vector<vector<double>> sum
如上所述,我很难找到将与并行循环聚合的示例。
另外,我正在寻找有关是否使用parallel_for 和combinable 或parallel_transform 与parallel_reduce 的建议?上面的第一个链接指出:
当您需要在使用 PPL 的应用程序中应用并行聚合模式时,通常推荐使用 parallel_reduce 函数。它的声明性使其比其他方法更不容易出错,并且它在多核计算机上的性能可以与它们竞争。使用 parallel_reduce 实现并行聚合不需要在代码中添加锁。相反,所有同步都发生在内部。当然,如果parallel_reduce 不能满足您的需求,或者您更喜欢声明性较少的编码风格,您也可以使用可组合类与parallel_for 或parallel_for_each 来实现并行聚合。
您应该知道,parallel_for 和 parallel_for_each 会增加开销,因为它们支持取消和动态范围窃取等功能。此外,在并行循环内调用 combinable::local() 方法会为循环的每次迭代增加哈希表查找的成本。通常,当迭代执行复杂计算时,使用并行聚合来提高性能。
谢谢。