Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么boosts矩阵乘法比我的慢?_C++_Performance_Boost_Ublas_Boost Ublas - Fatal编程技术网

C++ 为什么boosts矩阵乘法比我的慢?

C++ 为什么boosts矩阵乘法比我的慢?,c++,performance,boost,ublas,boost-ublas,C++,Performance,Boost,Ublas,Boost Ublas,我已经用boost::numeric::ublas::matrix实现了一个矩阵乘法(请参阅) Result=read(); boost::numeric::ublas::矩阵C; C=boost::numeric::ublas::prod(result.A,result.B); 另一个采用标准算法(参见): vectorijkalgorithm(vectorA, 向量B){ int n=A.size(); //用0初始化C 向量tmp(n,0); 向量C(n,tmp); 对于(int i=0

我已经用
boost::numeric::ublas::matrix
实现了一个矩阵乘法(请参阅)

Result=read();
boost::numeric::ublas::矩阵C;
C=boost::numeric::ublas::prod(result.A,result.B);
另一个采用标准算法(参见):

vectorijkalgorithm(vectorA,
向量B){
int n=A.size();
//用0初始化C
向量tmp(n,0);
向量C(n,tmp);
对于(int i=0;i
这是我测试速度的方法:

time boostImplementation.out > boostResult.txt
diff boostResult.txt correctResult.txt

time simpleImplementation.out > simpleResult.txt
diff simpleResult.txt correctResult.txt
两个程序都读取一个硬编码文本文件,其中包含两个2000 x 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
对于ikj算法,我得到了28.19秒,对于Boost算法,我得到了60.99秒。因此,推进速度仍然相当缓慢


为什么boost比我的实现慢得多?

正如TJD所指出的,uBLAS版本性能较慢的部分原因是后者的调试功能

以下是uBLAS版本在调试时花费的时间:

real    0m19.966s
user    0m19.809s
sys     0m0.112s
以下是uBLAS版本在调试关闭时所花费的时间(
-DNDEBUG-DBOOST\u uBLAS\u NDEBUG
添加了编译器标志):

因此,在关闭调试的情况下,uBLAS版本的速度几乎快了3倍

剩余的性能差异可以通过引用“为什么uBLAS比(atlas-)BLAS慢这么多”的以下部分来解释:

ublas的一个重要设计目标是尽可能通用

这种普遍性几乎总是要付出代价的。特别是
prod
函数模板可以处理不同类型的矩阵,例如稀疏矩阵或三角形矩阵。幸运的是,uBLAS提供了特别针对密集矩阵乘法和
block\u prod
优化的替代方案。以下是比较不同方法的结果:

ijkalgorithm   prod   axpy_prod  block_prod
   1.335       7.061    1.330       1.278
正如您所看到的,
axpy_prod
block_prod
都比您的实现快一些。在没有I/O的情况下测量计算时间,删除不必要的复制,并为
block_prod
(我使用64)仔细选择块大小,可以使差异更加深刻


另请参见和。

我相信,您的编译器没有进行足够的优化。uBLAS代码大量使用模板,模板需要大量使用优化。我用MSVC7.1编译器在1000x1000矩阵的发布模式下运行了你的代码,它给了我

10.064
s适用于uBLAS

向量的
7.851
s

差别仍然存在,但决不是压倒性的。uBLAS的核心概念是惰性评估,因此
prod(A,B)
仅在需要时评估结果,例如
prod(A,B)(10100)
将立即执行,因为实际上只计算一个元素。因此,实际上没有专门的算法可以优化整个矩阵乘法(见下文)。但是你可以帮图书馆一点忙

matrix<int, column_major> B;

即使在未优化的RoWiMax B矩阵中执行<代码> 8.091 <代码>秒,与向量算法

一致。 还有更多的优化:

C = block_prod<matrix<int>, 1024>(A, B);
C=block_prod(A,B);
4.4
s中执行,无论B是主列还是主行。
请考虑描述:“函数BuythPod是为<强>大密集< /强>矩阵设计的。”为特定任务选择特定工具! 我创建了一个小网站。它是关于将矩阵积的新实现集成到uBLAS中。如果您已经拥有boost库,那么它只包含额外的4个文件。所以它几乎是独立的


如果其他人能在不同的机器上运行简单的基准测试,我会很感兴趣

重新发明轮子是一个好主意的唯一时间是当你可以制造一个更好的轮子时…Boost.uBLAS是一个标准接口,而不是一个健壮的实现,所以不要期望它很快,除非你正在使用例如LAPACK后端。Boost-uBLAS有一些可选的调试检查,这会减慢速度。请参阅此常见问题解答,并检查预处理器宏BOOST_UBLAS_NDEBUG和NDEBUG,尽管阅读两个2k x 2k矩阵不应该花费4分钟。@神秘的棘手部分是,大多数人重新发明轮子时,通常都认为不管它是否真的是这样,它都会更好,否则他们一开始可能不会这么做-D你能用OP提供的版本运行相同的测试吗?@MFontani:当然,我更新了答案。请注意,我使用了更小(1000x1000)的随机矩阵,因此所有时间都更小。正如我已经评论过的,在我的机器/编译器组合(VS 9)中,充分优化后,op的boost版本实际上比vector版本运行得更快,只需对计算进行计时(无IO)。从反汇编来看,我想gcc可以更好地内联/简化向量版本,使用for循环展开等。另一方面,
vector
需要多个分配(可能的优化?),boost可以对整个矩阵使用一个。这两个时间对我来说都很大,在我的机器向量版本上,1000x1000随机矩阵只需1.3秒。你在哪台机器上进行测试?@vitaut,这是一台奔腾M1600笔记本:)+1根据我的测量,我现在可以得出结论:使用
迭代器
s而不是整数+元素访问在VC9上快3倍,但在g++(4.6.2)上不快。应用于boost矩阵的ikj算法比
向量
+
迭代器
s(在MSVC上是6x)慢
opb_prod(A, B, C, true);
C = block_prod<matrix<int>, 1024>(A, B);