Загрузка...
Linux
Новости, статьи, обсуждения, - все что связано с GNU Linux, FreeBSD, OpenBSD, Sun Solaris, Mac OS X и другими системами. Если вы интересуетесь данной темой - добро пожаловать в сообщество.

Cuda

     
07.03.11, 18:57
Автор ggg

Недавно возникла необходимость скрестить две технологии CUDA и Qt, а именно - ускорить работу программы за счет переноса некоторых математических вычислений с CPU на GPU. Как выглядит "скрещивание"?


Читать полностью
ключевые слова

CUDA (Compute Unified Device Architecture) - библиотека от NVIDIA, позволяющая использовать возможности GPU для вычислений. Как мне кажется, в скором времени будет достойной заменой таких библиотек как OpenMPI для большого количества процессоров. По FLOP'ам для распараллеливаемых задач и при использовании hardware одной ценовой категории можно получить преимущество где-то на порядок-другой.

Несколько слов односительно задач, которые можно распараллелить. Например, предполжим у нас есть некоторое трехмерное поле (массив A[M][N][K], где M, N, K - размерности поля. Предположим, что есть задача сложить A[M][N][K] c B[M][N][K] и результат поместить в C[M][N][K]). На CPU  решение задачи будет выглядеть так:

(тут я немного смухлевал, сделав массив линейным)

J = M*N*K;
for(int i=0;i< J;++i)
     C[i] = A[i] + B[i];

На CUDA же примерно так:

// Kernel definition
__global__ void VecAdd(float* A, float* B, float* C)
{
   int i = threadIdx.x;
   C[i] = A[i] + B[i];
}
int main()
{
    // Kernel invocation
    VecAdd< < < 1, N>>>(A, B, C);
}

Суть в том, что функция VecAdd будет выполняться одновременно на нескольких GPU (в моём случае на 16-ти) для NVIDIA 9500 GT, которые не уступают в производительности CPU применительно к работе с чиселками. Проблема CPU для данной задачи в том, что в CPU больше транзистров отводиться на предказание переходов, кеширование данных и некоторые другие операции, а надо-то всёго ничего - сложить чиселки.

Для того, чтобы сбилдить простейшее приложение на CUDA мне потребовалось произвести следующую последовательность действий:
0. Скачать и установить драйвер NVIDIA с поддержкой CUDA (версия драйвера >= 190) - для экспериметнов данный шаг является опциональным, так как можно билдить конечные бинари в режиме эмуляции.
1. Скачать и установить cudatoolkit с www.nvidia.com
2. Скачать и установить cudasdk
3. Добавить пути к бинарям и либам cudatoolkit'а - в моем случае добавить в ~/.bashrc следующие строки
export PATH=$PATH:/usr/local/cuda/bin
export LD_LIBRARY_PATH=/usr/local/cuda/lib
4. Почитать pdf-ки в /usr/local/cuda/doc относительно nvcc (надстройка над компилятором системы)
5. Создать себе папочку $(MY_PATH)
6. Положить туда файлик moveArrays.cu скопированный из следующей статьи http://www.ddj.com/hpc-high-performance-computing/207200659 :

// moveArrays.cu
//
// demonstrates CUDA interface to data allocation on device (GPU)
// and data movement between host (CPU) and device.
#include < stdio.h>
#include < assert.h>
#include < cuda.h>
int main(void)
{
   float *a_h, *b_h; // pointers to host memory
   float *a_d, *b_d; // pointers to device memory
   int N = 14;
   int i;
   // allocate arrays on host
   a_h = (float *)malloc(sizeof(float)*N);
   b_h = (float *)malloc(sizeof(float)*N);
   // allocate arrays on device
   cudaMalloc((void **) &a_d, sizeof(float)*N);
   cudaMalloc((void **) &b_d, sizeof(float)*N);
   // initialize host data
   for (i=0; i< N; i++) {
      a_h[i] = 10.f+i;
      b_h[i] = 0.f;
   }
   // send data from host to device: a_h to a_d 
   cudaMemcpy(a_d, a_h, sizeof(float)*N, cudaMemcpyHostToDevice);
   // copy data within device: a_d to b_d
   cudaMemcpy(b_d, a_d, sizeof(float)*N, cudaMemcpyDeviceToDevice);
   // retrieve data from device: b_d to b_h
   cudaMemcpy(b_h, b_d, sizeof(float)*N, cudaMemcpyDeviceToHost);
   // check result
   for (i=0; i< N; i++)
      assert(a_h[i] == b_h[i]);
   // cleanup
   free(a_h); free(b_h); 
   cudaFree(a_d); cudaFree(b_d);
}

7. Создать makefile полностью аналогичный makefile'ам примеров в CUDA SDK, в моём случае следующему:
~/NVIDIA_GPU_Computing_SDK/C/src/template/Makefile, который мной был приведен к виду

################################################################################
#
# Copyright 1993-2006 NVIDIA Corporation. All rights reserved.
#
# NOTICE TO USER: 
#
# This source code is subject to NVIDIA ownership rights under U.S. and 
# international Copyright laws. 
#
# NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE 
# CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR 
# IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH 
# REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF 
# MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. 
# IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 
# OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 
# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 
# OR PERFORMANCE OF THIS SOURCE CODE. 
#
# U.S. Government End Users. This source code is a "commercial item" as 
# that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of 
# "commercial computer software" and "commercial computer software 
# documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) 
# and is provided to the U.S. Government only as a commercial end item. 
# Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through 
# 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the 
# source code with only those rights set forth herein.
#
################################################################################
#
# Build script for project
#
################################################################################
OMIT_CUTIL_LIB := 1
ROOTDIR := .
ROOTBINDIR := . 
# Add source files here
EXECUTABLE := moveArrays
# CUDA source files (compiled with cudacc)
CUFILES := moveArrays.cu
# CUDA dependency files
#CU_DEPS := \
# C/C++ source files (compiled with gcc / c++)
#CCFILES := \
################################################################################
# Rules and targets
include common.mk


8. Скопировать ~/NVIDIA_GPU_Computing_SDK/C/common/common.mk в $(MY_PATH)/common.mk
9. Перейти в $(MY_PATH)
10. make - для дефолной сборки в режиме использования GPU
11. make emu=1 - для дефолной сборки в режиме эмуляции

ключевые слова
Ближайшие события
октябрь 2017
сентябрь 2017
август 2017
Пн
Вт
Ср
Чт
Пт
Сб
Вс
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1