Я кодировал ядро CUDA, которое выполняет добавление массивов из двух массивов arr1
и arr2
. Информация о том, какой индекс arr1
должен быть добавлен, с каким индексом arr2
хранится в массиве idx
.
Вот пример кода:
__global__ add(float* arr1, float* arr2, int* idx, int length)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
// each thread performs (length) additions,
// arr2 is (lenght) times larger than arr1
for (int j=threadIdx.x; j<length*blockDim.x; j+=blockDim.x)
{
arr1[i] += arr2[ idx[blockIdx.x*blockDim.x + j] ]; // edited here
}
}
Код выдает правильный вывод, хотя он чуть быстрее, чем код openmp-параллельный на ЦП с 8 потоками. Я пробовал это для разных размеров блока.
Я подозреваю, что шаблон доступа к arr2
неэффективен, поскольку arr2
находится в глобальной памяти и доступен почти случайно - массив idx
содержит уникальные, отсортированные, но несмежные индексы (может быть 2, 3, 57, 103, ...). Поэтому кеш L1 не используется.
Кроме того, массивы очень большие и не могут полностью поместиться в общей памяти.
Есть ли способ обойти это препятствие?
У вас есть идея, как оптимизировать схему доступа к arr2
?