gpt4 book ai didi

c++ - 使用自定义的总体分配器来利用std::vector末尾的内存

转载 作者:行者123 更新时间:2023-11-30 02:29:00 24 4
gpt4 key购买 nike

假设我有一个分配器my_allocator,它将在调用n+x时始终为n(而不是allocate(n))元素分配内存。

我是否可以轻松地假设[data()+n, data()+n+x)范围内的内存(对于std::vector<T, my_allocator<T>>)可以访问/有效以备将来使用(即在基本情况下放置新的或simd加载/存储(只要没有重新分配)?

注意:我知道data()+n-1之后的所有内容都是未初始化的存储。用例将是使用自定义分配器的基本类型的 vector (无论如何都没有构造函数),以避免在向 vector 抛出simd内部函数时出现特殊的极端情况。 my_allocator应分配以下存储空间:1.)正确对齐并具有2.)大小,该大小是所用寄存器大小的倍数。

为了使事情更加清楚:

假设我有两个 vector ,我想将它们相加:

std::vector<double, my_allocator<double>> a(n), b(n);
// fill them ...
auto c = a + b;
assert(c.size() == n);

如果现在从 my_allocator获得的存储分配了对齐的存储,并且 sizeof(double)*(n+x)始终是所用simd寄存器大小的倍数(因此是每个寄存器的值数的倍数),则我可以做类似的事情
for(size_t i=0u; i<(n+x); i+=y) 
{ // where y is the number of doubles per register and and divisor of (n+x)
auto ma = _aligned_load(a.data() + i);
auto mb = _aligned_load(b.data() + i);
_aligned_store(c.data() + i, _simd_add(ma, mb));
}

在这里,我不必关心任何特殊情况,例如未对齐的负载或来自y不可除的 n的积压。

但是 vector 仍然只包含 n值,并且可以像 n大小的 vector 一样进行处理。

最佳答案

对于您的用例,您应该没有任何疑问。但是,如果您决定在多余的空间中存储任何有用的东西,并在其生命周期内改变 vector 的大小,则可能会遇到重新分配可能性的问题-如何从中传输额外的数据鉴于重新分配是通过分别调用allocate()deallocate()且它们之间没有直接连接的结果而发生的,因此将旧分配转换为新分配?

编辑(解决添加到问题中的代码)

在我最初的回答中,我的意思是,访问分配器分配的超出请求数量的额外字节应该没有任何问题。但是,在存储范围内写入数据是麻烦的,该存储范围超出了 vector 对象当前使用的范围,但属于未经修改的分配将跨越的范围。与通过std::vector / size()函数公开的相比,capacity()的实现可以自由地向分配器请求更多的内存,并将辅助数据存储在未使用的区域中。尽管这是高度理论上的,但不考虑这种可能性就意味着要为不确定的行为打开一扇门。

考虑 vector 分配的以下可能布局:

---====================++++++++++------.........
  • ===- vector
  • 的已用容量
  • +++- vector
  • 的未使用容量
  • ---- vector 过度分配(但未显示为容量的一部分)
  • ...-由分配器
  • 过度分配

    您不得在区域2( ---)和区域3( +++)中写任何东西。您的所有写操作都必须限制在区域4( ...)中,否则可能损坏重要的位。

    关于c++ - 使用自定义的总体分配器来利用std::vector末尾的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40054362/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com