我正在创建一个需要超快的程序。它使用 CUDA 在 GPU 上运行一些东西,然后在 CPU 上进行一些计算。为此,我需要将高度优化的 GPU 数据结构转换为我可以在 CPU 上轻松使用的东西。我的数据基本上是一个以网格布局的图表。目前我正在使用 std::vector 作为 CPU 部分。因为我知道如果我做很多 s 会有相当大的开销,push_back()
而且我至少知道因为我知道我的图中有多少个顶点,所以我现在为此使用以下代码:
new_graph.resize(blockSize * blockSize);
for (unsigned long long y = 0; y < blockSize; y++) {
for (unsigned long long x = 0; x < blockSize; x++) {
int idx = y * blockSize + x;
new_graph[idx] = Vertex(x, y);
}
}
之后我添加边缘。不幸的是,我不知道每个顶点有多少条边,但我知道它永远不会大于 8。因此,我reserve()
在每个用于边的 std::vector 中都有 8 个。
但是,这两者似乎都非常缓慢。如果我对图形本身使用普通数组(所以基本上替换了外部 std::vector),那部分的速度提升是巨大的(比如 10 倍左右)。
对于图形这是可行的,但对于边缘不是真的,因为我在这些边缘上做了一些后处理,为此我真的需要像 std::vector 这样有点动态的东西(我添加了一些边缘)。
目前将数据转换为 std::vector 的速度比在 GPU 上运行我的算法(这是一种智能 MST 算法)慢 10 倍。这不是我真正想要的,因为现在开销太大了。
有人知道发生了什么或我该如何解决这个问题?
ps 我用-O2 编译,因为我已经发现这会产生很大的不同。也尝试使用-O3,没有真正的区别。
顶点定义如下:
struct Pos {
int x, y;
Pos() {
x = 0;
y = 0;
}
Pos(int x, int y) {
this->x = x;
this->y = y;
}
};
struct Vertex {
Pos pos;
bool hidden;
unsigned long long newIdx;
Vertex() {
this->pos = Pos();
this->hidden = false;
this->numEdges = 0;
this->numRemovedEdges = 0;
}
Vertex(Pos &pos) {
this->pos = pos;
this->hidden = false;
this->numEdges = 0;
this->numRemovedEdges = 0;
}
Vertex(int x, int y) {
this->pos = Pos(x, y);
this->hidden = false;
this->numEdges = 0;
this->numRemovedEdges = 0;
}
int numEdges;
int numRemovedEdges;
std::vector<Edge> edges;
std::vector<bool> removed;
std::vector<bool> doNotWrite;
};