@Robotex

Как можно оптимизировать этот кусочек CUDA-кода?

Взгляните на этот кусочек кода:

void OpenNNL::calculateNeuronsOutputsAndDerivatives(double * inputs, double * deviceOutputs, double * deviceDerivatives)
    {
        int inputsCount = _inputsCount;
    
        double * deviceTemp;
        double * deviceInputs;
    
        cudaCall(cudaMalloc ( (void**)&deviceInputs, inputsCount*sizeof(double) ));
    
        cudaCall(cudaMemcpy ( deviceInputs, inputs, inputsCount*sizeof(double), cudaMemcpyDeviceToDevice ));
    
        for(int i=0;i<_layersCount;i++)
        {
            cudaCall(cudaMalloc((void**)&deviceTemp, _neuronsPerLayerCount[i]*inputsCount*sizeof(double)));
    
            dim3 threadsMul = dim3(BLOCK_SIZE, 1);
            int blocksCount = floor((double) _neuronsPerLayerCount[i]*inputsCount / threadsMul.x) + 1;
            dim3 blocksMul = dim3(blocksCount, 1);
    
            weighting<<<blocksMul, threadsMul>>>(deviceTemp, deviceInputs, _neuronsInputsWeights, _inputsInPreviousLayers[i], inputsCount, _neuronsPerLayerCount[i]);
    
            cudaCall(cudaFree(deviceInputs));
    
            cudaCall(cudaMalloc((void**)&deviceInputs, _neuronsPerLayerCount[i]*sizeof(double)));
    
            dim3 threadsSum = dim3(BLOCK_SIZE, 1);
            blocksCount = floor((double) _neuronsPerLayerCount[i] / threadsSum.x) + 1;
            dim3 blocksSum = dim3(blocksCount, 1);
    
            calculateOutputsAndDerivatives<<<blocksSum, threadsSum>>>(deviceOutputs, deviceDerivatives, deviceInputs, deviceTemp, _neuronsBiases, inputsCount, _neuronsPerLayerCount[i], _neuronsInPreviousLayers[i]);
    
            inputsCount = _neuronsPerLayerCount[i];
    
            cudaCall(cudaFree(deviceTemp));
        }
    
        cudaCall(cudaFree(deviceInputs));
    }



Эта функция запускается очень часто. И работает она очень медленно. Вы можете увидеть cudaMemcpy в начале функции. Как можно было бы переписать ее так, чтобы избежать копирования? Массив **inputs** уже находится в глобальной памяти.
  • Вопрос задан
  • 4208 просмотров
Пригласить эксперта
Ответы на вопрос 4
@Robotex Автор вопроса
Вот здесь результаты работы профайлера: ubuntuone.com/41OVwiE7NEd3fI9jALsFi6
Но, увы, я не понимаю, что это значит (я в CUDA новичек). Я был бы рад, если бы кто-то смог мне пояснить это.
Ответ написан
Комментировать
@Disasm
Так не копируйте данные, передавайте их сразу на вход ядру weighting (если они не изменяются ядром, конечно).
Ещё было бы неплохо дожидаться окончания работы ядер.
Ответ написан
Комментировать
@oleksandr_veles
1.Я бы ещё избавился от cudaFree cudaMalloc во внутреннем цикле, хотя не знаю точно насколько они медленные.
2. Использовал бы одинарную точность, двойная на nvidia на порядок медленнее, тем более на мобильной карте.
3. Присоединяюсь к совету дожидаться окончания работы ядер.
Ответ написан
Используйте CUBLAS
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы