重复使用预分配的向量<复杂<double>>作为<double>长度两倍的向量

Re-use a pre-allocated vector<complex<double>> as a vector<double> of twice the length

本文关键字:gt lt double 向量 两倍 复杂 预分配 作为      更新时间:2023-10-16

我预先分配了一个由 N 个变量组成的大向量作为函数 A 作用的complex<double>。完成后,我希望将其传递给另一个函数 B,我希望在其中重用该内存分配,但作为数据类型double的长度为 2N 的向量,即:

vector<complex<double>> vec(N);
for (int i = 0; i < M; i++;
{
Function A(&vec); // Does work on vec as a vector<complex<double>>
// vector<complex<double>> vec(N) converts to vector<double> vec(2N) (or vector<float> vec(4N))
Function B(&vec); // Does work on vec as a vector<double> or vector<float>  
}

其中MN足够大,足以保证预先分配vec。我试图避免分配,因为它很昂贵。数据彼此独立(即,在函数 B 中使用它之前,我最终会再次填充数据(。从我目前所读到的内容来看,(匿名?(工会似乎是要走的路,但我不确定工会在向量方面是如何工作的。我希望我能在这件事上得到一些帮助。

谢谢。

编辑:分配向量需要 3 秒,函数需要 5 秒才能操作。

您正在尝试重用原始内存,而不是向量 - 那么为什么不这样做并避免弄乱类型呢?

编写一个预先分配并拥有内存的池分配器。

使用该池分配器(代理(构造第一个vector<complex>。 稍后,在第一个向量被销毁并放弃其在池上的声明后,使用(代理(相同的池分配器创建vector<double>

向量将复制顶级分配器对象,这就是为什么它必须是保留对预分配的持久池的引用的代理。

我看到以下解决方案:

1. 变体 - 现代工会

使用vector< variant< double, complex<double> > >.这可以存储doublecomplex<double>元素。

即使变体类型(doublecomplex<double>(可能共享空间,因为在给定时间只有一个类型处于活动状态,您仍然不知道它们这样做的效率如何(还需要有一个标识符来标记哪种类型是活动的,并且对齐 8 字节边界可能会浪费 50% 的空间(。另请参阅此处。

此外,您必须区分每个元素,即使容器在任何给定时刻都具有相同类型的所有元素。

2. 使用原始内存

更传统的选项是使用operator new()(函数,而不是运算符(分配内存。然后,您将在那里使用放置新构造双精度和复合体,并使用显式析构函数调用销毁它们。

如果您不需要很多std::vector功能,例如动态增长、删除、插入,而只需要一个大数据存储,那么这可能是一个有效的解决方案。在这种情况下,唯一需要的是大小。

为了不用担心范围,您可以使用自定义删除器将所有内容打包到std::unique_ptr中。删除程序只会调用operator delete()

3. 编写自定义分配器

std::vector为分配器采用第二个模板参数。分配器允许您自定义从何处获取内存。但是有很多东西需要实现,标准对行为施加了几条规则。