Ниже приведена часть моего ядра, которое не ведет себя правильно, а затем объяснение того, что я нашел во время отладки.Ядро CUDA, похоже, игнорирует оператор «if»
__global__ void Mangler(float *matrix, int *map)
{
__shared__ signed int localMap[N];
if(0 == threadIdx.x)
{
for(int i=0; i<N; i++)
localMap[i] = -1;
}
__syncthreads();
int fn = ...; // a lot of code goes into this number, skipped for clarity
int rnumber = threadIdx.x;
int X = atomicCAS(&localMap[fn], -1, rnumber); // Spot of bother 1
if(X == -1) // Spot of bother 2
{
// some code
}
else
{
// other code
}
}
Я нашел в документации, atomicCAS(*address, compare, value)
в основном возвращает (и сохраняет по данному адресу) результат (old == compare ? value : old)
, где старое значение по адресу, перед выполнением функции.
Идущий с этим, я считаю, что выполнение int X = atomicCAS(&localMap[fn], -1, rnumber);
должны иметь два возможных исхода (согласно Руководству по программированию NVidia Cuda C):
- если
localMap[fn] == -1
тоX
должен иметь значениеrnumber
иlocalMap[fn]
должен иметь значение отrnumber
. Этого не происходит. - если
localMap[fn] != -1
тогдаX
должно быть установлено в значениеlocalMap[fn]
, и указанное значение должно быть оставлено без изменений.
Что происходит вместо этого, как и отладка с Nsight показал мне, что X
в настоящее время присваивается -1, в то время как в настоящее время localMap[fn]
присваивается значение rnumber
. Я этого не понимаю, но, как вы можете видеть в моем коде, я изменил if
, чтобы поймать эту ситуацию.
подводит меня к пятну хлопоты номера 2: хотя Nsight показывает значение X
как -1, if {}
не быть полностью пропущен (без контрольных точек в пределах попадания бы то ни было), и выполнение переходит прямо к else
.
Мои вопросы:
ли я неправильнода, я сделалatomicCAS
полностью?- Что может быть причиной и
if
, которые должны оцениваться как истинные, чтобы прыгать прямо вelse
в коде устройства?
Я использую NVidia CUDA 5.5, Visual Studio 2012 x64 в Windows 8, NVidia Nsight Monitor Visual Studio Edition 3.1. GPU для машины - NVidia GeForce GTX 550 Ti.
Я попытался изменить синтаксис на if(X!=-1)
; истинная ветвь if все еще не выполняется.
Действительно ли отладчик говорит правду? – doctorlove
Хотя я ценю философский аспект этого вопроса, не могли бы вы предложить способ подтверждения того, что он делает? Я не могу думать ни о чем, потому что отлаживать код устройства - это боль. До сих пор он, казалось, не рассказывал ни одной завуалированной лжи. –
Кроме того, значение X позже используется как индекс массива (внутри 'else'), и это приводит к нарушению доступа к памяти, что согласуется с проскальзыванием -1 там. –