并行性能不佳的原因是什么?
What is the reason of bad parallel performance?
我正在尝试实现并行算法,该算法将计算列表中每个序列之间的Levenshtein距离并将它们存储在矩阵(2d向量(中。换句话说,我得到了带有数字的 2d 向量(数千个数字序列,最多 30 个数字(,我需要计算每个整数向量之间的 Levenshtein 距离。我实现了有效的串行算法,但是当我尝试将其转换为并行时,它的速度要慢得多(线程越多,速度越慢(。并行版本是用 c++11 线程实现的(我也尝试过 OpenMP,但结果相同(。
以下是分配工作的函数:
vector<vector<int>> getGraphParallel(vector<vector<int>>& records){
int V = records.size();
auto threadCount = std::thread::hardware_concurrency();
if(threadCount == 0){
threadCount = 1;
}
vector<future<vector<vector<int>>>> futures;
int rowCount = V / threadCount;
vector<vector<int>>::const_iterator first = records.begin();
vector<vector<int>>::const_iterator last = records.begin() + V;
for(int i = 0; i < threadCount; i++){
int start = i * rowCount;
if(i == threadCount - 1){
rowCount += V % threadCount;
}
futures.push_back(std::async(getRows, std::ref(records), start, rowCount, V));
}
vector<vector<int>> graph;
for(int i = 0; i < futures.size(); i++){
auto result = futures[i].get();
for(const auto &row : result){
graph.push_back(row);
}
}
for(int i = 0; i < V; i++)
{
for(int j = i + 1; j < V; j++){
graph[j][i] = graph[i][j];
}
}
return graph;
}
以下是计算最终矩阵行的函数:
vector<vector<int>> getRows(vector<vector<int>>& records, int from, int count, int size){
vector<vector<int>> result(count, vector<int>(size, 0));
for(int i = 0; i < count; i++){
for(int j = i + from + 1; j < size; j++){
result[i][j] = levenshteinDistance(records[i + from], records[j]);
}
}
return result;
}
最后是计算列文施泰因距离的函数:
int levenshteinDistance(const vector<int>& first, const vector<int>& second){
const int sizeFirst = first.size();
const int sizeSecond = second.size();
if(sizeFirst == 0) return sizeSecond;
if(sizeSecond == 0) return sizeFirst;
vector<vector<int>> distances(sizeFirst + 1, vector<int>(sizeSecond + 1, 0));
for(int i = 0; i <= sizeFirst; i++){
distances[i][0] = i;
}
for(int j = 0; j <= sizeSecond; j++){
distances[0][j] = j;
}
for (int j = 1; j <= sizeSecond; j++)
for (int i = 1; i <= sizeFirst; i++)
if (first[i - 1] == second[j - 1])
distances[i][j] = distances[i - 1][j - 1];
else
distances[i][j] = min(min(
distances[i - 1][j] + 1,
distances[i][j - 1] + 1),
distances[i - 1][j - 1] + 1
);
return distances[sizeFirst][sizeSecond];
}
我想到的一件事是,这种减速是由错误共享引起的,但我无法使用 perf 检查它,因为我正在 Oracle VirtualBox 中使用 Ubuntu - 缓存未命中在那里不可用。如果我是对的,并且速度减慢是由错误共享引起的,我应该怎么做才能解决它?如果不是,这种减速的原因是什么?
我可以看到的一个问题是您在使用std::async
时没有声明它应该如何运行。它可以异步运行,也可以延迟运行。在延迟的情况下,它将全部在一个线程中运行,它只是被懒惰地计算。默认行为是实现定义的。对于您的情况,如果延迟评估更多,它的运行速度会变慢是有道理的。您可以尝试std::async(std::launch::async, ...)
。
确保 VM 也设置为使用多个核心。理想情况下,在进行此类优化时,最好尝试消除尽可能多的变量。如果可以,请在没有 VM 的情况下在本地运行程序。分析工具是您最好的选择,它将准确显示时间花费在哪里。
相关文章:
- 并行性能不佳的原因是什么?
- 是什么让这种易失性打破了结构的指针算法?
- Haskell中用多态性替换条件的等效模式是什么?
- 在C++中将已签名/未签名的警告静音的侵入性最小的方法是什么?
- 访问说明符不会更改可访问性级别.这是什么意思
- java.io.Serializable 的 C/C++ 等价性是什么?
- 在这种情况下,从左到右的结合性是什么意思
- 并行化的最佳方法是什么
- 检查并集实例之间相等性的正确方法是什么
- 静态多态性中的纯抽象函数等价物是什么
- static_cast<T* 易失性*> - 此代码是什么意思?
- python中cin.ignore()的等价性是什么?
- 什么是易失性复制构造函数
- C++静态多态性背后的动机是什么?
- C++线程与可见性问题 - 常见的工程实践是什么?
- Boost 测试框架与 std::cout 的等效性是什么?
- QNetworkAccessManager中的并行机制是什么
- 在c++中使用多态性和继承来处理一篮子水果的正确方法是什么?
- 使用abi遵从性检查器时出现错误的原因是什么?
- 种子并行伪随机数生成器的好方法是什么?