在大型并发数组中组织已使用和未使用元素的有效方法

时间:2011-01-16 03:34:00

标签: c++ visual-studio-2008 memory-management concurrency

我在数组中有大约1800万个元素被初始化并准备好被一个名为ElementManager的简单管理器使用(这个数字稍后会在程序的后续迭代中攀升到略多于10亿) 。必须使用元素的类AElementManager通信,返回下一个可供使用的元素。该元素现在正在使用中,并且在再循环之前不能重复使用,这可能经常发生。类A是并发的,也就是说,它可以向ElementManager询问多个线程中的可用元素。在这种情况下,元素是一个存储三个顶点以形成三角形的对象。

目前,ElementManager正在使用名为mAllAvailableElements的英特尔TBB concurrent_bounded_queue。还有另一个容器(TBB concurrent_vector)包含所有元素,无论它们是否可用,都称为mAllElements。类A要求下一个可用元素,管理器尝试从队列中弹出下一个可用元素。弹出的元素现在正在使用中。

现在当课程A完成了它必须做的事情时,控制权交给了课程B,现在必须遍历in use的所有元素并创建网格 (为了利用并发性,数组被分成几个较小的数组来创建子网,这些子网可以根据可用线程的数量进行扩展 - 原因是创建网格必须连续完成)。为此我正在迭代容器mAllElements(这也是并发)并抓取任何正在使用的元素。如上所述,元素包含用于创建网格的多边形信息。在这种情况下进行迭代需要很长时间,因为它必须检查每个元素并查询它是否正在使用,因为如果它不是正在使用那么它不应该成为网格的一部分。

现在想象一下,如果在可能的1800万个元素中只有100万个正在使用(但超过5-6百万个被回收)。更糟糕的是,由于仅对网格的一部分进行不断更新(同时发生)意味着 in use 元素在整个mAllElements容器中被分段。

我已经考虑了很长一段时间了,我提出的一个有缺陷的解决方案是创建另一个名为mElementsInUse的元素队列,它也是concurrent_queue。我可以推送现在正在使用的任何元素。这种方法的问题在于,由于它是一个队列,该队列中的任何元素都可以随时回收(网格的一部分更新)并声明未使用,因为我只能弹出前面元素,这种方法失败了。我能想到的另一种方法是在没有进行任何操作的情况下每隔一段时间对concurrent_vector mAllElements进行碎片整理。

我认为我解决这个问题的方法是错误的,因此我的帖子在这里。我希望我能够详细解释这个问题。这似乎是一个常见的内存管理问题,但我无法想出任何搜索条件来搜索它。

1 个答案:

答案 0 :(得分:0)

如何使用位向量来指示您正在使用哪些元素?在构建完整网格时,可以很容易地对其进行分区以进行并行处理,并且可以对向量中的单词使用原子操作,从而避免锁定。