Расширенные проблемы с расхождением потоков графического процессора

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

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

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

t = 0, 1, 2, 3, 4, … 63, 64, 65, 66, 67, …
M1 0, 0, 0, 9, 9, … 9, 0, 0, 0, 9, …

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

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

ВОПРОС — Может ли расхождение потоков иметь тенденцию приводить к неправильным вычислениям или неопределенному поведению потоков?

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

Любой вклад будет принята с благодарностью. Спасибо!

0

Решение

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

1

Другие решения

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

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

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

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

0

По вопросам рекламы [email protected]