Зацикливание внутри кода cuda

Я запустил некоторый код CUDA, который обновил массив с плавающей запятой. У меня есть функция-оболочка, подобная той, что обсуждалась в Как я могу скомпилировать код CUDA, а затем связать его с проектом C++? этот вопрос.

Внутри моей функции CUDA я создаю цикл for, подобный этому...

int tid = threadIdx.x;
for(int i=0;i<X;i++)
{
     //code here
}

Теперь проблема в том, что если X равно значению 100, все работает нормально, но если X равно 1000000, мой вектор не обновляется (почти как если бы код внутри цикла for не выполнялся)

Теперь внутри функции-оболочки, если я вызываю функцию CUDA в цикле for, она все равно работает нормально (но по какой-то причине значительно медленнее, чем если бы я просто выполнял тот же процесс на ЦП) вот так...

for(int i=0;i<1000000;i++)
{
      update<<<NumObjects,1>>>(dev_a, NumObjects);
}

Кто-нибудь знает, почему я могу зацикливаться миллион раз в функции-оболочке, но не просто один раз вызвать функцию «обновления» CUDA, а затем внутри этой функции запустить цикл for из миллиона?


person Matthew    schedule 01.03.2012    source источник
comment
возможный дубликат кажется, что предел CUDA достигнут, но какой это предел?   -  person talonmies    schedule 01.03.2012
comment
Когда вы используете большее значение X, ваше ядро ​​вообще выполняется? Вы делаете какие-либо проверки ошибок? Вам следует. Является ли X константой времени компиляции или #define? Если да, проверяете ли вы требования к разделяемой и постоянной памяти, а также количество регистров, используя соответствующие флаги компилятора? Изучаете ли вы последствия с помощью Калькулятора занятости NVIDIA CUDA? Много чего может происходить.   -  person Patrick87    schedule 01.03.2012
comment
Спасибо, Патрик... X - это просто переменная для целей этого поста. Обычно я заменяю x жестко заданным значением, например, у 1000000 Talonmies есть хороший пост, и я считаю, что это причина, почему...   -  person Matthew    schedule 02.03.2012


Ответы (1)


Вы должны использовать cudaThreadSynchronize и cudaGetLastError после запуска, чтобы увидеть, была ли какая-то ошибка. Я предполагаю, что в первый раз время истекло. Это происходит, если ядро ​​занимает много времени для завершения. Карта просто отказывается от этого.

Во-вторых, причина, по которой выполнение занимает гораздо больше времени, заключается в том, что для каждого запуска ядра установлено определенное время. Когда у вас был цикл внутри ядра, вы испытали эти накладные расходы один раз и запустили цикл. Теперь вы испытываете это X раз. Накладные расходы довольно малы, но достаточно велики, чтобы как можно большая часть цикла помещалась внутрь ядра.

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

person P O'Conbhui    schedule 26.03.2012