Я пишу программу для анализа графа социальной сети. Это означает, что программе требуется много случайных обращений к памяти. Мне кажется, prefetch должен помочь. Вот небольшой фрагмент кода чтения значений от соседей вершины.
for (size_t i = 0; i < v.get_num_edges(); i++) {
unsigned int id = v.neighbors[i];
res += neigh_vals[id];
}
Я преобразовываю приведенный выше код в приведенный ниже и предварительно выбираю значения соседей вершины.
int *neigh_vals = new int[num_vertices];
for (size_t i = 0; i < v.get_num_edges(); i += 128) {
size_t this_end = std::min(v.get_num_edges(), i + 128);
for (size_t j = i; j < this_end; j++) {
unsigned int id = v.neighbors[j];
__builtin_prefetch(&neigh_vals[id], 0, 2);
}
for (size_t j = i; j < this_end; j++) {
unsigned int id = v.neighbors[j];
res += neigh_vals[id];
}
}
В этом коде C++ я не переопределял никаких операторов.
К сожалению, код на самом деле не улучшает производительность. Интересно, почему. По-видимому, аппаратная предварительная выборка в этом случае не работает, потому что аппаратное обеспечение не может предсказать расположение памяти.
Интересно, вызвано ли это оптимизацией GCC. Когда я компилирую код, я включаю -O3. Я действительно надеюсь, что предварительная выборка может еще больше повысить производительность, даже если -O3 включен. В этом случае оптимизация -O3 объединяет две петли? Может ли -O3 включить предварительную выборку в этом случае по умолчанию?
Я использую gcc версии 4.6.3, и программа работает на Intel Xeon E5-4620.
Спасибо, да
get_neighbor
? Какой типneigh_vals
? Что такоеvertex_id_t
? Что такоеv
? Пожалуйста, отредактируйте свой вопрос, чтобы улучшить его. - person Basile Starynkevitch   schedule 23.03.2015gcc
, какой процессор? Вам нужно отредактировать свой вопрос, чтобы улучшить его. - person Basile Starynkevitch   schedule 23.03.2015v.get_num_edges()
инвариантным на протяжении всего циклаfor
? Похоже, вы можете назначить его переменной, а не вызывать ее каждый раз в начале цикла. - person Andy Lester   schedule 23.03.2015