我已经实现了一个矩阵乘法boost::numeric::ublas::matrix
(见我的全力,努力提升代码 )
Result result = read ();
boost::numeric::ublas::matrix<int> C;
C = boost::numeric::ublas::prod(result.A, result.B);
和另一个标准算法(参见完整的标准代码 ):
vector< vector<int> > ijkalgorithm(vector< vector<int> > A,
vector< vector<int> > B) {
int n = A.size();
// initialise C with 0s
vector<int> tmp(n, 0);
vector< vector<int> > C(n, tmp);
for (int i = 0; i < n; i++) {
for (int k = 0; k < n; k++) {
for (int j = 0; j < n; j++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
return C;
}
这是我的测试速度:
time boostImplementation.out > boostResult.txt
diff boostResult.txt correctResult.txt
time simpleImplementation.out > simpleResult.txt
diff simpleResult.txt correctResult.txt
这两个程序读取一个硬编码的文本文件包含两个2000×2000矩阵。 这两个程序被编译与这些标志:
g++ -std=c++98 -Wall -O3 -g $(PROBLEM).cpp -o $(PROBLEM).out -pedantic
我得到了15秒我的实现和超过4分钟升压实现!
编辑:有它编译后
g++ -std=c++98 -Wall -pedantic -O3 -D NDEBUG -DBOOST_UBLAS_NDEBUG library-boost.cpp -o library-boost.out
我28.19秒为ikj算法和60.99秒的提升。 所以升压仍然是相当慢。
为什么这么助推比我的执行慢得多?
的的uBLAS版本的性能下降可以通过正如指出的TJD调试后者的特征部分原因。
这里是由uBLAS库版本调试上所花的时间:
real 0m19.966s
user 0m19.809s
sys 0m0.112s
下面是与调试关闭(采取的uBLAS版本时-DNDEBUG -DBOOST_UBLAS_NDEBUG
添加编译器标志):
real 0m7.061s
user 0m6.936s
sys 0m0.096s
因此,与调试关,uBLAS库的版本快了近3倍。
其余的性能差异可以通过引用以下部分中介绍的uBLAS常见问题解答 “为什么比uBLAS库(atlas-)BLAS这么慢得多”:
uBLAS库的一个重要的设计目标是要尽可能通用。
这种通用性几乎总是带有一个成本。 尤其是prod
功能模板可以处理不同类型的矩阵,例如稀疏或三角形的。 幸运的uBLAS提供替代品稠密矩阵乘法优化,特别地, axpy_prod和block_prod
。 以下是比较不同方法的结果:
ijkalgorithm prod axpy_prod block_prod
1.335 7.061 1.330 1.278
正如你可以同时看到axpy_prod
和block_prod
比你实现稍快。 测量刚计算时间没有I / O,去除不必要的复制和的块大小的仔细选择block_prod
(I用64)可以使不同更深刻。
另见的uBLAS常见问题和有效的uBLAS和一般的代码优化 。
我相信,你的编译器不优化不够。 uBLAS库代码大量使用的模板和模板需要大量使用优化。 我跑了通过MS VC 7.1编译器代码在发布模式为1000×1000矩阵,它给了我
10.064
S代表的uBLAS
7.851
S代表矢量
所不同的是仍然存在,但绝不是压倒性的。 uBLAS库的核心概念是惰性计算,所以prod(A, B)
的计算结果仅在需要时的结果,例如prod(A, B)(10,100)
将在任何时间执行,因为只有一个元件实际上将被计算。 这样实际上有一个为全矩阵乘法它可以优化 (见下文) 没有专门的算法 。 但是你可以帮助图书馆一点,声明
matrix<int, column_major> B;
将减少运行时间,以4.426
S的用一只手绑击败你的函数。 矩阵相乘时,优化缓存使用这个声明使得访问存储更多的顺序。
PS读过的uBLAS文档,以结束),你应该已经发现,竟然有一个专用的功能一下子成倍整个矩阵。 2个功能- axpy_prod
和opb_prod
。 所以
opb_prod(A, B, C, true);
即使在未优化row_major乙矩阵执行8.091
秒,是在同水准与你的载体算法
PPS甚至还有更多的优化:
C = block_prod<matrix<int>, 1024>(A, B);
执行4.4
S,不管B是否是column_或row_重大。 请看介绍:“该功能block_prod是专为大型密集矩阵”。 选择针对特定任务特定的工具!
我创建了一个小网站用的uBLAS矩阵-矩阵产品实验 。 这是关于整合的新实现对矩阵矩阵产品投入的uBLAS。 如果你已经有了Boost库只包含额外的4个文件。 所以它是非常自足。
我会感兴趣,如果其他人可以运行在不同的机器上简单的基准。