2013-12-11 2 views
1

Я пытаюсь разработать следующий блокировки свободного кода (C++ 11):блокировки свободного программирования - C++ атомное

int val_max; 
std::array<std::atomic<int>, 255> vector; 

    if (vector[i] > val_max) { 
    val_max =vector[i]; 
    } 

Проблема в том, что при наличии большого числа нитей (128 потоков), результат неверно, потому что, если, например, val_max = 1 и три потока (с вектором [i] = 5, 15 и 20) будут выполнять код в следующей строке, и это будет гонка данных.

So , Я не знаю, как лучше всего решить проблему с доступными функциями в C++ 11 (я не могу использовать мьютекс, блокировки), защищая весь код.

Любые предложения? Заранее спасибо!

+0

Опишите, чего вы хотите достичь. – chill

+1

Возможно, это решит вашу проблему http://stackoverflow.com/questions/16190078/how-to-atomically-update-a-maximum-value – chill

+1

Большая проблема в том, что даже если вы избавитесь от гонки данных, Конфликт на 'val_max' станет узким местом и убьет все преимущества производительности, которые вы ожидали от многопоточного решения. Ваш алгоритм кажется ошибочным, но поскольку вы не писали то, что пытались достичь, вам сложно помочь в его исправлении. – ComicSansMS

ответ

3

Необходимо описать проблему с большей проблемой, которую вы должны решить, и о том, почему требуется много потоков для этого.

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

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

+0

Как я писал ранее, это всего лишь требование (количество потоков и блокировка). Как вы сказали, я дал каждому потоку кусок массива, но проблема в том, что при выполнении 128 потоков иногда они выполняют одну и ту же строку, и у меня есть неправильное значение ... – Javi

+1

Они должны дать им локальные максимумы и в концевой совокупности. Если у вас нет отдельного потока, чтобы суммировать это, вам нужно сделать конечный атомарный max_val и использовать цикл compare_exchange для его установки. –

1
  1. Сделайте атомную выборку val_max.
  2. Если значение выбрано больше или равно vector[i], остановитесь, все готово.
  3. Проведите обмен атомарным атомом - сравните val_max со значением, которое вы читаете на шаге 1, и обмениваете его на значение vector[i], если оно сравнивается.
  4. Если сравнение выполнено успешно, остановитесь, все готово.
  5. Перейдите к шагу 1, вы мчались с другим потоком, который продвигался вперед.
Смежные вопросы