Предположим, что у нас есть массив int * data
, каждый поток будет обращаться к одному элементу этого массива. Поскольку этот массив будет совместно использоваться всеми потоками, он будет сохранен в глобальной памяти.Стоит ли передавать параметры ядра через разделяемую память?
Давайте создадим тестовое ядро:
__global__ void test(int *data, int a, int b, int c){ ... }
Я знаю наверняка, что data
массива будет в глобальной памяти, потому что я выделил память для этого массива с помощью cudaMalloc
. Теперь, как и для других переменных, я видел несколько примеров, которые передают целое число без выделения памяти непосредственно на функцию ядра. В моем случае такими переменными являются a
b
и c
.
Если я не ошибаюсь, даже если мы не называем непосредственно cudaMalloc
выделить 4 байта для каждого три целых числа, CUDA автоматически сделает это за нас, так что в конце концов переменные a
b
и c
будут выделены глобальной памяти.
Теперь эти переменные являются вспомогательными, потоки только читают их и ничего больше.
Мой вопрос:, не лучше ли переносить эти переменные в общую память?
Я полагаю, что если бы мы, например 10
блоков с 1024
нитями, мы должны были бы 10*3 = 30
считывание 4
байт для хранения чисел в общей памяти каждого блока.
Без общей памяти и если каждый поток должен прочитать все эти три переменные один раз, общий объем чтения глобальной памяти будет 1024*10*3 = 30720
, что очень неэффективно.
Теперь вот проблема я несколько новых для CUDA, и я не уверен, если это возможно, чтобы передать память для переменных a
b
и c
к общей памяти каждого блока, не имея каждый поток читает эти переменные из глобальной памяти и загрузки их в разделяемую память, поэтому в итоге общий объем чтения глобальной памяти будет 1024*10*3 = 30720
, а не 10*3 = 30
.
На следующий website есть этот пример:
__global__ void staticReverse(int *d, int n)
{
__shared__ int s[64];
int t = threadIdx.x;
int tr = n-t-1;
s[t] = d[t];
__syncthreads();
d[t] = s[tr];
}
Здесь каждый поток загружает различные данные внутри общей переменной s
. Поэтому каждый поток, в соответствии с его индексом, загружает указанные данные внутри общей памяти.
В моем случае я хочу загрузить только переменные a
b
и c
в общую память. Эти переменные всегда одни и те же, они не меняются, поэтому они не имеют ничего общего с самими потоками, они являются вспомогательными и используются каждым потоком для запуска некоторого алгоритма.
Как мне подойти к этой проблеме? Можно ли достичь этого, только делая чтение total_amount_of_blocks*3
?
спасибо, ничего себе, есть так много вещей, чтобы учиться! – ksm001
в качестве эталона: это содержится в документации CUDA Toolkit v6.5 в разделе «E.2.5.3. Параметры функции» Руководства по программированию. – JonathanK