Понимание использования memset в коде устройства CUDA

У меня есть линейный int массив arr, который находится на глобальной памяти CUDA. Я хочу установить подмассивы arr до определенных значений. Начальные индексы подмассива задаются starts массив, в то время как длина каждого подмассива указана в counts массив.

Что я хочу сделать, это установить значение подмассива i начиная с starts[i] и продолжая до counts[i] к стоимости starts[i], То есть операция это:

arr[starts[i]: starts[i]+counts[i]] = starts[i]

Я думал об использовании memset() в ядре для установки значений. Тем не менее, он не записывается правильно (элементам массива присваиваются некоторые случайные значения). Код, который я использую:

#include <stdlib.h>
__global__ void kern(int* starts,int* counts, int* arr,int* numels)
{
unsigned int idx = threadIdx.x + blockIdx.x*blockDim.x;

if (idx>=numels[0])
return;

const int val = starts[idx];
memset(&arr[val], val, sizeof(arr[0])*counts[idx]) ;
__syncthreads();
}

Обратите внимание, что numels[0] содержит количество элементов в starts массив.

Я проверил код с cuda-memcheck() но не получил никаких ошибок. я использую PyCUDA, если это актуально. Я, вероятно, неправильно понимаю использование memset здесь, поскольку я изучаю CUDA.

Можете ли вы предложить способ исправить это? Или другой эффективное способ сделать эту операцию.

П.С .: Я знаю это thrust::fill() Возможно, я смогу сделать это хорошо, но так как я изучаю CUDA, я хотел бы знать, как это сделать без использования внешних библиотек.

0

Решение

Реализации memset и memcpy в коде устройства CUDA генерируют простые последовательные операции с байтовыми значениями (и обратите внимание, что memset не может устанавливать ничего, кроме байтовых значений, что может способствовать возникновению проблемы, которую вы видите, если значения, которые вы пытаетесь установить, являются больше 8 бит).

Вы можете заменить вызов memset чем-то вроде этого:

const int val = starts[idx];
//memset(&arr[val], val, sizeof(arr[0])*counts[idx]) ;
for(int i = 0; i < counts[idx]; i++)
arr[val + i] = val;

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

Обратите внимание также, что __syncthreads() Вызов в конце вашего ядра является ненужным и потенциальным источником тупика и должен быть удален. Увидеть Вот для дополнительной информации.

0

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

Других решений пока нет …

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