Estoy creando un programa que necesita ser ultrarrápido. Está ejecutando algunas cosas en la GPU usando CUDA y luego hace algunos cálculos en la CPU. Para esto, necesito convertir la estructura de GPU altamente optimizada a algo que pueda usar fácilmente en la CPU. Mi información es básicamente un gráfico presentado en una grilla. Actualmente estoy usando std :: vector para la parte de la CPU. Porque sé que es toda una sobrecarga si hago un montón de push_back()
s y yo al menos sé porque sé cuántos vértices que tengo en la gráfica, ahora uso el siguiente código para esto:std :: vector vs normal array
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);
}
}
Después Agrego los bordes. Lamentablemente, no sé cuántos bordes por vértice tengo, pero sí sé que nunca será mayor que 8. Por lo tanto, I reserve()
8 en cada estándar :: vector que utilizo para los bordes.
Sin embargo, ambos parecen ser extremadamente lentos. Si utilizo una matriz normal para el gráfico en sí (básicamente, reemplazando el std :: vector externo), la mejora de velocidad en esa parte es enorme (como 10x más o menos).
Para el gráfico esto es factible, pero en realidad para los bordes no, porque hago algo de postprocesamiento en estos bordes y para esto realmente necesito algo como std :: vector, que es algo dinámico (agrego algunos bordes) .
Actualmente, convertir los datos a std :: vector es algo así como 10 veces más lento que ejecutar mi algoritmo en la GPU (que es un algoritmo MST inteligente). Esto no es realmente lo que quiero, porque ahora los gastos generales son demasiado grandes.
¿Alguien sabe lo que está pasando o cómo puedo solucionarlo?
p.s. Compilo con -O2, porque ya descubrí que eso puede marcar una gran diferencia. También lo intenté con -O3, sin diferencia real.
vértice se define como sigue:
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;
};
Trate de compilar con '-O3' que alineará algunas funciones (99.999% de probabilidad de que insertará' push_back', y si no lo hace, entonces la implementación o compilador es una porquería). –
@daknok_t también lo intentó, no hay diferencia real. – nickygerritsen
Llamar 'reserve' en lugar de' resize' y luego usar 'push_back' en lugar de' [] 'evitará la inicialización redundante realizada por' resize'. No sé si esa es la causa de la ralentización de 10x (dudo que represente todo), pero sin duda debería ayudar. –