为性能库制作高效包装器的智能方法

时间:2016-04-26 07:17:45

标签: c++ performance numerical-computing

假设我们有一个外部库,它可以在双精度浮点数数组上非常快速地进行计算(大多数情况下是多线程的)。为方便起见,我以面向对象的方式编写代码,以便获得一个对象数组。每个对象都有一个包含double值的属性。使用强大的外部库的天真方法是这样的:

double temp[N];
for i from 1 to N
   temp[i] = objectArray[i].property;
end

但是,这需要时间和额外的内存来保存 temp 数组。有没有更好的方法呢?

这是一个普遍的问题,但我基本上想在C ++中使用它。

2 个答案:

答案 0 :(得分:2)

如果您确定您的对象只包含double数据成员,没有数据成员添加基础且没有virtual函数 - 请使用静态断言sizeof(*objectArray) == sizeof(double) - 并检查假设您的外部库函数不在线,您可以将外部库double*传递给objectArray[0]

如果库函数内嵌在您包含的标题中,则可能会遇到别名问题,应查阅编译器文档以获取选项。

如果您的objectArray元素 ,只需按double必须复制如果这是外部库所期望的,那么它们就变成了压缩数组。 (您可以考虑的一个选项是将double值保留在数组中,让更复杂的对象存储对数组元素的引用。)

答案 1 :(得分:1)

您可以为对象使用竞技场策略。基本上我们的对象只包含索引和数据领域的句柄。实际数据存储在右侧索引的竞技场中。这种方式当你需要创建双向量时,它已经存在于竞技场内。

这仅在您始终知道哪些对象一起处理时才有效,并且它们几乎总是一起处理。如果您需要每次选择所需的对象,这将不会为您提供任何性能提升(除非对象在数组中始终是连续的)。这也使常规对象访问速度变慢,所以只有每次复制值确实是程序中的瓶颈时才有意义。

您的数据结构如下:

class Arena {
   vector<double> propertyX;
   vector<double> propertyY;
   int next_index;
};

class MyObject {
  int index;
  Arena& arena
  MyObject(Arena& arena_ref): arena(arena_ref) { index = arena.next_index++; }
  double getX() { return arena.propertyX[index]; }
};

你需要更多的代码来确保事情的分配等等,但你明白了。现在,当您需要调用外部库时,可以直接从Arena对象获取数组。