Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.04.2014, 13:34   #1
Вадим290692
 
Регистрация: 10.04.2014
Сообщений: 4
По умолчанию ИСпользование CUDA

Товарищи, может кто-нибудь разбирается в технологии CUDA и может дать совет новичку вт этом деле. Пишу самую простую программу поэлементного перемножения 2-х комплексных векторов и сравниваю скорость работы кода.
Программа, в которой вычисление производится CPU:
Код:
#include<iostream>
#include <helper_functions.h> // helper functions for SDK examples
#define SIGNAL_SIZE  8192
typedef double2 Complex;
using std::cout;
using std::endl;
 int main() 
 
{  
    StopWatchInterface *timer = 0;
    sdkCreateTimer(&timer);
   
    // Allocate host memory for the signal
    Complex *h_signal = (Complex *)malloc(sizeof(Complex) *SIGNAL_SIZE);
    Complex *h_pr_signal = (Complex *)malloc(sizeof(Complex) * SIGNAL_SIZE);
    
    for (unsigned int i = 0; i < SIGNAL_SIZE; ++i)
    {  
    h_signal[i].x = i;
    h_signal[i].y = i;
        //cout<<"<"<< h_signal[i].x<<","<<h_signal[i].y<<">"<<"\n"; 
    }
    
    sdkStartTimer(&timer);
    
        for (unsigned int i = 0; i < SIGNAL_SIZE; ++i)
    {
        h_pr_signal[i].x=h_signal[i].x*h_signal[i].x-h_signal[i].y*h_signal[i].y; 
        h_pr_signal[i].y=2*h_signal[i].y*h_signal[i].x; 
    }
    sdkStopTimer(&timer);
    printf("Processing time: %f (ms)\n", sdkGetTimerValue(&timer));
    sdkDeleteTimer(&timer); 
    
    for (unsigned int i = 0; i < SIGNAL_SIZE; ++i)
    {   
        if(i==2||i==SIGNAL_SIZE/2||i==SIGNAL_SIZE)
        cout<<"<"<< h_pr_signal[i].x<<","<<h_pr_signal[i].y<<">"<<"\n"; 
    }
    // cleanup memory
    free(h_signal);
    free(h_pr_signal);
}
Программа, в которой вычисление производится GPU:
Код:
#include<iostream>
#include <cufft.h>
#include <cuda_runtime.h>
#include <helper_functions.h> // helper functions for SDK examples
#define SIGNAL_SIZE        8192
typedef double2 Complex;
using std::cout;
using std::endl;
__global__ void MultiVector(cufftDoubleComplex *d_signal, cufftDoubleComplex *d_pr_signal) 
{ 
  // Получаем id текущей нити. 
  int idx = threadIdx.x+blockIdx.x*blockDim.x; 
  // Расчитываем результат. 
  d_pr_signal[idx].x = d_signal[idx].x*d_signal[idx].x-d_signal[idx].y*d_signal[idx].y; 
  d_pr_signal[idx].y = 2*d_signal[idx].x*d_signal[idx].y; 
}
 int main() 
 
{   
    cudaSetDevice(0);
    StopWatchInterface *timer = 0;
    sdkCreateTimer(&timer);
   
    // Allocate host memory for the signal
    Complex *h_signal = (Complex *)malloc(sizeof(Complex) *SIGNAL_SIZE);
    Complex *h_pr_signal = (Complex *)malloc(sizeof(Complex) * SIGNAL_SIZE);
    
    for (unsigned int i = 0; i < SIGNAL_SIZE; ++i)
    {  
        h_signal[i].x = i;
        h_signal[i].y =i;
    
    //    cout<<"<"<< h_signal[i].x<<","<<h_signal[i].y<<">"<<"\n"; 
    }
    
    cufftDoubleComplex *d_signal;
    cufftDoubleComplex *d_pr_signal;
    
    cudaError_t cuerr=cudaMalloc((void **)&d_signal,sizeof(cufftDoubleComplex)*SIGNAL_SIZE);
    if(cuerr!=cudaSuccess)
      cout<<"Cannot create GPU memory buffer for d_signal"<<endl;
    
    cudaError_t cuerr1=cudaMalloc((void **)&d_pr_signal,sizeof(cufftDoubleComplex)*SIGNAL_SIZE);
    if(cuerr1!=cudaSuccess)
      cout<<"Cannot create GPU memory buffer for d_signal"<<endl;
    
    sdkStartTimer(&timer);
     cudaError_t cudaResult=cudaMemcpy(d_signal,h_signal,sizeof(cufftDoubleComplex)*SIGNAL_SIZE,cudaMemcpyHostToDevice);
    if(cudaResult!=cudaSuccess)
                        cout<<"Could not copy data from device to host"<<endl;
    
    dim3 gridSize = dim3(SIGNAL_SIZE/512,1,1);
    dim3 blockSize = dim3(512,1,1);
    
    MultiVector<<<gridSize,blockSize>>>(d_signal, d_pr_signal); 
    
    //Хендл event’а 
  cudaEvent_t syncEvent; 
  cudaEventCreate(&syncEvent);    //Создаем event 
  cudaEventRecord(syncEvent, 0);  //Записываем event 
  cudaEventSynchronize(syncEvent);  //Синхронизируем event 
 
 cudaError_t cudaResult2=cudaMemcpy(h_pr_signal,  d_pr_signal,sizeof(cufftDoubleComplex)*SIGNAL_SIZE,cudaMemcpyDeviceToHost);
      if(cudaResult2!=cudaSuccess)
         cout<<"Could not copy data from device to host"<<endl;
  
    sdkStopTimer(&timer);
    printf("Processing time: %f (ms)\n", sdkGetTimerValue(&timer));
    sdkDeleteTimer(&timer); 
    
    for (unsigned int i = 0; i < SIGNAL_SIZE; ++i)
    {   
        if(i==0||i==SIGNAL_SIZE/2||i==SIGNAL_SIZE-1)
        cout<<"<"<< h_pr_signal[i].x<<","<<h_pr_signal[i].y<<">"<<"\n"; 
    }
    // cleanup memory
    free(h_signal);
    free(h_pr_signal);
    cudaFree(d_signal);
    cudaFree(d_pr_signal);
    cudaDeviceReset();
}
Результаты работы этих программ:
Снимок.JPG
Подскажите должно ли так быть(или я что=то делаю неправильно?) и почему? Заранее спасибо за помошь!!!
P.S. Видеокарта NDIVIA GeForse GTX 650
проц Intel Core™ 2
VS2012
CUDA Tollkit 5.5
Вадим290692 вне форума Ответить с цитированием
Старый 15.04.2014, 21:17   #2
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

думаю результат правильный.

самая медленная операция - пересылка данных.

значения N небольшие
данные пересылаются два раза

неудивительно, что CPU тут быстрее.



я бы ожидал, что для таких объемов работ результат на видиокарте был одинаковым для всех N.

Последний раз редактировалось f.hump; 15.04.2014 в 21:26.
f.hump вне форума Ответить с цитированием
Старый 16.04.2014, 10:23   #3
Вадим290692
 
Регистрация: 10.04.2014
Сообщений: 4
По умолчанию

Дополнил таблицу.
Получается увеличивая N мне не добиться повышения производительности? Все время съедает операция копирования в память GPU. Измерил время выполнения только ядра (без операции копирования, для N=8 388 608) получилось всего 12 мс!!!
Может быть так, что я как-то неправильно(неоптимально) запускаю ядро? (неверно выбираю размер блоков и грида?)
Снимок.JPG
Вадим290692 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
CUDA Animal_juice Visual C++ 8 22.12.2011 20:12
[CUDA] параллельный метод бактерий на cuda mamant1 Фриланс 4 13.12.2011 08:27
CUDA Kukurudza Свободное общение 7 07.11.2011 17:53
MiniGW и Cuda bondik Общие вопросы C/C++ 0 14.09.2011 23:09
CUDA dxdy Свободное общение 3 29.10.2010 20:17