Умножение ublas Slow Matrix-SparseVector - PullRequest
0 голосов
/ 13 июня 2011

Я конвертирую свой собственный код векторной алгебры, чтобы использовать оптимизированную библиотеку uBLAS boost. Однако когда я попытался выполнить умножение SymmetricMatrix-SparseVector, я обнаружил, что оно примерно в 4 раза медленнее, чем моя собственная реализация. Размер вектора обычно составляет около 0-500, а около 70-80% записей равны нулю.

Вот мой код

void CRoutines::GetA(double a[], double vectorIn[], int sparseVectorIndexes[], int vectorLength, int sparseLength)
{
    compressed_vector<double> inVec (vectorLength, sparseLength);
    for(int i = 0; i < sparseLength; i++)
    {
        inVec(sparseVectorIndexes[i]) = vectorIn[sparseVectorIndexes[i]];
    }
    vector<double> test = prod(inVec, matrix);
        for(int i = 0; i < vectorLength; i++)
    {
        a[i] = test(i);
    }
}

sparseVectorIndexes хранит индексы ненулевых значений входного вектора, vectorLength - длина вектора, а sparseLength - число ненулевых значений в векторе. Матрица хранится в виде симметричной матрицы symmetric_matrix<double, lower>.

Моя собственная реализация - это простая итерация вложенного цикла, где матрица - это просто двумерный двойной массив:

void CRoutines::GetA(double a[], double vectorIn[], int sparseVectorIndexes[], int vectorLength, int sparseLength)
 {
    for (int i = 0; i < vectorLength; i++)
    {
            double temp = 0;

            for (int j = 0; j < sparseLength; j++)
            {
                int row = sparseVectorIndexes[j];
                if (row <= i) // Handle lower triangular sparseness
                    temp += matrix[i][row] * vectorIn[row];
                else
                    temp += matrix[row][i] * vectorIn[row];
            }
            a[i] = temp;
    }

}

Почему uBLAS 4x медленнее? Я не пишу умножение правильно? Или есть другая библиотека, более подходящая для этого?

РЕДАКТИРОВАТЬ: Если я вместо этого использую плотный векторный массив, тогда uBLAS будет только в 2 раза медленнее ...

Ответы [ 3 ]

2 голосов
/ 13 июня 2011

uBlas не был спроектирован с целью повышения производительности в качестве цели №1. Есть библиотеки, которые значительно быстрее, чем uBlas. Смотрите, например http://eigen.tuxfamily.org/index.php?title=Benchmark

1 голос
/ 22 марта 2012

В этом pdf содержится довольно подробное сравнение различных библиотек линейной алгебры. Я сталкивался с этим в этом ответе от Обмен вычислительных стеков , который, возможно, является лучшим местом для такого рода вопросов.

0 голосов
/ 13 июня 2011

Не уверен, что это является причиной замедления (вы заполнили профиль, чтобы получить номер 4x?), Но этот цикл может быть медленным:

for(int i = 0; i < vectorLength; i++)
    {
        a[i] = test(i);
    }

Если большая часть времени уходит на обработку цикловв вашем коде этот дополнительный цикл может удвоить время (и не иметь ничего общего с убласом).Я бы рекомендовал использовать std::copy вместо:

std::copy(test.begin(), test.end(), a[0])

Большинство компиляторов должны видеть, что это копирование двойного кода, и делать оптимальное копирование, что может несколько решить вашу проблему.

...