对于进化算法,我需要一个容器来存储一群个体 - 即一个对象的矢量。我需要在每次迭代时对该向量进行排序,这应该是有效的。此外,我想避免缓存未命中,所以我想预先批量分配整个人口(其大小已知且已修复)。但是,我不满足于类的默认构造函数,但是想在每个对象上调用特定的构造函数。
我在当前代码上运行cachegrind
,发现Individual::operator <(const Individual &other)
中出现的最大缓存未命中数是我对谓词进行排序的谓词。由于我的人口按每次迭代排序,我认为此时的优化会给我带来最大的好处。我在operator <()
中解释了缓存未命中以阻止Individual
对象在我的系统内存上的分布 - 如果不是这样的话,我会在访问者函数中看到缓存未命中,例如{存储个人参数的{1}},对吗?
根据我的要求,我选择了std::vector<double>
。主要是因为它允许我(a)将我的对象保存在一块内存中,同时提供不会创建和销毁临时对象的boost::ptr_vector
实现。
现在,为了避免缓存未命中,我想将整个人口分配成一个整体。我想做的事情就是......
sort()
但是,我不确定如何实现这一点,以便不违反空间局部性的概念(即,我想避免缓存未命中)。我可以愉快地循环:
boost::ptr_vector<Individual> population;
auto *rawPopulaton = new Individual[populationSize](templateObject);
population.transfer(population.begin(), rawPopulation, populationSize);
return population;
...但我担心这会导致我的人口分布在不同的记忆块上。
所以这里实际上有两个问题:
答案 0 :(得分:1)
我选择了boost :: ptr_vector。主要是因为它允许我(a)将我的对象保存在一块内存中
它没有做到这一点。您的transfer
方法已接近,但
同时提供sort()的实现,它不会创建和销毁临时对象。
您可能正在寻找stable_vector
或侵入式容器。
我的设计选择是否符合优化目标?
我不确定,但我对此表示怀疑。 (你有没有描述过你的瓶颈?你似乎建议重新排序应该为顺序访问重新排序。在这种情况下,只需使用vector<X>
而不是ptr_vector<X>
?)
如何批量分配人口并调用特定的构造函数?
您是否考虑过std::fill[_n]
和std::generate[_n]
?