SuperLu和LaPack的比较在与犰狳进行基准测试时失败
Comparison of SuperLu and LaPack fails when benchmarking with armadillo
我想比较SuperLu稀疏求解器的速度和使用LaPack的密集版本,在犰狳中使用spsolve()
。因此,我编写了这个程序:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <armadilloarmadillo>
#define SIZE 2500
#define ROUNDS 2500
int main()
{
//Time measurement stuff
LARGE_INTEGER frequency;
LARGE_INTEGER t1, t2, t3, t4;
QueryPerformanceFrequency(&frequency);
//Other stuff
arma::cx_colvec b = arma::randu<arma::cx_colvec>(SIZE);
arma::cx_colvec b1 = b, b2 = b;
arma::sp_cx_mat A = arma::sp_cx_mat(SIZE, SIZE);
A.diag(-2).fill(-1);
A.diag(-1).fill(16);
A.diag(0).fill(-30);
A.diag(1).fill(16);
A.diag(2).fill(-1);
arma::cx_colvec c = arma::zeros<arma::cx_colvec>(SIZE), d = arma::zeros<arma::cx_colvec>(SIZE);
QueryPerformanceCounter(&t1);
for (size_t i = 0; i < ROUNDS; i++)
{
if(arma::spsolve(c, A, b1, "superlu") == false)
{
std::cout << "Error in round 1n";
break;
}
b1 = c;
}
QueryPerformanceCounter(&t2);
QueryPerformanceCounter(&t3);
for (size_t i = 0; i < ROUNDS; i++)
{
if(arma::spsolve(d, A, b2, "lapack") == false)
{
std::cout << "Error in round 2n";
break;
}
b2 = d;
}
QueryPerformanceCounter(&t4);
std::cout << "Superlu took " << (t2.QuadPart - t1.QuadPart)*1000.0 / frequency.QuadPart << 'n';
std::cout << "Lapack took " << (t4.QuadPart - t3.QuadPart)*1000.0 / frequency.QuadPart << 'n';
std::cout << "Both results are equal: " << arma::approx_equal(b1, b2, "abstol", 1e-5) << 'n';
return 0;
}
现在,对于SIZE
和ROUND
的小值,函数approx_equal
返回 true,但对于较大的值,根据approx_equal
b1
和b2
的结果不再相等。为什么?问题可能是我的超级卢库无法正常工作吗?
我不会责怪 SuperLU 库。这里的"问题"似乎是矩阵的最小特征值A
变得越来越小,SIZE
的值越来越大。现在,for
循环反复将inv(A)
应用于给定的向量。由于您开始的向量是随机的,因此它将具有对应于最小特征值的A
的特征向量的一些非零"混合"。如果反转重复多次,该分量会显着放大,因此向量的各个分量b1/b2
变大。
例如,对于SIZE=2000
和ROUNDS=2
,我得到解决方案的最大分量(绝对值)约为10^9
.然后,您的测试似乎规定了10^-5
的绝对耐受性。但是,对于如此大的数字,这意味着 14 位有效数字必须完全匹配,这几乎是双精度的极限。 在我看来,鉴于这里比较的数字的性质,测试(例如)与approx_equal(b1, b2, "reldiff", 1E-8)
的相对误差更有意义。
另外,应该检查解决方案是否确实有意义 - 对于大量ROUNDS
,它迟早会溢出。例如,已经有了SIZE=2000
和ROUNDS=80
,我在b1/b2
向量中得到了无穷大......
相关文章:
- 换位表导致测试失败(但在游戏中运行良好)
- 使用rdtsc进行基准测试的缺点是什么
- 对 'std::thread::_M_start_thread CMake 的未定义引用进行基准测试
- 更高效地在微控制器上对C++进行基准测试
- _mm256_load_ps调试模式下导致谷歌/基准测试的分段错误
- 二叉树基准测试结果
- 如何使用谷歌基准测试对自定义界面进行基准测试
- 谷歌基准测试,如何只调用一次代码?
- 使用 std::chrono::steady_clock 对线程/异步中的代码进行基准测试
- 谷歌基准测试结果中显示的时间没有意义
- 使用 Google 基准测试时返回值会发生什么情况?
- 如果出现警告,如何立即使自动测试失败
- 如何在Qt测试框架中对信号进行基准测试?
- C/C++memcpu基准测试:测量CPU和墙时间
- 如何将参数传递给Google基准测试程序
- 如何对CUDA项目进行基准测试
- 为什么这个简单的 C++ SIMD 基准测试在使用 SIMD 指令时运行速度较慢?
- 模型测试 + 简单表模式 = 父测试失败
- SuperLu和LaPack的比较在与犰狳进行基准测试时失败
- 谷歌基准测试:断言"has_range_x_"失败