#cuda
#cuda
Вопрос:
У меня есть ядро, которое вызывает функцию устройства внутри инструкции if. Код выглядит следующим образом:
__device__ void SetValues(int *ptr,int id)
{
if(ptr[threadIdx.x]==id) //question related to here
ptr[threadIdx.x] ;
}
__global__ void Kernel(int *ptr)
{
if(threadIdx.x<2)
SetValues(ptr,threadIdx.x);
}
В потоках ядра 0-1 одновременно вызываются setValues. Что происходит после этого? Я имею в виду, что теперь есть 2 одновременных вызова setValues. Выполняется ли каждый вызов функции последовательно? То есть они ведут себя как два вызова функций ядра?
Ответ №1:
CUDA фактически внедряет все функции по умолчанию (хотя Fermi и более новые архитектуры также поддерживают надлежащий ABI с указателями на функции и реальными вызовами функций). Итак, ваш пример кода компилируется примерно так
__global__ void Kernel(int *ptr)
{
if(threadIdx.x<2)
if(ptr[threadIdx.x]==threadIdx.x)
ptr[threadIdx.x] ;
}
Выполнение происходит параллельно, точно так же, как обычный код. Если вы встроите в функцию скачок памяти, нет механизма сериализации, который может вас спасти.
Комментарии:
1. у меня есть плата fermi. означает ли это, что функция не является встроенной? следовательно, threadIdx.x в setValues — это все потоки, а не только потоки 0 и 1?
2. Функции по-прежнему встроены по умолчанию в Fermi. Я думаю, я понимаю, о чем вы на самом деле спрашиваете сейчас — о том, какова область действия встроенных переменных для каждого потока (например, threadIdx) внутри функций устройства . Мне становится теплее?
3. да, это мой вопрос. но поскольку функции устройства являются встроенными.. тогда я предполагаю, что область действия потоков такая же, как и при вызове с использованием <<<блоки, потоки>>> но из-за ветвления только потоки 0 и 1 выполняют ptr[threadIdx.x] . это правильно?