搜索范围数组中的成员资格

时间:2010-02-12 16:29:13

标签: algorithm search

作为我们系统仿真的一部分,我使用稀疏存储器阵列建模具有64位寻址的存储空间,并保留对象列表以跟踪在存储器空间内分配的缓冲区。缓冲区是动态分配和解除分配的。

我有一个函数,在分配的缓冲区中搜索给定的地址或地址范围,以查看对内存模型的访问是否在分配的空间中,并且我的第一个剪切“搜索所有缓冲区,直到找到匹配“我们的模拟速度减慢了10%。我们的UUT进行了大量的内存访问,必须通过模拟进行审查。

所以,我正在努力优化。内存缓冲区对象包含起始地址和长度。我正在考虑通过在创建对象时启动地址来对对象数组进行排序,然后在调用检查函数时,通过数组进行二进制搜索,以查看给定地址是否属于开始/结束范围。

有更好/更快的方法吗?使用堆或散列签名或某些东西必须有一些更快/更冷的算法,对吧?

3 个答案:

答案 0 :(得分:2)

通过排序数组进行二进制搜索可以正常工作,但会使分配/释放变慢。

一个简单的例子是生成一个由起始地址索引的有序二叉树(红黑树,AVR树等),以便插入(分配),删除(解除分配)和搜索都是O(log n )。大多数现代语言已经提供了这样的数据结构(例如C ++的std::map)。

答案 1 :(得分:0)

我的第一个想法也是二元搜索,我认为这是一个好主意。您也应该能够快速插入和删除。使用哈希只会让你把地址放在桶中(在我看来)然后你会快速到达正确的桶(然后必须搜索桶)。

答案 2 :(得分:0)

基本上你的问题是你有一个“有效”内存的定义间隔,这些间隔之外的内存是“无效”,你想要检查一个给定的地址是否在有效的内存块内。

您可以通过在二叉树中存储所有已分配块的起始地址来实现此目的;然后搜索查询地址或其下方的最大地址,并验证该地址是否在有效地址的长度范围内。这为您提供了O(log n)查询时间,其中n =已分配块的数量。同样的查询当然也可以用来实际找到块本身,所以你也可以在给定的地址读取块的内容,我想你也需要。

但是,这不是最有效的方案。相反,您可以使用额外的一维空间细分树来标记无效的内存区域。例如,使用分支因子为256(对应于8位)的树,将所有仅具有无效地址的16kB块映射到“1”,将其他块映射到“0”;树只有两个级别,查询效率很高。当你看到一个地址时,首先询问这棵树是否确实无效;只有当它不是时,查询另一个。只有在您实际获得大量无效的内存参考时,这才能加快速度;如果所有内存引用实际上都是有效的并且您只是断言,则不会保存任何内容。但是你也可以翻转这个想法,并将树标记用于所有那些只有有效地址的16kB或256B块;树的增长程度取决于模拟内存分配器的工作方式。