Я предполагаю:
- Массив, который вы хотите отсортировать, мал (<100 элементов) </li>
- Это часть более крупного алгоритма графического процессора
- массив находится в общей памяти или может быть скопирован туда
Если что-то из этого не соответствует действительности, не делайте пузырьковую сортировку!
количество потоков вблок составляет половину размера массива.Это хорошая реализация?
Это разумно.Когда в деформации возникает расходящаяся ветвь, все потоки выполняют все ветви в идеальной синхронизации, просто у некоторых потоков установлен флаг «отключен».Таким образом, каждая ветвь выполняется только один раз .Единственное исключение - когда ни один поток из деформации не принимает ветвь - тогда ветвь просто пропускается.
BUG!
В вашем коде,однако я вижу проблему.Если вы хотите, чтобы один поток работал с двумя элементами массива, сделайте так, чтобы они обрабатывали его исключительно, то есть:
if(a[2*threadIdx.x]>a[2*threadIdx.x + 1])
Swap(a[2*threadIdx.x] , a[2*threadIdx.x + 1]);
В противном случае, если Swap
выполняется двумя соседними потоками, некоторые значения могут исчезнуть инекоторые другие значения могут дублироваться в массиве.
Еще одна ошибка!
Если ваш блок больше, чем размер деформации, не забудьте поставить __syncthreads()
при необходимости.Даже если ваш блок меньше (не должен быть), вы должны проверить __threadfence_block()
, чтобы убедиться, что записи в разделяемую память видны другим потокам того же блока.В противном случае компилятор может быть слишком агрессивен в отношении оптимизаций и сделать ваш код недействительным.
Другая проблема
Если вы исправите первую ошибку, у вас будет банк с 2-мя путямиконфликт в вашей общей памяти.Это не очень важно, но вы можете реорганизовать данные в вашем массиве, чтобы избежать их, например, располагать последовательные элементы в следующем порядке:
[1, 3, 5,7, 9, ..., 29, 31, 2, 4, 6, 8, ..., 30, 32]
Таким образом, элементы 1 и 2 принадлежат одному и тому же банку в общей памяти.