Странная проблема параллелизма с STL / OpenMP в 64-битных сборках

У меня странная проблема, когда я создаю один из наших проектов в 64-битной конфигурации отладки. Похоже, что это вызывает какое-то странное поведение, которое немного похоже на то, что один итератор увеличивается несколько раз. Я сузил его до следующего тестового кода:

#include <omp.h>

#define _HAS_ITERATOR_DEBUGGING 0

#include <vector>
#include <set>

int main(int argc, const char* argv[]) {    
   std::vector<int> v;
   for(int j = 0; j < 20; ++j) {
      v.push_back(j);
   }

   #pragma omp parallel for
   for(int i = 0; i < 100000; ++i) {
      std::set<int> s;
      std::vector<int>::const_iterator begin = v.begin(), end = v.end();
      s.insert(begin, end); // after this line s should contain the numbers 0-19
      if(s.size() != 20) {
         printf("fail\n");
         exit(3);
      }
   }
   return 0;
}

Однако тест размера часто терпит неудачу, что означает, что каким-то образом он не вставляет все содержимое вектора - и из-за того, что в него много тыкают, он выглядит скорее как векторные итераторы увеличиваются более чем на один шаг за раз. Это' Хотя это довольно сложно сказать, поскольку этого не происходит, если кто-то взламывает отладчик.

Очевидный вывод, который можно сделать, будет заключаться в том, что это не потокобезопасно, но я понимаю, что это должно быть, потому что изменилась единственная переменная s , имеющий локальную область видимости.

Есть несколько вещей, которые помогут решить непосредственную проблему:

  • удалить параллель для
  • ; создать критическую секцию вокруг вызова insert ()
  • #define HAS_ITERATOR_DEBUGGING 1
  • замените единственный вызов insert () ручным циклом и вставьте каждый элемент по отдельности (это в основном то, что эта функция делает внутри, но проблема определенно исчезнет, ​​когда я сделаю это сам)
  • создаю 32-битную версию того же кода
  • создаю окончательную версию того же кода

Это компилируется под MSVC ++ 2008 SP1, с компилятором- поставляемая реализация STL.

Может ли кто-нибудь пролить свет на то, что здесь происходит? Заранее благодарим за любые подсказки - я в большом тупике :)

Edit: Если это не ясно, я не ищу «быстрого исправления», чтобы заставить этот код работать; как отмечалось выше, я знаю довольно много из них. Я хочу понять, почему эта проблема возникает в первую очередь.

Редактировать 2: Код работает правильно при компиляции с помощью gcc.

11
задан Peter 16 April 2011 в 22:36
поделиться