Быстрые матричные сложения в C++

В одном проекте на С++ мне понадобилось два типа матриц: разреженные и заполненные.
Для первых выбрали матрицы из библиотеки uBLAS, для вторых выбрать библиотеку сложнее, так как важна была скорость с которой выполняются операции сложения матриц и умножения на скаляр.
Я решил протестировать несколько библиотек: uBLAS, tvmet и AlgLib.

Вот что получилось:

  1. операция: n = m + m;
    uBLAS: 1.357
    tvmet: 0.945
    AlgLib: 0.889
  2. операция: n = 2 * m – m;
    uBLAS: 1.607
    tvmet: 1.512
    AlgLib: 1.404
  3. операция: 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. Так как у них уж очень не удобно всё.

Комментарии (2)

toxx

Elfet, как вы делаете замер времени выполнения операций? Очень интересно, хочу тоже сделать для своего класса тест такой =)

При помощи boost::timer ;)

Вы можете следить за обсуждением этой записи с помощью RSS

Оставить комментарий





Подтвердите, что Вы не бот — выберите человечка с поднятой рукой:

Рубрики



Ссылки


наверх