Пиша програма за анализ на графика на социална мрежа. Това означава, че програмата се нуждае от много произволни достъпи до паметта. Струва ми се, че 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