не могу войти в функцию __global__ с помощью cuda

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

Странно то, что когда я запускаю его в режиме отладки, он работает отлично, но слишком медленно.

Вот часть кода перед входом в функцию, которая обращается к графическому процессору (где, я думаю, есть ошибка, которую я не могу найти):

void parallelAction (int * dataReturned, char * data, unsigned char * descBase, int range, int cardBase, int streamIdx)
{
    size_t inputBytes = range*128*sizeof(unsigned char);
    size_t baseBytes = cardBase*128*sizeof(unsigned char);
    size_t outputBytes = range*sizeof(int);

    unsigned char * data_d;
    unsigned char * descBase_d;
    int * cardBase_d;
    int * dataReturned_d;

    cudaMalloc((void **) &data_d, inputBytes);  
    cudaMalloc((void **) &descBase_d, baseBytes);
    cudaMalloc((void **) &cardBase_d, sizeof(int));
    cudaMalloc((void **) &dataReturned_d, outputBytes);

    int blockSize = 196;
    int nBlocks = range/blockSize + (range%blockSize == 0?0:1);

    cudaMemcpy(data_d, data, inputBytes, cudaMemcpyHostToDevice);
    cudaMemcpy(descBase_d, descBase, baseBytes, cudaMemcpyHostToDevice);
    cudaMemcpy(cardBase_d, &cardBase, sizeof(int), cudaMemcpyHostToDevice);

    FindClosestDescriptor<<< nBlocks, blockSize >>>(dataReturned_d, data_d, descBase_d, cardBase_d);

    cudaMemcpy(dataReturned, dataReturned_d, outputBytes, cudaMemcpyDeviceToHost);

    cudaFree(data_d);
    cudaFree(descBase_d);
    cudaFree(cardBase_d);
    cudaFree(dataReturned_d);
}

И функция, входящая в GPU (я не думаю, что здесь ошибка):

__global__ void FindClosestDescriptor(int * dataReturned, unsigned char * data, unsigned char * base, int *cardBase)
{
    int idx = blockDim.x * blockIdx.x + threadIdx.x;
    unsigned char descriptor1[128], descriptor2[128];
    int part = 0;
    int result = 0;
    int winner = 0;
    int minDistance = 0;
    int itelimit = *cardBase;
    for (int k = 0; k < 128; k++)
    {
        descriptor1[k] = data[idx*128+k];

    }
    // initialize minDistance
    for (int k = 0; k < 128; k++)
    {
        descriptor2[k] = base[k];
    }

    for (int k = 0; k < 128; k++)
    {
        part = (descriptor1[k]-descriptor2[k]);
        part *= part;
        minDistance += part;
    }

    // test all descriptors in the base :
    for (int i = 1; i < itelimit; i++)
    {
        result = 0;
        for (int k = 0; k < 128; k++)
        {
            descriptor2[k] = base[i*128+k];
            // Calculate squared l2 distance :
            part = (descriptor1[k]-descriptor2[k]);
            part *= part;
            result += part;
        }

        // Compare to minDistance
        if (result < minDistance)
        {
            minDistance = result;
            winner = i;
        }
    }

    // Write the result in dataReturned
    dataReturned[idx] = winner;
}

Заранее спасибо, если вы можете мне помочь.

РЕДАКТИРОВАТЬ: последний cudaMemcpy возвращает ошибку «время запуска истекло и было прекращено».


person user2682877    schedule 21.08.2013    source источник
comment
@UchiaItachi требует пустоты **, поэтому вы отправляете адрес указателя.   -  person doctorlove    schedule 21.08.2013
comment
нет, он принимает только void *, это не cardBase_d, который является указателем, а cardBase, который является целым числом в аргументе функции. Неверно прочитал.   -  person Uchia Itachi    schedule 21.08.2013
comment
@user2682877: user2682877: Он вообще доходит до вызова функции?   -  person Uchia Itachi    schedule 21.08.2013
comment
да, он достигает этого, он проходит через функцию, не входя в нее, а затем завершает работу   -  person user2682877    schedule 21.08.2013
comment
А также выполняет оператор после вызова функции?   -  person Uchia Itachi    schedule 21.08.2013
comment
возможно, ваше ядро ​​вообще не выполняется или не завершено. Пожалуйста, добавьте правильный cuda проверка ошибок в вашем коде. После того, как вы разобрались со всеми обнаруженными ошибками, запустите свой код с помощью cuda-memcheck.   -  person Robert Crovella    schedule 21.08.2013
comment
Попробуйте использовать процедуры обработки ошибок после каждого API cuda позвоните, чтобы узнать, что происходит на самом деле. Ваш размер блока может быть слишком большим из-за большого количества регистров, используемых в ядре.   -  person kangshiyin    schedule 21.08.2013
comment
Одна вещь, которую вы можете использовать, это проверить возвращаемые значения cudaMalloc и cudaMemcpy и посмотреть, возвращает ли он cudaSuccess   -  person Uchia Itachi    schedule 21.08.2013
comment
да нет инструкции, но в режиме отладки работает, не понимаю почему   -  person user2682877    schedule 21.08.2013
comment
последний cudamemcpy возвращает ошибку, время запуска истекло и было прекращено, я пытаюсь выяснить, почему.   -  person user2682877    schedule 21.08.2013
comment
Возможно, вы сталкиваетесь с событием Windows TDR, т.е. Ваше ядро ​​работает слишком долго. Под windows по умолчанию выполнение ядра ограничено несколькими секундами.   -  person Robert Crovella    schedule 21.08.2013
comment
Дело не в этом, я под Ubuntu.   -  person user2682877    schedule 21.08.2013
comment
Linux также имеет механизм сторожевого таймера.   -  person Robert Crovella    schedule 21.08.2013


Ответы (1)


Linux имеет механизм сторожевого таймера. Если ваше ядро ​​​​работает в течение длительного времени (вы говорите, что оно работает медленно в режиме отладки), вы можете нажать сторожевой таймер linux и получить ошибку «время запуска истекло и было прекращено».

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

person Robert Crovella    schedule 21.08.2013