Быстрые матричные сложения в C++
В одном проекте на С++ мне понадобилось два типа матриц: разреженные и заполненные.
Для первых выбрали матрицы из библиотеки uBLAS, для вторых выбрать библиотеку сложнее, так как важна была скорость с которой выполняются операции сложения матриц и умножения на скаляр.
Я решил протестировать несколько библиотек: uBLAS, tvmet и AlgLib.
Вот что получилось:
- операция: n = m + m;
uBLAS: 1.357
tvmet: 0.945
AlgLib: 0.889
- операция: n = 2 * m – m;
uBLAS: 1.607
tvmet: 1.512
AlgLib: 1.404
- операция: n = 2 * m + m / 3.3 – 0.1 * -m;
uBLAS: 2.854
tvmet: 3.176
AlgLib: 3.682
В uBLAS хорошо оптимизированы алгоритмы по работе с выражениями и большими матрицами, но хуже работает на простых выражениях и маленьких матрицах чем AlgLib.
Тогда мне в голову пришла гениальная идея о том как можно ускорить простые операции с матрицами до максимума – использовать для этого циклы 
А для красоты использовать вот такой-вот define:
#define MatrixExp(n, exp) {\
for(int i = 0; i < n.size1(); i++) \
for(int j = 0; j < n.size2(); j++) \
n(i, j) = exp; \
}
Этим дефайном очень просто пользоваться: MatrixExp([новая матрица], [выражение с индексами (i,j)] ),
пример:
MatrixExp(new_matrix, 2 * m1(i,j) + m2(i,j) -m3(i,j) / 5 );
Для любых выражений скорость на порядок выше ~ 0.515 (так не создаются временные объекты)
Вот пример из рабочего кода:
Matrix total(varsize, varsize);
MatrixExp(total, Ck[j] * k(i,j) + Ckx[j] * k_x(i,j) + Cky[j] * k_y(i,j) );
PS Matrix – это моя обертка над классом ap::real_2d_array из AlgLib. Так как у них уж очень не удобно всё.