首页 > 解决方案 > 重构以减少微小内存分配“ClassC[massive]::ClassB[]::int[tiny]”的“频率”(时间量)

问题描述

我想存放int[]在里面B并存B[]放在里面C
还有其他领域的行为方式相同。

在此处输入图像描述

在特定的运行时情况下,我知道在代码范围内创建的所有向量(.bf1.bf2.cf1和)必须具有一定的大小(例如、、.cf2和)。csnum_bf1num_bf2num_cf1num_cf2num_c

#include <iostream>
#include <vector>
class B{public:
    std::vector<int> bf1; //b's field 1   <---------
    std::vector<float> bf2;//b's field 2
    //... many of it
};
class C{public:
    std::vector<B> cf1;  // <---------
    std::vector<int> cf2;
    //... many of it
};
int main(){
   //"num_xxx" are known only after some complex algo only at run time.
   //    Their value are also different for each game time-step.
    int num_bf1=3;   // <---------
    int num_bf2=4;
    int num_cf1=2;   // <---------
    int num_cf2=8;
    int num_c=6;
    std::vector<C> cs;
    for(int m=0;m<num_c;m++){
        C c;
        for(int n=0;n<num_cf1;n++){
            B b;
            b.bf1.resize(num_bf1);   // <---------
            b.bf2.resize(num_bf2);
            c.cf1.push_back(b);      // <---------
        }
        c.cf2.resize(num_cf2);
        cs.push_back(c);  // "cs" is now finished as i wish
    }
}

它可以工作,但这段代码有一个丑陋的瓶颈。
在实际情况下,仅内存分配就使用了约 35% 的 CPU 时间

我的糟糕做法

我想通过分配大内存并拆分它来避免它。

有了 的已知值num_xxx,我可以计算出int想要C::B::bf1的数量。

在此处输入图像描述

因此,我可以std::vector<int> bf1; bf1.resize(num_c*num_cf1*num_bf1);

这是完整的代码:-

#include <iostream>
#include <string>
#include <vector>
#include <cmath>

class B{public:
    int* bf1; //b's field 1
    float* bf2;//b's field 2
    //... many of it
};
class C{public:
    B* cf1;
    int* cf2;
    //... many of it
};

这是新的主要内容:-

int main(){
    int num_bf1=3;
    int num_bf2=4;
    int num_cf1=2;
    int num_cf2=8;
    int num_c=6;
    std::vector<C> cs;
    std::vector<int> bf1;  bf1.resize(num_c*num_cf1*num_bf1);
    std::vector<float> bf2;  bf2.resize(num_c*num_cf1*num_bf2);
    std::vector<B> cf1;  cf1.resize(num_c*num_cf1);
    std::vector<int> cf2;  bf2.resize(num_c*num_cf2);
    
    for(int m=0;m<num_c;m++){
        C c;
        for(int n=0;n<num_cf1;n++){
            B* b=&(cf1[m*num_cf1+n]);
            b->bf1=&bf1[(m*num_cf1+n)*num_bf1];
            // .... something about bf2 that is hard ...
           
        }
        c.cf1=&(cf1[m*num_cf1+0]);
        // .... something about cf2 that is hard ...
        cs.push_back(c);
    }
}

这使我的程序更快,但它很难编码,导致可维护性可读性的噩梦。

我的糟糕方法 V.2

我尝试使用自定义堆栈分配器(并计划使用单帧分配器)。

问题是,在多线程中,分配器的互斥锁经常被调用和阻塞。
一种解决方案是为每个线程创建 1 个堆栈分配器。

但是,我认为这种方法太低级了。这是一个固定的地方,在另一个遥远的地方解决问题。我认为正确的解决方案是修复微型阵列的创建,而不是创建一个库来支持这种不良做法(?)。

问题

如何优雅地解决这个小阵列问题?

标签: c++memory-managementc++17allocation

解决方案


推荐阅读