优化c ++矩阵/位图类

时间:2010-05-20 23:20:16

标签: c++ optimization templates matrix bitmap

我正在搜索2D矩阵(或位图)类,它灵活但快速的元素访问。内容灵活的类应允许您在运行时选择维度,并且看起来像这样(简化):

class Matrix 
{
public:   
  Matrix(int w, int h) :  
    data(new int[x*y]), width(w)  {}

 void SetElement(int x, int y, int val)  
 {  
   data[x+y*width] = val;  
 } 

 // ...
private: // symbols
  int width;  
  int* data;  
};

使用模板的经常提出的解决方案更快(简化):

template <int W, int H>
class TMatrix {
  TMatrix() data(new int[W*H])  {}

  void SetElement(int x, int y, int val)  
  {  
    data[x+y*W] = val;  
  } 

  private:
    int* data;
};

这更快,因为代码中的宽度可以“内联”。第一种解决方案不会这样做。但是,这不再灵活,因为您无法在运行时更改大小。

所以我的问题是: 是否有可能告诉编译器生成更快的代码(比如使用模板解决方案时),代码中的大小是否已修复并在运行时依赖时生成灵活的代码?

我试图通过尽可能地写“const”来实现这一点。我用gcc和VS2005尝试过,但没有成功。这种优化对许多其他类似案例都很有用。

3 个答案:

答案 0 :(得分:0)

我会选择第一个版本,我自己。

但是,如果你真的想要尝试两全其美,你可以拥有一个Matrix类,它包含一个指向多态实现类型的指针。对于常见大小(例如最多4x4),您可以指向模板实例化,对于更大的大小,您可以指向处理一般MxN情况的实现。

说了这么多,我认为所有的间接&amp;虚拟调用将否定可能来自模板的任何性能改进。我认为你不能吃蛋糕和蛋糕。在这种情况下也要吃它。

如果您总是处理编译时已知大小的数据(例如图形/几何向量),那么您最好使用模板版本(可能以静态大小(非堆分配)存储数据)阵列)。如果您需要任意数据的一般功能,请改用动态版本。

答案 1 :(得分:0)

当然,您的需求可能会有所不同,但我会跳过自动生成,只需使用一组简单的“固定”版本即可。例如。 Vector3,Vector4,Matrix3x3,Matrix3x4和Matrix4x4。我想你可以从模板化版本中获得所有这些,但它不会产生任何特定的性能差异。

您是否有任何特殊原因希望能够在运行时更改尺寸?因为我建议只要在需要进行更改的情况下(从我怀疑是罕见的)实例,只需从一个复制到另一个就不会非常昂贵。

最后 - 我见过的事情是命名元素访问以及数组,但是你只能使用“硬编码”类型。类似的东西:

class Vector3
{
public:
   // other stuff...

   union
   {
      struct { float x, y, z; };
      float m[3];
   };
};

(这可能不是完全合法的C ++,适合您的编译器。)

哦,即使是模板化版本也不需要使用新版本。只需将数据声明为float data[W*H];将其从堆中取出将比“优化”一些数学运算带来更大的性能提升。

答案 2 :(得分:0)

完整的答案不同,但有些信息可能会有所帮助(如果您还没有意识到这些):OpenCVBoost (uBLAS)都非常好(快速/完整/全功能)矩阵实现。我没有查看它们内部以查看它们如何设置/获取元素或在实例化后调整大小。