2013-07-25 3 views
0

Моя ситуация - У меня есть алгоритм динамического программирования для реализации на графических процессорах с использованием OpenCL в рамках моих исследований по PhD. В GPU, с которыми я работаю, входят AMD HD 7970, 7750, A10-5800K APU и nVidia GTX 680. Я понимаю принципы и большинство лучших практик, необходимых для обеспечения хорошей производительности.Продвинутые проблемы с расхождением нитей GPU

Моя программа содержит 4 вложенных цикла и в моей параллельной форме данных я могу развернуть 2 внешних контура. Теперь из-за природы проблемы внутренний цикл не может обойтись без возникновения расхождения. Результатом является таблица, которая представляет графики рабочих мест на машинах (информатика).

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

т = 0, 1, 2, 3, 4, ... , 64, 65, 66, 67, ...
М1 0, 0, 0, 9, 9, ... 9, 0, 0, 0, 9, ...

над размером рабочей группы - 64. Первые значения до t = 63 являются правильными, но обратите внимание, как они повторяются снова ровно с t = 64 ! Они не должны быть нулями. Здесь каждый рабочий элемент отображается в момент времени t.

Если я исправляю параметр, который вызывает расхождение, таблица полностью заполняется ожидаемыми (неправильными) результатами, без пробелов (нулей), поэтому я получаю значение 9 от t = 0 до TMAX, где TMAX является множественным от 64.

ВОПРОС - Есть ли отклонения в потоках в результате неправильных вычислений или неопределенного поведения ниток?

Я вырыл Интернет, документацию, книги на все, что я могу найти о расхождениях потоков и последовательности памяти. Я реализовал всю программу по-разному, включая ту, которая вызывает ядро ​​несколько раз, чтобы исключить несогласованность глобальной памяти, но результаты все одинаковы.

Любой вход будет оценен с большой благодарностью. Благодаря!

ответ

0

Я думаю, что ваша проблема проста: вы заставляете первые 64 потока запускать и заканчивать до следующих 64 потоков. Это НЕ верно, все они работают параллельно.

Фактически, вы должны предположить, что весь ваш размер рабочей группы GLOBAL будет работать параллельно или даже в недетерминированном порядке (от конца до начала). Единственное ограничение, которое пользователь может выполнить с помощью ядра, в том, что каждый фрагмент потоков (размер локальной рабочей группы) будет работать одновременно. Это помогает совместному использованию промежуточных результатов или совместного доступа к памяти.

В вашем случае, если локальная рабочая группа использует в качестве начальной точки глобальную память, то первая рабочая группа из 64 нитей и вторая будут давать одинаковые результаты.

Пожалуйста, пересмотреть свой код/​​алгоритм, чтобы сделать это на самом деле параллельно. Будет также полезной паста из вашего кода ядра.

+0

Большое спасибо за ввод. Я понимаю, что вы пытаетесь объяснить, особенно потому, что я имею дело с динамическим программированием.Каждый промежуточный результат вычисляется GLOBALLY, потому что это можно сделать параллельно, так что NDRange отлично :) – oogway

1

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

Смежные вопросы