超高速である必要があるプログラムを作成しています。CUDA を使用して GPU でいくつかのことを実行してから、CPU でいくつかの計算を行います。このためには、高度に最適化された GPU データ構造を、CPU で簡単に使用できるものに変換する必要があります。私のデータは基本的に、グリッドに配置されたグラフです。現在、CPU 部分に std::vector を使用しています。多くの 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 でアルゴリズムを実行するよりも 10 倍遅くなります (これはスマート MST アルゴリズムです)。オーバーヘッドが大きすぎるため、これは私が望んでいるものではありません。
誰かが何が起こっているのか、またはこれを修正する方法を知っていますか?
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;
};