3

帮派。首先,对问题和方法的高级描述。

我有一个包含每个图像中的图像和像素位置的列表 - 一个列表列表。我想从该图像列表中随机选择n 个项目,并且对于每个图像我想迭代k个随机像素位置。我想并行执行此操作。对于每个处理过的像素,我希望将其从列表中删除。

我的方法是在所有线程之间分配图像和像素列表——因此每个线程都有自己的图像列表和像素位置列表,但没有两个线程会同时处理同一个图像。我将这些存储到一个向量中。

所以假设代码看起来像这样:

struct MyObject
{
  // Image index on disk
  int imageIndex_;
  // List of x,y locations
  std::list< Point > pixels_;
};

std::vector< std::list < MyObject > > mainList(NUM_THREADS);

然后,mainList[0]将包含要由 id 为 0 的线程处理的图像。我以以下方式启动线程:#pragma omp parallel num_threads(numThreads_)然后它们都运行同一段代码,该代码从线程的图像列表中随机采样图像。

问题是,当一个像素被处理并且一个线程从像素列表中删除它时,例如mainList[0].begin()->pixels_.erase(someIter),我有时会得到一个断言;它追溯到删除运算符。

我知道写入 std::list 不是线程安全的,但我很确定它对于列表列表是安全的,其中主列表中的每个列表只能由一个线程访问。我知道我提供了有限的代码,但问题归结为从列表列表(或列表向量)中并行删除,当每个线程一次只能访问一个列表并且列表不在线程之间共享时。

我在这里想念什么?我不能从列表列表的向量中并行删除吗?

4

1 回答 1

1

您提供的信息太少,我无法猜测真正的问题,这里有一些想法:

您似乎访问了无效的迭代器(即两次删除一个元素)。这可能是由竞争条件或代码中的错误导致的,该错误确实试图多次删除项目。例如 - 你确定你生成的随机数是唯一的吗?您是否在删除每个元素后将模运算符应用于生成的随机数以确保索引有效?

我首先要检查的是在禁用 OpenMP 的情况下运行程序。然后,您可以决定断言是由于竞争条件还是由于另一个错误而失败。

在不相关的注释上 - 您可能想要使用std::vector而不是std::list. 您正在访问容器中的随机元素,并std::vector针对随机访问进行了优化。

于 2010-10-14T20:12:14.543 回答