Sto creando un programma che deve essere ultraveloce. Sta eseguendo alcune cose sulla GPU usando CUDA e successivamente esegue alcuni calcoli sulla CPU. Per questo, ho bisogno di convertire la struttura della GPU altamente ottimizzata in qualcosa che posso facilmente utilizzare sulla CPU. I miei dati sono fondamentalmente un grafico disposto in una griglia. Attualmente sto usando std :: vector per la parte CPU. Perché so che c'è piuttosto un overhead se faccio un sacco di push_back()
s ed io almeno so perché so quanti vertici ho nel mio grafico, io uso il seguente codice per questo: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);
}
}
Successivamente Aggiungo i bordi Purtroppo non so quanti spigoli per vertice ho, ma so che non sarà mai più grande di 8. Pertanto I reserve()
8 in ogni std :: vector che uso per i bordi.
Tuttavia, entrambi sembrano essere estremamente lenti. Se io uso un array normale per il grafico stesso (in pratica sostituendo lo std :: vector esterno), il miglioramento della velocità in quella parte è enorme (come 10x circa).
Per il grafico questo è fattibile, ma per i bordi non proprio, perché faccio alcuni post-procesing su questi bordi e per questo ho davvero bisogno di qualcosa come std :: vector che è un pò dinamico (aggiungo alcuni bordi) .
Attualmente la conversione dei dati in std :: vector è qualcosa come 10 volte più lento di eseguire il mio algoritmo sulla GPU (che è un algoritmo MST intelligente). Questo non è proprio quello che voglio, perché ora il sovraccarico è troppo grande.
Qualcuno sa cosa sta succedendo o come posso risolvere questo problema?
p.s. Compilo con -O2, perché ho già scoperto che ciò può fare una grande differenza. Anche provato con -O3, nessuna vera differenza.
Vertex è definito come segue:
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;
};
Provate a compilare con '-O3', che inline alcune funzioni (99,999% di probabilità che sia in linea' push_back', e in caso contrario l'implementazione o il compilatore è un pezzo di merda). –
@daknok_t ci ha provato, nessuna vera differenza. – nickygerritsen
Chiamare 'reserve' invece di' ridimensionare' e quindi usare 'push_back' invece di' [] 'eviterà l'inizializzazione ridondante eseguita da' ridimensiona'. Non so se questa è la causa del rallentamento 10x (dubito che conti per tutto), ma dovrebbe certamente aiutare. –