Распараллеливание OpenMP и удаление из вектора списков - PullRequest
3 голосов
/ 14 октября 2010

Банда. Во-первых, общее описание проблемы и подхода.

У меня есть список, содержащий изображения и расположение пикселей на каждом изображении - список списков. Я хочу выбрать 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] будет содержать изображения для обработки потоком с идентификатором 0. Я запускаю потоки следующим образом: #pragma omp parallel num_threads(numThreads_), а затем все они запускают один и тот же фрагмент кода, который случайным образом выбирает изображения из списка изображений потока.

Проблема в том, что когда пиксель обрабатывается и поток удаляет его из списка пикселей, например mainList[0].begin()->pixels_.erase(someIter), I иногда получают утверждение; он отслеживает оператор удаления.

Я знаю, что запись в std :: list не является поточно-ориентированной, но я был уверен, что она безопасна для списка списков, где каждый список в основном списке доступен только одному потоку. Я знаю, что предоставил ограниченный код, но проблема сводится к параллельному удалению из списка списков (или вектора списков), когда каждый поток имеет доступ только к одному списку за раз, и списки не разделяются между потоками.

Что мне здесь не хватает? Не могу ли я удалить из вектора списки списков параллельно?

1 Ответ

1 голос
/ 15 октября 2010

Вы предоставили мне слишком мало информации, чтобы угадать реальную проблему, вот несколько мыслей:

Вы, похоже, получаете доступ к недействительным итераторам (т.е. удаляете один элемент дважды). Это может быть вызвано состоянием гонки ИЛИ ошибкой в ​​вашем коде, которая действительно пытается удалить элемент более одного раза. Например, вы уверены, что сгенерированные вами случайные числа уникальны? Применяете ли вы оператор по модулю к сгенерированным случайным числам после удаления каждого элемента, чтобы убедиться, что индекс действителен?

Сначала я бы запустил программу с отключенным OpenMP. Затем вы можете решить, является ли утверждение неверным из-за состояния гонки или из-за другой ошибки.

На несвязанной заметке - вы можете использовать std::vector вместо std::list. Вы получаете доступ к случайным элементам в контейнере, и std::vector оптимизирован для произвольного доступа.

...