Память текстур CUDA для связывания части глобальной памяти - PullRequest
3 голосов
/ 30 марта 2011

У меня проблема с привязкой к памяти текстур части глобальной памяти устройства.

У меня большой глобальный массив устройств, заполненный памятью:

двойной * device_global;

cudaMalloc ((void **) & device_global, sizeof (double) * N));

cudaMemcpy (device_global, host, sizeof (double) * N, cudaMemcpyHostToDevice));

Я запускаю множество ядер в цикле for.

Каждому ядру требуется небольшая часть (int offset = 100) device_global, которую я привязываю к текстуре через:

cudaBindTexture (0, texRef, device_global, channelDesc, sizeof (double) * 10);

Однако проблема, с которой я сталкиваюсь, заключается в том, что я не могу использовать арифметику указателей для привязки только циклического участка device_global через смещение, которое зацикливается.

Я хотел бы сделать что-то вроде:

cudaBindTexture (0, texRef, device_global + offsett * i, channelDesc, sizeof (double) * 10);

Следует отметить, что вышеуказанный подход работает, если смещение установлено на 0, арифметика указателя не работает.

Любая помощь или другие рекомендации будут высоко оценены.

Ответы [ 3 ]

3 голосов
/ 30 марта 2011

Я не верю, что возможно сделать то, что вы пытаетесь сделать.Я подозреваю, что есть некоторая закулисная трансляция адресов, что означает, что если указатель, который вы передаете вызову привязки, еще не известен диспетчеру памяти времени выполнения и соответствующим образом выровнен по границе страницы, он не позволит привязать текстурупо адресу.

Возможно, лучше связать весь массив с текстурой, а затем передать смещение индексации в каждое ядро, которое будет использоваться в выборке текстуры.

3 голосов
/ 18 января 2013

Неправильно передавать 0 или NULL в качестве первого аргумента cudaBindTexture.Привязка текстуры CUDA требует, чтобы указатель, который должен быть привязан, был выровнен.Требование выравнивания можно определить с помощью свойства устройства cudaDeviceProp::textureAlignment.

cudaBindTexture может привязать любой указатель устройства к текстуре.Если указатель не выровнен, он возвращает смещение в байтах от ближайшего предыдущего выровненного адреса в первом аргументе cudaBindTexture.Если первый аргумент NULL, вызов функции завершится неудачно.

Привязка должна быть выполнена как:

size_t texture_offset = 0;
cudaBindTexture(&texture_offset, texRef, device_global+ offsett * i , channelDesc, sizeof(double)*10);
2 голосов
/ 30 марта 2011

Смещение текстурной памяти должно быть выровнено. Вы не можете привязать любую часть памяти только к той, которая правильно выровнена, и это из-за того, как работает внутреннее высокопроизводительное оборудование.

Одним из решений было бы использование Pitched Memory и вместо очень маленькой текстуры есть несколько больших, каждый из которых начинается с выровненного ряда матрицы.

Я предполагаю здесь, но я думаю, что используя

sizeof(double)*10

как размер данных для текстурной памяти, требуется больше для настройки самой памяти, чем для ее чтения.

Насколько велика общая матрица?

...