C ++向量问题

时间:2010-07-15 18:41:52

标签: c++ performance boost vector

有谁知道如何加快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倍。有人知道如何加快速度吗?

也许是通过编写自定义包装或类似的东西?

谢谢

3 个答案:

答案 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毫秒的时间。我再问一遍:你确定你已经开启了优化并且正在链接到发布库吗?