C++ 是否可以使多索引容器使用连续内存?
这里我有一个简单的multi_索引容器,我想知道是否有办法强制multi_索引在内存中连续分配元素。我认为如果主索引是C++ 是否可以使多索引容器使用连续内存?,c++,memory,boost-multi-index,C++,Memory,Boost Multi Index,这里我有一个简单的multi_索引容器,我想知道是否有办法强制multi_索引在内存中连续分配元素。我认为如果主索引是随机访问,这是可能的 然而,这个简单的示例显示,这些元素在内存中意外地不连续是否存在可能导致连续内存的组合boost::multi_index::index_by #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #includ
随机访问
,这是可能的
然而,这个简单的示例显示,这些元素在内存中意外地不连续是否存在可能导致连续内存的组合boost::multi_index::index_by
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
int main(){
typedef boost::multi_index_container<
double, // simply store doubles
boost::multi_index::indexed_by<
boost::multi_index::random_access<>
>
> random_access_container;
random_access_container v; // fill container
v.reserve(10); // also tried this
v.push_back(1.);
v.push_back(2.);
v.push_back(3.);
assert( v[0] == 1. ); // ok
assert( *(&v[0] + 1) == v[1] ); // this fails, memory is not contiguous
}
#包括
#包括
#包括
#包括
#包括
int main(){
typedef boost::多索引容器<
double,//只存储double
boost::多索引::按索引索引<
boost::多索引::随机访问
>
>随机存取容器;
随机访问容器v;//填充容器
v、 保留(10);//也尝试过这个
v、 向后推(1);
v、 向后推(2);
v、 向后推(3);
断言(v[0]==1.);//确定
assert(*(&v[0]+1)==v[1]);//此操作失败,内存不连续
}
注1:我希望这样做是为了兼容性(这样我可以利用multi_index
容器--与其他访问选项--),但也可以使用直接内存访问(就像std::vector
一样)
注2:我刚从文档中找到这句话,所以看起来很难
除非另有说明或相应接口不存在,
随机访问索引验证的容器要求与
std::vector加上std::列表特定列表的要求
[list.ops]上的操作。与
关于std::vector,如下所示:
不,你没有记忆连续性。随机访问索引的布局类似于: 如果将元素(例如
T
)存储在std::vector
中,然后使用std::ref
s的multi_index_容器
,则可以获得连续内存的近似值。当然,这会使对象生命周期管理复杂化
编辑:设计原理
内存连续性难以/难以包含在库设计中的原因有很多:
- 迭代器稳定性由所有索引提供,而不仅仅是随机访问索引。如果元素连续存储在内存块中,就不可能保持这种状态(具有合理的性能)
- 假设我们设法获得了一个随机访问索引,该索引导致了关于元素存储的内存连续性。如果我们有两个随机访问索引,会发生什么?似乎容器的第一个索引应该有一个特殊的地位,它决定了整个容器的布局,以使容器能够容纳水
- 非随机访问索引根据需要基于节点。这意味着每个值都存储在一个更大的结构中,并有空间容纳额外的信息(rb树指针等)。如果元素是连续存储的,那么a)将是连续存储的节点,而不是值本身,这看起来非常无用(想想
将返回什么),或者b)必须将节点与值分离,这样,我们就不用在节点中嵌入值,而是让节点具有指向连续存储值的指针,这是一种空间浪费,看起来不像是合理的默认决策data()
reserve
与此无关,因为它仅适用于索引的内部指针数组(参见图)。最后,我看不出什么节点连续性是有用的(特别是因为作为用户,您不知道节点类型)。@alfC我担心:reserve
只影响索引指针数组(我的响应中显示的图中的上向量),没有实际的节点是真正预先分配的。@alfC在一天结束时,multi\u index\u contaner
是一个基于节点的容器,在这方面的行为非常类似于,比如说,std::set
,它也没有保留。您可能希望使用基于池的分配器来查看这是否提高了效率和/或缓存位置。