Если я неправильно истолковал ваш вопрос, вам не нужно и не следует использовать общую память для этой операции.Общая память полезна для совместного использования и возобновления данных между потоками в одном блоке, а также для облегчения доступа к объединенной памяти.Похоже, что ваша операция не требует ни одной из этих вещей для правильной работы.Использование общей памяти так, как вы предлагаете, вероятно, будет медленнее , чем простое чтение из глобальной памяти напрямую.Кроме того, поскольку вас беспокоят только поэлементные операции, схема индексации вашего ядра может быть значительно упрощена - тот факт, что A
, B
, C
и D
являются "матрицами", не имеет отношения квычисления, как я понимаю ваш вопрос.
В результате, почти оптимальная версия вашего ядра может быть записана так же просто, как
__global__ void kernel(const float *A, const float *B, const float *C,
const float *D, const int n, float *R)
{
int tidx = threadIdx.x + blockIdx.x * blockDim.x;
int stride = blockDim.x * gridDim.x;
while(tidx < n) {
R[tidx] = A[idx] * sinf(B[idx]) + C[idx]*cosf(D[idx]);
tidx += stride
}
}
В этом коде вы запустите столько блоков, сколькодостигнет пиковой пропускной способности вашего графического процессора, и каждый поток обработает более одного значения ввода / вывода, если размер массива превысит размер оптимальной 1D сетки, которую вы запустили.Конечно, это довольно академично, если вы обрабатываете всего 4096 элементов - это, вероятно, на 2 порядка меньше, чтобы получить какую-либо выгоду от использования графического процессора.