Мне нужно переместить каждый из первых k элементов 1-D массива на смещение , где смещения монотонно возрастают, т. Е. Если смещение для элемента i смещено 1 , тогда элемент i + 1 имеет смещение, offset2, которое удовлетворяет: offset2> = offset1.CUDA: как перемещать элементы массива
Я написал ядро, которое выполняется на каждом из первых к элементов:
if (thread_id < k) {
// compute offset
if (offset) {
int temp = a[thread_id];
__synchthreads();
a[thread_id + offset] = temp;
}
}
Однако при испытании при к = 3, смещение действительно монотонно возрастает, а именно 0, 1, 1. Элемент 0 остается в своем положении так, как ожидалось. Однако элемент 1 копируется не только на элемент 2 (в соответствии со смещением для элемента 1), но также на элемент 3.
То есть, кажется, что поток 2 считывает элемент 2 и сохраняет его в своей копии temp только после того, как поток 1 завершил копию элемента 1 на элемент 2.
Что я делаю неправильно и как его исправить?
Спасибо!
Обратите внимание, что '__syncthreads()' только обеспечивает барьер для потоков внутри блока. Таким образом, этот метод будет разорваться, как только вы перейдете к более чем одному блоку в своей сетке. Кроме того, если вы делаете что-то глупое, например, запускаете сетку потоков, каждый из которых имеет только один поток, тогда код будет разрываться повсюду. Возможно, вам следует показать полное представление вашего ядра вместе с вызовом ядра и вычислением параметров запуска. Вы можете просто отредактировать свой вопрос с помощью этой информации, не пробуйте и не добавляйте ее в комментарии. –
Да, я неправильно выполнял 3 блока по 1 нити каждый. Он отлично работает с 1 блоком из 3 потоков. Однако это ограничение ограничено 1024 потоками на блок на Tesla K20. Как перемещается более 1024 элементов? Перемещая один блок по 1024 за один раз, завершив работу, прежде чем сделать еще один блок из 1024 и т. Д.? – user1760748
также, '__syncthreads()' внутри условного блока вроде этого не гарантируется. Прочитайте [здесь] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#synchronization-functions) о syncthreads в условном коде. Что касается того, как заставить его работать с несколькими блоками потоков, вам понадобится другой алгоритм, который будет распараллеливаться.Я не думал об этом широко, но мне кажется, что если ваш выходной вектор отличается от вашего входного вектора, вы бы полностью избегали этой опасности. –