TLDR: во-первых, оптимизируйте алгоритм умножения матриц, затем проследите за вашим временным числом, а затем оптимизируйте внутреннее распределение матриц.
Длинный ответ:
Я думаю, что самое важное для решенияэто оптимизация умножения ваших матриц.Умножение матриц для наиболее интуитивного алгоритма - O (n ^ 3) (что огромно даже для маленьких матриц).
Например, для умножения матриц 2x2 у вас есть 16 операций умножения ("mo«).Для умножения матрицы 3x3 у вас есть 27 мес, а для 4x4 у вас есть 64 мес.
Я не уверен, как он реализован в вашем случае, но если это интуитивный алгоритм (как тройной цикл for
), меняющий его на умножение матриц с использованием LU-разложенных матриц должно резко повысить вашу производительность.
Это потому, что, получив разложенные матрицы, вы можете сильно оптимизировать алгоритм умножения (нет смысла умножать строки и столбцы для нулевых элементов).
Далее рассмотримиспользование кэшированных значений вместо повторения операций для добавления в diffsumsq
:
старый код:
diffsum+=valA-valB; // compute difference once
diffsumsq+=(valA-valB)*(valA-valB); // compute it two more times, then multiply
новый код:
diff = valA-valB; // compute difference once
diffsum+= diff; // use computed difference
diffsumsq+=diff*diff; // just multiply
Второй вариант - трив разы быстрее при вычислении разности (две for
циклы - операции x * y выполняются только один раз, а не три раза).
Вы можете дополнительно отслеживать количество временных объектов: каждая двоичная операция создает временную(что означает выделение еще одной матрицы x * y в памяти и копирование значений).Например, выражение:
diffsumsq+=(valA-valB)*(valA-valB);
создает временное значение для разницы в первом паратезе, затем другое для разницы во втором, а затем еще одно для продукта.
В моемВ приведенном выше примере лучше написать
diff = valA;
diff -= valB;
вместо
diff = valA - valB;
, поскольку таким образом вы избегаете выделения временного элемента, назначенного для diff (во втором варианте).
Еще одна вещь, на которую стоит обратить внимание, - это потребление памяти: так как это выполняется много, вы можете либо предварительно выделить память, либо объединить в памяти использованные матрицы и повторно использовать память вместо создания новых объектов.
IЯ уверен, что есть другие вещи, которые нужно посмотреть.
Редактировать: Как вы можете умножить матрицы?Они должны совпадать по столбцам х строк.То есть количество столбцов в valA должно быть равно количеству строк в valB (если я правильно помню умножения матриц).
Еще одна вещь:
Iсделал процедуру вычисления многострочным макросом #define, чтобы обеспечить его встраивание и избежать вызовов и возвратов функций.
Вам не нужны макросы для оптимизации кода C ++.Чтобы избежать вызовов и возвратов функций, используйте функции inline
d.Макросы идут со своими проблемами.