Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование CUDA, Сравнение времени работы кода 
:(
    Опции темы
Vadim290692
Дата 15.4.2014, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 10.4.2014

Репутация: нет
Всего: нет



Товарищи, может кто-нибудь разбирается в технологии 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();
}


Результаты работы этих программ во вложении)
Подскажите должно ли так быть(или я что=то делаю неправильно?) и почему? Заранее спасибо за помошь!!!
P.S. Видеокарта NDIVIA GeForse GTX 650
проц Intel Core™ 2
VS2012
CUDA Tollkit 5.5

Присоединённый файл ( Кол-во скачиваний: 10 )
Присоединённый файл  Снимок.JPG 41,19 Kb
PM MAIL   Вверх
Vadim290692
Дата 16.4.2014, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 10.4.2014

Репутация: нет
Всего: нет



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


Это сообщение отредактировал(а) Vadim290692 - 16.4.2014, 09:26

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  Снимок.JPG 51,12 Kb
PM MAIL   Вверх
tzirechnoy
Дата 16.4.2014, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: 2
Всего: 16



Скорее -- простенький алгоритм и так работает со скоростью доступа к памяти. Три умножэния, по два такта на штуку, против 16 байт read/8 write -- при том, что оно делается параллельно, всё происходит на скорости памяти. http://www.intel.com/content/dam/www/publi...tion-manual.pdf

Потому лишние копирования -- добавляют времени выполнения и только.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0759 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.