c++ - 重构以减少微小内存分配“ClassC[massive]::ClassB[]::int[tiny]”的“频率”(时间量)
问题描述
我想存放int[]
在里面B
并存B[]
放在里面C
。
还有其他领域的行为方式相同。
在特定的运行时情况下,我知道在代码范围内创建的所有向量(.bf1
、.bf2
、.cf1
和)必须具有一定的大小(例如、、.cf2
和)。cs
num_bf1
num_bf2
num_cf1
num_cf2
num_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 个堆栈分配器。
但是,我认为这种方法太低级了。这是一个固定的地方,在另一个遥远的地方解决问题。我认为正确的解决方案是修复微型阵列的创建,而不是创建一个库来支持这种不良做法(?)。
问题
如何优雅地解决这个小阵列问题?
解决方案
推荐阅读
- css - 手机上的 webkit 盒子和线夹
- reactjs - 如何更改 recharts 图表中的工具提示 dataKey
- android - 在 android Webview 中写入权限
- java - 如何让滚动按钮使用java放大和缩小对象
- javascript - 从 urql 查询数据存储中设置分页组件中的属性会导致页面挂起
- python-3.x - 我能够在不使用 setter 方法的情况下将私有变量设置为另一个值。这怎么可能?它是在创建新参数吗?
- r - 如何使用 R 将每天 1 列的数据集转换为只有 1 个日期列(天)
- android - 将自定义视图动态添加到 RelativeLayout 时出现 Logcat 错误
- flutter - 如何在按钮单击时在两个图像之间切换?
- excel - 如何通过excel中的每一列(包含信息)运行代码?