Нет, невозможно выделить выделение общей памяти (статической или динамической) определенному потоку. Совместно используемая память имеет только область видимости блока.
Однако вполне возможно разработать схему индексирования, при которой потоки внутри блока используют исключительно уникальные местоположения в распределении общей памяти области действия блока. Например:
template<int nthreads, int words_per_thread>
__global__
void kernel(..)
{
__shared__ int buffer[nthreads * words_per_thread];
int* localbuff = &buffer[threadIdx.x * words_per_thread];
// localbuff is now safely indexed from [0] to [words_per_thread-1]
}
Другой возможный метод будет выглядеть примерно так:
#include <stdio.h>
template<typename T>
class sr_
{
T *sp;
public:
__device__
sr_(T *_sd) { sp = _sd;}
__device__
T &operator[](int idx){return sp[blockDim.x*idx+threadIdx.x];}
};
// for statically allocated shared memory
#define SREG(size,type,block_size) \
__shared__ type SREG_sdata[size*block_size]; \
typedef type SREG_type; \
sr_<SREG_type> sreg(SREG_sdata);
// for dynamically allocated shared memory
#define DSREG(type) \
__shared__ type SREG_sdata[]; \
typedef type SREG_type; \
sr_<SREG_type> sreg(SREG_sdata);
const int BS = 8;
__global__ void k2(){
SREG(8,float,BS)
sreg[0] = 1.0f;
printf("%f\n", sreg[0]);
}
int main(){
k2<<<1,BS>>>();
cudaDeviceSynchronize();
}
Преимущества этого метода в том, что у одного потока нет возможности индексировать пространство другого потока, итакже, что не может быть никаких банковских конфликтов. Обратите внимание, что это не будет обрабатывать все варианты использования. Его необходимо изменить, например, если бы в одном модуле было несколько ядер, которые использовали разные типы данных для совместной памяти.