有谁知道如何加快boost::numeric::ublas::vector
?
我正在使用typedef ublas::vector<float, ublas::bounded_array<float, 3> > MYVECTOR3
并将其速度与普通操作的D3DXVECTOR3
进行比较。
测试看起来如下:
#include <d3dx9.h>
#pragma comment(lib, "d3dx9.lib")
static const size_t kRuns = static_cast<size_t>(10e6);
TEST(Performance, CStyleVectors) {
D3DXVECTOR3 a(1.0f, 2.0f, 3.0f);
D3DXVECTOR3 b(2.0f, 3.0f, 1.0f);
D3DXVECTOR3 c(6.0f, 4.0f, 5.0f);
for (size_t i = 0; i < kRuns; ++i) {
c = c + (a + b) * 0.5f;
}
}
#include <boost/numeric/ublas/vector.hpp>
TEST(Performance, CppStyleVectors) {
typedef boost::numeric::ublas::vector<float,
boost::numeric::ublas::bounded_array<float, 3> > MYVECTOR3;
MYVECTOR3 a(3), b(3), c(3);
a[0] = 1.0f, a[1] = 2.0f, a[2] = 3.0f;
b[0] = 2.0f, b[1] = 3.0f, b[2] = 1.0f;
c[0] = 6.0f, c[1] = 4.0f, c[2] = 5.0f;
for (size_t i = 0; i < kRuns; ++i) {
noalias(c) = c + (a + b) * 0.5f;
}
}
结果如下:
[----------] 2 tests from Performance
[ RUN ] Performance.CStyleVectors
[ OK ] Performance.CStyleVectors (484 ms)
[ RUN ] Performance.CppStyleVectors
[ OK ] Performance.CppStyleVectors (9406 ms)
[----------] 2 tests from Performance (9890 ms total)
正如您所看到的,即使使用基于自定义堆栈的分配器,普通C风格的矢量也比boost::numeric::ublas
的矢量快20倍。有人知道如何加快速度吗?
也许是通过编写自定义包装或类似的东西?
谢谢
答案 0 :(得分:3)
Boost uBLAS(和BLAS一般)提供对向量和矩阵代数的支持,其中维度的数量在运行时确定。它适用于解决某些数值问题(如用FEM或类似方法进行仿真,优化问题,近似)。对于这些问题,它的速度相对较快,但无法与其专业的 3d 矢量类库竞争。
使用其他一些库。如果D3DXVECTOR3不够,请结账,例如CGAL。
答案 1 :(得分:0)
我认为如果你从ublas :: vector类继承到带有手动编码复制构造函数的专用3D矢量类,你可能会获得更好的性能。像这样的代码(使用双精度)
/**
A 3D vector
*/
class c3d : public boost::numeric::ublas::bounded_vector<double, 3>
{
typedef boost::numeric::ublas::bounded_vector<double, 3> Base_vector;
public:
// ctors
c3d () : Base_vector()
{}
c3d (double x, double y, double z) : Base_vector()
{ Base_vector::iterator p = begin(); *p++=x; *p++=y; *p++=z;}
template <class R> c3d (const boost::numeric::ublas::vector_expression<R>& r) : Base_vector(r)
{}
template <class R> void operator=(const boost::numeric::ublas::vector_expression<R>& r)
{ Base_vector::operator=(r); }
template <class R> void operator=(const Base_vector& r)
{ Base_vector::operator=(r); }
答案 2 :(得分:0)
我再次看了一眼,并意识到加快速度的最佳方法是重写
for (size_t i = 0; i < kRuns; ++i) {
c = c + (a + b) * 0.5f;
}
作为
c = c + kRuns * ( a + b ) * 0.5f
根本没有时间。
当我使用简单数组对其进行编码时,我的优化编译器显然会为'循环'执行此操作,并且在一段时间内运行的时间太短而无法测量。
float a[3], b[3], c[3];
a[0] = 1.0f, a[1] = 2.0f, a[2] = 3.0f;
b[0] = 2.0f, b[1] = 3.0f, b[2] = 1.0f;
c[0] = 6.0f, c[1] = 4.0f, c[2] = 5.0f;
for (size_t i = 0; i < KRUNS; ++i) {
c[0] = c[0] + ( a[0] + b[0] ) * 0.5;
c[1] = c[1] + ( a[1] + b[1] ) * 0.5;
c[2] = c[2] + ( a[2] + b[2] ) * 0.5;
}
不是吗?
使用ublas库会阻止优化器执行此操作。运行此代码
#define KRUNS 1000000
typedef boost::numeric::ublas::vector<float,
boost::numeric::ublas::bounded_array<float, 3> > MYVECTOR3;
MYVECTOR3 a(3), b(3), c(3);
a[0] = 1.0f, a[1] = 2.0f, a[2] = 3.0f;
b[0] = 2.0f, b[1] = 3.0f, b[2] = 1.0f;
c[0] = 6.0f, c[1] = 4.0f, c[2] = 5.0f;
for (size_t i = 0; i < KRUNS; ++i) {
noalias(c) = c + (a + b) * 0.5f;
}
需要63毫秒。无论你的机器有多慢,我都无法想象你为什么要花9400毫秒的时间。我再问一遍:你确定你已经开启了优化并且正在链接到发布库吗?