Всем доброго времени суток!
Почти через месяц защита диссертации. Разбираться во всех дебрях программирования на CUDA уже не осталось времени. Нужна программа, реализующая алгоритм поиска на GPU. Какой именно алгоритм это тоже большой вопрос. Алгоритмов поиска не мало и какой из них лучше распараллелиться на GPU?
Может кто подскажет как реализовать? Буду очень рад любой помощи. Спасибо.
Пока набросал простой линейный поиск. замечаниям и отзывам тоже буду рад.
При создании программы использовались следующие средства и инструменты:
1. Видеокарта из серии nVidia GeForce 8xxx/9xxx или более современная.
2. CUDA Toolkit v.2.3 (скачать можно здесь: www.nvidia.ru/object/cuda_get_ru.html)
3. CUDA SDK v.2.3 (скачать можно там же где Toolkit)
4. Visual Studio 2008
5. CUDA Visual Studio Wizard (скачать можно здесь: sourceforge.net/projects/cudavswizard/)
Текст программы
- #include <stdio.h>
- #include <time.h>
- #define CPU 1
- #define GPU 2
- // функция выполняемая на центральном процессоре
- __host__ void searchCPU ( float * data, int * result )
- {
- int len = 16 * 1024 * 1024;
- for ( int j = 0; j < len; j++ )
- {
- if (data[j] == 2.0f )
- {
- result[0] = data[j];
- result[1] = j;
- }
- }
- }
- // функция выполняемая на графическои процессоре
- __global__ void searchGPU ( float * data, int * result )
- {
- int idx = blockIdx.x * blockDim.x + threadIdx.x;
- //data [idx] = data [idx] + 1.0f;
- if ( data [idx] == 2.0f )
- {
- result[0] = data [idx];
- result[1] = idx;
- }
- }
- int main ( int argc, char * argv [] )
- {
- int n = 16 * 1024 * 1024;
- int numBytes = n * sizeof ( float );
- int size_int = 2 * sizeof ( int );
- //timer for host
- clock_t start, finish;
- double duration;
- // allocate host memory
- float * a = new float [n];
- int * host_res = new int[2];
- //init host variables
- for ( int i = 0; i < n-1; i++ )
- a [i] = 0.0f;
- a [n-1] = 2.0f;
- host_res [0] = 0;
- host_res [1] = 0;
- //Выбираем способ расчета
- int mode;
- scanf("%i", &mode);
- if ( mode == CPU )
- { start = clock(); //start timer
- searchCPU (a, host_res);
- finish = clock(); //stop timer
- duration = (double)(finish - start) / CLOCKS_PER_SEC; //time in seconds
- } else
- if ( mode == GPU )
- { // allocate device memory
- float * dev = NULL;
- int * res = NULL;
- cudaMalloc ( (void**)&dev, numBytes );
- cudaMalloc ( (void**)&res, size_int );
- // set kernel launch configuration
- dim3 threads = dim3(512, 1);
- dim3 blocks = dim3(n / threads.x, 1);
- // create cuda event handles
- cudaEvent_t start, stop;
- float gpuTime = 0.0f;
- cudaEventCreate ( &start );
- cudaEventCreate ( &stop );
- // asynchronously issue work to the GPU (all to stream 0)
- cudaEventRecord ( start, 0 );
- //copy data to device
- cudaMemcpy ( dev, a, numBytes, cudaMemcpyHostToDevice );
- cudaMemcpy ( res, host_res, size_int, cudaMemcpyHostToDevice );
- //call device function
- searchGPU<<<blocks, threads>>>(dev,res);
- //copy data to host
- cudaMemcpy ( host_res, res, size_int, cudaMemcpyDeviceToHost );
- cudaEventRecord ( stop, 0 ); // stop timer for device
- cudaEventSynchronize ( stop );
- cudaEventElapsedTime ( &gpuTime, start, stop ); //gpuTime - time in miliseconds
- // print the gpu times
- // release resources (device)
- cudaEventDestroy ( start );
- cudaEventDestroy ( stop );
- cudaFree ( dev );
- }
- else
- //print result
- // release resources (host)
- delete a;
- delete host_res;
- return 0;
- }
Время выполнения программы на ЦП составило 78 миллисекунд.
При выполнение на графическом процессоре, время выполнения программы составило 47 миллисекунд. Как видим прирост производительности порядка 40%. Не так уж много. Однако время измерения выполнения на графическом процессоре измерялось с учетом копирования исходных данных в память видеокарты и результата обратно в ОЗУ.
Результат выполнения программы на GPU без учета копирования данных составил около 9 миллисекунд. Таким образом, львиная доля времени используется на копирование данных в память GPU и обратно. Но, несмотря на это, все же достигается неплохой прирост производительности.
Программа выполнялась на платформе со следующими характеристиками:
Windows XP Professional (5.1, Build 2600) Service Pack 3
Processor: Intel(R) Pentium(R) 4 CPU 3.00GHz (2 CPUs)
Memory: 1024MB RAM
Display Devices
Name GeForce 8600 GT
Compute Capability 1.1
Clock Rate 1188 MHz
Multiprocessors 4
Warp Size 32
Regs Per Block 8192
Threads Per Block 512
Watchdog Enabled Yes
Threads Dimentions 512 x 512 x 64
Grid Dimentions 65535 x 65535 x 1
Memory InformationTotal Global 511.688 MB
Shared Per Block 16 KB
Pitch 256 KB
Total Constant 64 KB
Texture Alignment 256
GPU Overlap Yes
Performance InformationMemory Copy
Host Pinned to Device 3059.73 MB/s
Host Pageable to Device 1600.54 MB/s
Device to Host Pinned 3062.96 MB/s
Device to Host Pageable 1651.8 MB/s
Device to Device 5295.5 MB/s
GPU Core Performance
Single-precision Float 75641.8 Mflop/s
Double-precision Float Not Supported
32-bit Integer 15184 Miop/s
24-bit Integer 75647.5 Miop/s
Спасибо. Жду ответов и комментариев.