使2个非静态字段(即动态数组)相互接近使用内存

Make 2 non-static fields (that are dynamic arrays) use memory near each other

本文关键字:接近 内存 数组 动态 2个 静态 字段      更新时间:2023-10-16

B1B2为动态大小的存储类。
(例如B1~std::vector<char> B2~std::vector<float>

在C 11中,如果我代码B1B2'S movecopy函数(五个规则),则包含它们的类C将以字段为单位,默认情况下正确复制/移动自动自动复制/移动。

class C{
    B1 b1; B2 b2;
};

它的工作非常好。

问题

今天,我得到了个人资料结果 对性能问题进行了一些测试。
主要目标:我必须制作C同一实例的b1b2彼此分配内存: -

b1[0]  b1[1] ... b1[b1.size-1] (minimum gap) b2[0]  b2[1] ... b2[b2.size-1] 

如果可以的话,整个程序我将获得10-20%的性能提升。

我的解决方案

我可以使用这样的自定义分配器(伪代码): -

class C{
    B1 b1; 
    B2 b2;
    Allocator* allo_; // can be heap allocator 
    public: void reserve(int size){
        //old : b1.reserve(size); b2.reserve(size);  .... so easy
        //new :-
        B1 b1Next; B2 b2Next;
        int nb1=b1Next.howMuchIWant(size); 
        int nb2=b2Next.howMuchIWant(size);
        //^ request amount of bytes needed if capacity="size"
        void* vPtr=allo_->allocate(nb1+nb2);
        b1Next.setMemory(vPtr);
        b2Next.setMemory(vPtr + nb1);  //add "vPtr" by "nb1" bytes
        b1Next=b1;   //copy assignment (not move memory)
        b2Next=b2;   //copy assignment (not move memory)
        b1=std::move(b1Next);   //move memory
        b2=std::move(b2Next);   //move memory 
        //clean up previous "vPtr" (not shown)
    }
};

它有效,但是代码变得更难进行调试/维护。更不用说C的移动和复制了。

在旧版本中,所有copy/move杂物仅出现在B1B2中。
现在,混乱出现在每个使用B1B2等数据结构的类中。

问题

什么是可以帮助您的C 技术/Design-Pattern/IDIOM?
要回答,不需要可运行的代码。伪代码或仅概念就足够了。

我很遗憾不提供MCVE。
自定义分配器和数组管理确实是最小化的很难。

提高数据局部性的一种可能性是从vector s的structstruct s的vector。而不是

struct S
{
    std::vector<char> c;
    std::vector<int> i;
};
S data;

使用

struct S
{
    char c;
    int i;
};
std::vector<S> data;

这样,数据始终被存储在一起,您无需使用自定义分配器来修补。这是否适用于您的情况主要取决于两个条件:

  • 是否有必要让所有char(或int)连续?例如。因为定期称为API,需要相应类型的vector
  • 存储的charint的数量相等(至少几乎相等)?