0

最適化されたブーストuBLASライブラリを使用するために、独自のベクトル代数コードの一部を変換しています。ただし、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>ます。

私自身の実装は、単純なネストされたループの反復であり、行列は単なる2D二重配列です。

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倍遅くなります...

4

3 に答える 3

2

uBlas は、第 1 の目標としてのパフォーマンスを考慮して設計されていません。uBlas よりも大幅に高速なライブラリがあります。たとえば、http ://eigen.tuxfamily.org/index.php?title=Benchmark を参照してください。

于 2011-06-13T14:33:58.153 に答える
1

この pdfには、さまざまな線形代数ライブラリの非常に詳細な比較が含まれています。Computational Science Stack Exchangeからのこの回答でこれに出会いました。これは、この種の質問に適した場所である可能性があります。

于 2012-03-22T11:21:37.550 に答える
0

それがスローダウンの原因であるかどうかはわかりませんが (4x の数値を取得するためにプロファイリングしましたか?)、このループは遅くなる可能性があります。

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

ほとんどの時間がコード内のループの処理に費やされている場合、この余分なループによって時間が 2 倍になる可能性があります (ubla とは関係ありません)。代わりに使用することをお勧めしstd::copyます:

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

ほとんどのコンパイラは、これが double をコピーしていることを認識し、最適なコピーを実行する必要があります。これにより、問題が多少解決される可能性があります。

于 2011-06-13T14:16:19.220 に答える