Я пишу программу для анализа графика социальной сети. Это означает, что программе требуется много случайных обращений к памяти. Мне кажется, что предварительная выборка должна помочь. Вот небольшая часть кода считывания значений соседей вершины.
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];
}
}
В этом коде на С++ я не переопределял никаких операторов.
К сожалению, код действительно не улучшает производительность. Интересно, почему. По-видимому, аппаратная предварительная выборка не работает в этом случае, потому что аппаратное обеспечение не может предсказать местоположение памяти.
Интересно, вызвано ли это оптимизацией GCC. Когда я компилирую код, я включаю -O3. Я действительно надеюсь, что предварительная выборка может еще больше повысить производительность даже при включенном -O3. В этом случае оптимизация -O3 сплавляет две петли? Может ли -O3 включить предварительную выборку в этом случае по умолчанию?
Я использую gcc версии 4.6.3, и программа работает на Intel Xeon E5-4620.
Спасибо, Da