Я учащийся Cuda, и я хотел бы оптимизировать время выполнения моей функции ядра. В результате я понял короткую программу, вычисляющую разницу между двумя картинками. Поэтому я сравнил время выполнения между классическим исполнением процессора в C, и выполнение GPU в Cuda C.Оптимизация выполнения времени ядра Cuda
Здесь вы можете найти код я говорю:
int *imgresult_data = (int *) malloc(width*height*sizeof(int));
int size = width*height;
switch(computing_type)
{
case GPU:
HANDLE_ERROR(cudaMalloc((void**)&dev_data1, size*sizeof(unsigned char)));
HANDLE_ERROR(cudaMalloc((void**)&dev_data2, size*sizeof(unsigned char)));
HANDLE_ERROR(cudaMalloc((void**)&dev_data_res, size*sizeof(int)));
HANDLE_ERROR(cudaMemcpy(dev_data1, img1_data, size*sizeof(unsigned char), cudaMemcpyHostToDevice));
HANDLE_ERROR(cudaMemcpy(dev_data2, img2_data, size*sizeof(unsigned char), cudaMemcpyHostToDevice));
HANDLE_ERROR(cudaMemcpy(dev_data_res, imgresult_data, size*sizeof(int), cudaMemcpyHostToDevice));
float time;
cudaEvent_t start, stop;
HANDLE_ERROR(cudaEventCreate(&start));
HANDLE_ERROR(cudaEventCreate(&stop));
HANDLE_ERROR(cudaEventRecord(start, 0));
for(int m = 0; m < nb_loops ; m++)
{
diff<<<height, width>>>(dev_data1, dev_data2, dev_data_res);
}
HANDLE_ERROR(cudaEventRecord(stop, 0));
HANDLE_ERROR(cudaEventSynchronize(stop));
HANDLE_ERROR(cudaEventElapsedTime(&time, start, stop));
HANDLE_ERROR(cudaMemcpy(imgresult_data, dev_data_res, size*sizeof(int), cudaMemcpyDeviceToHost));
printf("Time to generate: %4.4f ms \n", time/nb_loops);
break;
case CPU:
clock_t begin = clock(), diff;
for (int z=0; z<nb_loops; z++)
{
// Apply the difference between 2 images
for (int i = 0; i < height; i++)
{
tmp = i*imgresult_pitch;
for (int j = 0; j < width; j++)
{
imgresult_data[j + tmp] = (int) img2_data[j + tmp] - (int) img1_data[j + tmp];
}
}
}
diff = clock() - begin;
float msec = diff*1000/CLOCKS_PER_SEC;
msec = msec/nb_loops;
printf("Time taken %4.4f milliseconds", msec);
break;
}
И вот мое ядро функция:
__global__ void diff(unsigned char *data1 ,unsigned char *data2, int *data_res)
{
int row = blockIdx.x;
int col = threadIdx.x;
int v = col + row*blockDim.x;
if (row < MAX_H && col < MAX_W)
{
data_res[v] = (int) data2[v] - (int) data1[v];
}
}
Я получил это время выполнения для каждого один
- CPU: 1,3210ms
- GPU: 0,3229ms
Интересно, почему результат GPU не так ниже, как это должно быть. Я новичок в Cuda, поэтому, пожалуйста, будьте всеобъемлющими, если есть некоторые классические ошибки.
EDIT1: Благодарим вас за отзыв. Я попытался удалить условие «if» из ядра, но это не сильно изменило время выполнения моей программы.
Однако, после установки профилировщика Cuda, он сказал мне, что мои потоки не запускались одновременно. Я не понимаю, почему у меня такое сообщение, но это кажется правдой, потому что у меня есть только 5 или 6 раз быстрее приложение с графическим процессором, чем с процессором. Это отношение должно быть больше, поскольку каждый поток должен обрабатывать один пиксель одновременно со всеми другими. Если у вас есть представление о том, что я делаю неправильно, это было бы полезно ...
Поток.
CUDA не C, а C++. – Olaf
Итак, ваш результат GPU в 4 раза быстрее, чем результат вашего процессора? Что вы ожидали? –
Сколько циклов вы используете? При копировании на/из GPU возникают значительные накладные расходы. –