Я являюсь автором научного кода с открытым исходным кодом под названием vampire (http://github.com/richard-evans/vampire), а интенсивность вычислений означает любое улучшение производительности кода может значительно увеличить объем исследований, которые могут быть сделаны. Типичными временем выполнения этого кода могут быть сотни основных часов, поэтому я всегда ищу способы улучшить критические разделы кода. Тем не менее, я немного зациклился на следующем немного относительно безобидного вида кода, который составляет около 40% времени выполнения:
for (int atom = start_index; atom < end_index; atom++){
register double Hx = 0.0;
register double Hy = 0.0;
register double Hz = 0.0;
const int start = atoms::neighbour_list_start_index[atom];
const int end = atoms::neighbour_list_end_index[atom] + 1;
for (int nn = start; nn < end; nn++){
const int natom = atoms::neighbour_list_array[nn];
const double Jij = atoms::i_exchange_list[atoms::neighbour_interaction_type_array[nn]].Jij;
Hx -= Jij * atoms::x_spin_array[natom];
Hy -= Jij * atoms::y_spin_array[natom];
Hz -= Jij * atoms::z_spin_array[natom];
}
atoms::x_total_spin_field_array[atom] += Hx;
atoms::y_total_spin_field_array[atom] += Hy;
atoms::z_total_spin_field_array[atom] += Hz;
}
Обзор функций и переменных этого кода на высоком уровне выглядит следующим образом: существует 1D-массив физического вектора (разбивается на три массива 1D для каждого компонента x, y, z для целей кэширования памяти, atoms::x_spin_array
, и т.д.) называется "спин". Каждый из этих спинов взаимодействует с некоторыми другими спинами, и все взаимодействия хранятся в виде списка 1D-соседей (atoms::neighbour_list_array
). Соответствующий список взаимодействий для каждого атома определяется начальным и конечным индексом соседа listarray
в двух отдельных массивах. В конце вычисления каждый атомный спин имеет эффективное поле, которое является векторной суммой взаимодействий.
Учитывая небольшой объем кода и значительную долю времени выполнения, который он занимает, я сделал лучше всего, но я считаю, что должен быть способ оптимизировать это дальше, но, как физик, а не компьютерный ученый, возможно, я отсутствую что-то?