Оптимизация цикла C

#c #optimization #loop-unrolling

#c #оптимизация #развертывание цикла

Вопрос:

У меня есть следующая функция для вычисления коэффициентов:

 void CalculateCoefficients(LinearFit *DataSet, double *A, double *B)
  {
   /* Declare and initialize sum variables */
   double S_XX = 0.0;
   double S_XY = 0.0;
   double S_X  = 0.0;
   double S_Y  = 0.0;
   int lcv;

   /* Compute the sums */
   for (lcv=0; lcv < DataSet->NextElement; lcv  )
    {
      S_XX  = DataSet->Data_X[lcv] * DataSet->Data_X[lcv];
      S_XY  = DataSet->Data_X[lcv] * DataSet->Data_Y[lcv];
      S_X   = DataSet->Data_X[lcv];
      S_Y   = DataSet->Data_Y[lcv];
    } /* for() */

   /* Compute the parameters of the line Y = A*X   B */
   (*A) = (((DataSet->NextElement * S_XY) - (S_X * S_Y)) / ((DataSet->NextElement * S_XX) - (S_X * S_X)));
   (*B) = (((S_XX * S_Y) - (S_XY * S_X)) / ((DataSet->NextElement * S_XX) - (S_X * S_X)));
  } /* CalculateCoefficients() */
  

Я ищу, чтобы оптимизировать цикл. Я попытался развернуть цикл, но это мало что дало. Что еще я могу сделать?

Комментарии:

1. Вы могли бы получить значительный прирост производительности, используя инструкции SIMD, если ваша архитектура поддерживает это … если вы не против вычисления параллельных сумм, а затем горизонтального добавления в конце. Это меняет порядок добавлений, но это имеет значение только в более крайних случаях. Если вы можете позволить себе роскошь выбора своей архитектуры, вам может повезти использовать некоторые серьезно расширенные векторизованные инструкции.

Ответ №1:

Вы могли бы попробовать:

 double dsdx, dsdy;
...
dsdx = DataSet->Data_X[lcv];
dsdy = DataSet->Data_y[lcv];
S_XX  = dsdx * dsdx;
S_XY  = dsdx * dsdy;
S_X   = dsdx;
S_Y   = dsdy;
...
  

Таким образом, вы получаете значения из своей структуры только один раз на каждой итерации цикла.