Передача данных из CPU в GPU без явной передачи в качестве параметра - PullRequest
2 голосов
/ 13 октября 2011

Можно ли передавать данные из CPU в GPU без явной передачи их в качестве параметра?

Я не хочу передавать его в качестве параметра в основном по причинам синтаксического сахара - у меня есть около 20 постоянных параметров, которые мне нужно передать, а также потому, что я последовательно вызываю два ядра с (почти) одинаковыми параметрами.

Я хочу что-то вроде

__constant__ int* blah;

__global__ myKernel(...){
    ... i want to use blah inside ...
}

int main(){
    ...
    cudaMalloc(...allocate blah...)
    cudaMemcpy(copy my array from CPU to blah)

}

Ответы [ 3 ]

3 голосов
/ 13 октября 2011

cudaMemcpyToSymbol , кажется, функция, которую вы ищете.Он работает аналогично cudaMemcpy , но с дополнительным аргументом 'offset', который выглядит так, как будто его будет проще копировать через 2D-массивы.

(я не решаюсь предоставить код,так как я не могу это проверить - но посмотрите эту тему и эту запись для справки.)

1 голос
/ 13 октября 2011

Вы можете использовать несколько подходов.Это зависит от того, как вы собираетесь использовать эти данные.

  1. Если ваш шаблон доступа константа и потоки внутри блока читают одно и то же место, используйте __constant__ память для трансляции чтениязапросов.
  2. Если ваш доступ к шаблону связан с соседями по заданной позиции или с случайным доступом (не объединенным), то я рекомендую использовать текстурную память
  3. Если вам нужны данные для чтения / записи и вы знаете размер вашего массива, определите его как __device__ blah [size] в вашем ядре.

Например:

__constant__ int c_blah[65536]; // constant memory
__device__ int g_blah[1048576]; // global memory

__global__ myKernel() {
    // ... i want to use blah inside ...
    int idx = threadIdx.x + blockIdx.x * blockDim.x;
    // get data from constant memory
    int c = c_blah[idx];
    // get data from global memory
    int g = g_blah[idx];
    // get data from texture memory
    int t = tex1Dfetch(ref, idx);
    // operate
    g_blah[idx] = c + g + t;
}


int main() {
    // declare array in host
    int c_h_blah[65536]; // and initialize it as you want
    // copy from host to constant memory
    cudaMemcpyToSymbol(c_blah, c_h_blah, 65536*sizeof(int), 0, cudaMemcpyHostToDevice);
    // declare other array in host
    int g_h_blah[1048576]; // and initialize it as you want
    // declare one more array in host
    int t_h_blah[1048576]; // and initialize it as you want
    // declare a texture reference
    texture<int, 1, cudaReadModeElementType> tref;
    // bind the texture to the array
    cudaBindTexture(0,tref,t_h_blah, 1048576*sizeof(int));
    // call your kernel
    mykernel<<<dimGrid, dimBlock>>>();
    // copy result from GPU to CPU memory
    cudaMemcpy(g_h_blah, g_blah, 1048576*sizeof(int), cudaMemcpyDeviceToHost);
}

Вы можете использовать три массива в ядре без передачи каких-либо параметров ядру.Обратите внимание, что это только пример использования, а не оптимизированное использование иерархии памяти, т. Е. Использовать постоянную память таким способом не рекомендуется.

Надеюсь, что это поможет.

1 голос
/ 13 октября 2011

используйте __device__ для применения глобальных переменных.Это похоже на способ использования __constant__

...