У вас есть два варианта объявления общей памяти внутри ядра - статическая или динамическая. Я предполагаю, что то, что вы делаете в данный момент, выглядит примерно так:
#define BLOCK_SIZE (16)
__global__ void sgemm0(const float *A, const float *B, float *C)
{
__shared__ float As[BLOCK_SIZE][BLOCK_SIZE];
}
и вы хотели бы легко изменить BLOCK_SIZE.
Одна возможность - продолжать использовать статическое распределение совместно используемой памяти, но сделать размер выделения параметром шаблона, например так:
template<int blocksize=16>
__global__ void sgemm1(const float *A, const float *B, float *C)
{
__shared__ float As[blocksize][blocksize];
}
template void sgemm1<16>(const float *, const float *, float *C);
Затем вы можете создать столько разных вариантов размера блока во время компиляции, сколько вам нужно.
Если вы хотите динамически распределять память, определите ее следующим образом:
__global__ void sgemm2(const float *A, const float *B, float *C)
{
extern __shared__ float As[];
}
и затем добавьте размер выделения в качестве аргумента к вызову ядра:
size_t blocksize = BLOCK_SIZE * BLOCK_SIZE;
sgemm2<<< gridDim, blockDim, sizeof(float)*blocksize >>>(....);
Если у вас есть несколько статически объявленных массивов, которые вы хотите заменить динамически распределенной совместно используемой памятью, помните, что для каждого ядра выделяется только одно динамическое распределение совместно используемой памяти, поэтому несколько элементов выходят в пределах (разделяют) этот сегмент памяти. Так что, если у вас было что-то вроде:
#define BLOCK_SIZE (16)
__global__ void sgemm0(const float *A, const float *B, float *C)
{
__shared__ float As[BLOCK_SIZE][BLOCK_SIZE];
__shared__ float Bs[BLOCK_SIZE][BLOCK_SIZE];
}
Вы можете заменить его на:
#define BLOCK_SIZE (16)
__global__ void sgemm3(const float *A, const float *B, float *C)
{
extern __shared__ float buffer[];
float *As = &buffer[0];
float *Bs = &buffer[BLOCK_SIZE*BLOCK_SIZE];
}
и запустите ядро так:
size_t blocksize = 2 * BLOCK_SIZE * BLOCK_SIZE;
sgemm3<<< gridDim, blockDim, sizeof(float)*blocksize >>>(....);
Все они одинаково действительны, хотя я лично предпочитаю версию шаблона, потому что она может позволить другую оптимизацию компилятора, такую как автоматическое развертывание цикла, что динамическая версия не может без дополнительной работы.