Очень интересен вопрос в отношении профилировщика в NVIDIA CUDA. Как его запустить и анализировать? Так, например, меня интересует вопрос: какое количество регистров было задействовано при исполнении ядра? Полагаю, через профилировщик это можно выяснить, но как?
[+] NVIDIA CUDA и профилировщик
Сообщений 1 страница 6 из 6
Поделиться22016-02-27 11:02:54
Запустил профилировщик nvvp в c:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\bin\
и получил следующее сообщение:
nvprof log: C:\Users\Администратор\nvvp_workspace\.metadata\.plugins\com.nvidia.viper\launch\2\nvprof_5448.log
==5448== Error: Cannot create profiling file: C:\Users\Администратор\nvvp_workspace\.metadata\.plugins\com.nvidia.viper\launch\2\api_5448.log
Похожая проблема описана тут
Зашел в свойства папки:
Убрал галочку только для чтения, но зайдя в свойства папки она стоит вновь. Однако меня смущает еще другое, как несмотря на указанные свойства в папке nvvp_workspace\... профилировщик создает файл nvprof_5448.log и при этом еще ругается на то, что мол файл создать не может?!
Поделиться32016-02-27 11:33:18
Проблему с правами решил, зайдя под доменным именем.
Теперь на очереди следующее сообщение
nvprof log: C:\Users\lws1\nvvp_workspace\.metadata\.plugins\com.nvidia.viper\launch\2\nvprof_4848.log
==4848== Warning: Unified Memory Profiling is not supported on devices of compute capability less than 3.0
==4848== Warning: Some profiling data are not recorded. Make sure cudaProfilerStop() or cuProfilerStop() is called before application exit to flush profile data.
Поделиться42016-02-27 15:55:42
Забыл отметить, рассмотрение вопроса провожу на карте Tesla C-2075.
1)
Warning: Unified Memory Profiling is not supported on devices of compute capability less than 3.0
Убираем галочку в свойствах профайлера.
2)
Warning: Some profiling data are not recorded. Make sure cudaProfilerStop() or cuProfilerStop() is called before application exit to flush profile data.
Применяем к нашему коду следующую конструкцию:
#include <cuda_profiler_api.h>
...
int main(){
cudaProfilerStart();
Вызов kernel
cudaProfilerStop();
cudaDeviceReset(); //explicitly destroys and cleans up all resources associated with the current device in the current process
return 0;
}
В результате запустил в профайлере следующий код:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"#include <cuda_profiler_api.h>
#include <stdio.h>
__global__ void kernel(int *A, int *B, int *C){
int tid = threadIdx.x + blockIdx.x * blockDim.x;
C[tid] = A[tid] + B[tid];
}
int main(){
int n = 512;
int *A, *B, *C;
cudaProfilerStart();
cudaMalloc(&A, n*n*sizeof(int));
cudaMalloc(&B, n*n*sizeof(int));
cudaMalloc(&C, n*n*sizeof(int));
kernel <<< 512, 512 >>>(A, B, C);
cudaDeviceSynchronize();
cudaProfilerStop();
return 0;
}
Получил картинку:
На этом рассмотрение профайлера не закончено. Я не до конца разобрался с его конфигурацией и не понял, как узнать количество регистров на нить, а также сколько нитей всего запущено? На досуге посмотрю видео и вернусь к этому вопросу позже.
Поделиться52016-02-27 17:20:30
Разобрался. Ключ к разгадке лежал в неверном указании компилятору:
Ошибка типа "invalid device function" гарантирована. Глупо было заставить карту с Compute capability = 2.0 [https://en.wikipedia.org/wiki/CUDA#Supported_GPUs] выполнить код, сформированный для устройства с Compute capability = 3.0.
Запустил следующий код с верными указаниями компилятору:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"#include <cuda_profiler_api.h>
#include <stdio.h>
__global__ void kernel(int *A, int *B, int *C)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
C[tid] = A[tid] + B[tid];
}int main(){
cudaProfilerStart();
int n = 512;
int *A, *B, *C;
cudaMalloc (&A, n * n * sizeof(int));
cudaMalloc (&B, n * n * sizeof(int));
cudaMalloc (&C, n * n * sizeof(int));
kernel <<< 512, 512>>> (A, B, C);
cudaDeviceSynchronize();
cudaProfilerStart();
cudaDeviceReset();
printf("%s\n", cudaGetErrorString(cudaGetLastError()));
return 0;
}
И вуаля
Поделиться62016-02-27 17:26:50
Кстати, компилятор указал такое же число регистров.