Я создаю программу, которая должна быть очень быстрой. Он запускает некоторые вещи на графическом процессоре, используя CUDA, а затем выполняет некоторые вычисления на процессоре. Для этого мне нужно преобразовать высоко оптимизированную графическую структуру данных в нечто, что я могу легко использовать на процессоре. Мои данные в основном представляют собой график, выложенный в сетке. В настоящее время я использую std :: vector для части процессора. Потому что я знаю, что есть довольно накладные расходы, если я много push_back()
с и я по крайней мере знаю, потому что я знаю, сколько вершин у меня есть в моем графике, теперь я использую следующий код для этого: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);
}
}
После Я добавляю края. К сожалению, я не знаю, сколько ребер на вершине у меня есть, но я знаю, что он никогда не будет больше 8. Поэтому I reserve()
8 в каждом std :: vector, который я использую для ребер.
Однако, оба эти устройства выглядят чрезвычайно медленно. Если я использую обычный массив для самого графика (так, в основном, заменяя внешний std :: vector), улучшение скорости в этой части огромно (например, 10x или около того).
Для графика это выполнимо, но для ребер на самом деле нет, потому что я выполняю постпроцессорство на этих краях, и для этого мне действительно нужно что-то вроде std :: vector, который является динамическим (я добавляю некоторые ребра) ,
В настоящее время преобразование данных в std :: vector является чем-то вроде 10 раз медленнее, чем запуск моего алгоритма на графическом процессоре (который является интеллектуальным алгоритмом MST). Это не совсем то, что я хочу, потому что теперь накладные расходы слишком велики.
Кто-нибудь знает, что происходит или как я могу это исправить?
p.s. Я компилирую с -O2, потому что я уже выяснил, что это может иметь большое значение. Также пробовал с -O3, никакой реальной разницы.
Vertex определяется следующим образом:
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;
};
Попробуйте скомпилировать с '-O3', который будет встроить некоторые функции (99.999% шанс, что он будет встроен' push_back', а если нет, то реализация или компилятор - это часть дерьма). –
@ daknok_t также пробовал, что, никакой реальной разницы. – nickygerritsen
Вызов 'reserve' вместо' resize', а затем с помощью 'push_back' вместо' [] 'будет избегать избыточной инициализации, выполняемой' resize'. Я не знаю, является ли это причиной 10-кратного замедления (я сомневаюсь, что это объясняет все), но это, безусловно, поможет. –