62
Программирование для GPU с использованием NVidia CUDA. Половинкин А.Н.

Программирование для GPU с использованием NVidia CUDA

  • Upload
    loman

  • View
    94

  • Download
    0

Embed Size (px)

DESCRIPTION

Программирование для GPU с использованием NVidia CUDA. . Половинкин А.Н. Содержание. Вычисления общего назначения на GPU Архитектура GPU Программная модель выполнения на CUDA Программирование с использованием CUDA - PowerPoint PPT Presentation

Citation preview

Page 1: Программирование для  GPU  с использованием  NVidia  CUDA

Программирование для GPU с использованием NVidia

CUDA.

Половинкин А.Н.

Page 2: Программирование для  GPU  с использованием  NVidia  CUDA

Вычисления общего назначения на GPU Архитектура GPU Программная модель выполнения на

CUDA Программирование с использованием

CUDA Настольная вычислительная

суперкомпьютерая система Nvidia Tesla D870

Содержание

Page 3: Программирование для  GPU  с использованием  NVidia  CUDA

Почему GPU?!

Page 4: Программирование для  GPU  с использованием  NVidia  CUDA

Сравнение CPU и GPU

CPU

GPU предназначен для вычислений, ◦ параллельных по данным:

одна и та же операция выполняется над многими данными параллельно (SIMD)

◦ в которых отношение вычислительных операций к числу операций по доступу к памяти велико

Вместо кэша и сложных элементов управления на кристалле размещено большее число вычислительных элементов

GPU

Page 5: Программирование для  GPU  с использованием  NVidia  CUDA

Архитектура GPU

Page 6: Программирование для  GPU  с использованием  NVidia  CUDA

8 SP (Streaming Processor) - потоковые скалярные процессоры

2 SFU (Super Functions Unit) – предназначен для вычисления сложных математических функций

RFn (Register File) Shared Memory – разделяемая

память

Потоковый мультипроцессор

Page 7: Программирование для  GPU  с использованием  NVidia  CUDA

Программная модель выполнения (1) ядро (kernel) – функция,

выполняемая решеткой (grid) блоков потоков (threads block)

блок потоков (threads block) – набор потоков, выполняющих одну функцию (kernel) на одном мультипроцессоре, способных общаться между собой посредством:

◦ разделяемой памяти (shared memory)

◦ точек синхронизации два потока из двух различных

блоков не взаимодействуют между собой

Page 8: Программирование для  GPU  с использованием  NVidia  CUDA

Программная модель выполнения (2) каждый поток и блок

потоков имеют идентификаторы◦ каждый поток может

определить, с какими данными он должен работать

Block ID (1D или 2D) Thread ID (1D, 2D или 3D) данный подход упрощает

адресацию памяти при обработке многомерных данных

Page 9: Программирование для  GPU  с использованием  NVidia  CUDA

Программная иерархия памяти registers (чтение/запись,

одним SP*) local (чтение/запись, одним SP) shared (чтение/запись, всеми

SP, входящими в состав MP**) constant cache (только

чтение, всеми SP, входящими в состав MP)

texture cache (только чтение, всеми SP, входящими в состав MP)

device (global) (чтение/запись, всеми SP, входящими в состав всех MP)

*SP – scalar processor**MP – multiprocessor

Page 10: Программирование для  GPU  с использованием  NVidia  CUDA

данные, расположенные в глобальной памяти, реально располагаются в памяти устройства (доступ к device memory много медленнее доступа к shared memory)

общий подход к ускорению вычислений заключается в следующем:◦ разбить множество обрабатываемых данных на

подмножества, убирающиеся в shared memory ◦ обрабатывать каждое подмножество данных одним блоком

потоков: загрузить подмножество данных из global memory в shared

memory выполнить вычисления над элементами данных из

подмножества скопировать результаты из shared memory в global memory

Эффективная работа с памятью

Page 11: Программирование для  GPU  с использованием  NVidia  CUDA

host = CPU device = GPU = набор мультипроцессоров device memory = собственная память GPU kernel (ядро) – подпрограмма, выполняемая

на GPU grid (решетка) – массив блоков потоков,

которые выполняют одно и то же ядро thread block (блок потоков) – набор

потоков, которые выполняют ядро и могут взаимодействовать, используя общую память (shared memory)

Терминология

Page 12: Программирование для  GPU  с использованием  NVidia  CUDA

Стандартный язык C для разработки параллельных приложений на GPU

Библиотеки FFT (Fast Fourier Transform) и BLAS (Basic Linear Algebra Subroutine)

Специализированный драйвер для вычислений, обеспечивающий быструю передачу данных между CPU и GPU

Драйвер CUDA, обеспечивающий взаимодействие с OpenGL и DirectX

CUDA (Compute Unified Device Architecture)

Page 13: Программирование для  GPU  с использованием  NVidia  CUDA

Поддержка видеокарт NVidia >= G80, Tesla, Quadro

Поддержка Windows XP 32/64bit, Windows Vista 32/64 bit, Linux 32/64bit, Mac OS

Комплект поставки◦ CUDA driver◦ CUDA toolkit◦ CUDA SDK

CUDA

Page 14: Программирование для  GPU  с использованием  NVidia  CUDA

API представляет собой расширение языка C

Состав CUDA API:◦ расширения языка C◦ библиотека времени выполнения (runtime

library): общий компонент, обеспечивающий встроенные

векторные типы и подмножество C runtime library поддерживающее как host, так и device код

host component, обеспечивающий управление и доступ к одному или нескольким устройствам с хоста

device component, обеспечивающий функции, специфичные для устройства

CUDA Application Programming Interface (API)

Page 15: Программирование для  GPU  с использованием  NVidia  CUDA

Квалификатор Выполняется на: Вызывается с:__device__ device device__host__ host host__global__ device host

Квалификаторы функций

__global__ - определяет функцию ядро (kernel) должна возвращать результат типа void

__device__ и __host__ могут использоваться совместно невозможно взять адрес __device__ функции функции, выполняемые на устройстве, не допускают:

рекурсию объявление статических переменных внутри функции переменное число аргументов

Пример: __global__ void KernelFunc(float arg);

Page 16: Программирование для  GPU  с использованием  NVidia  CUDA

__device__ объявляет переменную, размещаемую на GPU◦ размещается в глобальном пространстве памяти;◦ время жизни переменной совпадает со временем жизни приложения;◦ доступ к переменной может быть осуществлен из всех потоков,

выполняемых на устройстве, а также с хоста через библиотеки времени выполнения.

__constant__ объявляет переменную, которая◦ размещается в константном пространстве памяти;◦ время жизни переменной совпадает со временем жизни приложения;◦ доступ к переменной может быть осуществлен из всех потоков,

выполняемых на устройстве, а также с хоста через библиотеки времени выполнения.

__shared__ объявляет переменную, которая◦ размещается в пространстве общей памяти блока потоков;◦ время жизни переменной совпадает со временем жизни блока потоков;◦ доступ к переменной может быть осуществлен из потоков,

принадлежащих блоку потоков.

Квалификаторы переменных

Page 17: Программирование для  GPU  с использованием  NVidia  CUDA

[u]char[1..4] [u]int[1..4] [u]long[1..4] float[1..4] double2

Дополнительные типы данных

Page 18: Программирование для  GPU  с использованием  NVidia  CUDA

gridDim – переменная типа dim3, содержит текущую размерность решетки;

blockIdx – переменная типа uint3, содержит индекс блока потоков внутри решетки;

blockDim – переменная типа dim3, содержит размерность блока потоков;

threadIdx – переменная типа uint3, содержит индекс потока внутри блока потоков;

warpSize – переменная типа int, содержит размер «свёртки» (warp) в потоках.

Замечание:◦ данные переменные предназначены только для чтения и не

могут быть изменены из вызывающий программы

Встроенные переменные

Page 19: Программирование для  GPU  с использованием  NVidia  CUDA

перечисление устройств:◦ cudaError_t cudaGetDeviceCount(int* count) – возвращает число

доступных устройств;◦ cudaError_t cudaGetDevice (int* dev) – возвращает используемое

устройство◦ cudaError_t cudaGetDeviceProperties(struct cudaDeviceProp* prop,

int dev) – возвращает структуру, содержащую свойства устройства выбор устройства:

◦ cudaError_t cudaChooseDevice(int* dev, const struct cudaDeviceProp* prop) – устанавливает устройство, на котором выполняется device код, в наибольшей степени соответствующее конфигурации

◦ cudaError_t cudaSetDevice(int dev) – устанавливает устройство, на котором выполняется device код;

Замечание:Nvidia Tesla D870 представляется в виде двух устройств

Управление устройствами

Page 20: Программирование для  GPU  с использованием  NVidia  CUDA

выделение и освобождение памяти на устройстве:◦ cudaError_t cudaMalloc(void** devPtr, size_t count)

– выделяет память на устройстве и возвращает указатель на нее

◦ cudaError_t cudaFree(void* devPtr) – освобождает память на устройстве

копирование данных между хостом и устройством:◦ cudaError_t cudaMemcpy(void* dst, const void* src,

size_t count, enum cudaMemcpyKind kind) – копирует данные между хостом и устройством

Управление памятью

Page 21: Программирование для  GPU  с использованием  NVidia  CUDA

Функция ядра должна быть вызвана с указанием конфигурации исполнения

Конфигурация определяется использованием выражения специального вида <<< Dg, Db, Ns>>> между именем функции и списком ее аргументов, где:

◦ Dg – определяет размерность и размер сетки, так что Dg.x * Dg.y равно числу блоков потоков, которые будут запущены, Dg.z не используется.

◦ Db – определяет размерность и размер каждого блока потоков, Db.x * Db.y * Db.z равно числу потоков на блок.

◦ Ns – переменная типа size_t, определяет число байт в разделяемой памяти, которое дополнительно выделяется на блок добавление к автоматически выделенной компилятором памяти.

Вызов ядер (1)

Page 22: Программирование для  GPU  с использованием  NVidia  CUDA

__global__ void KernelFunc()….dim3 DimGrid(100, 50); dim3 DimBlock (8, 8, 8); size_t SMSize = 64; KernelFunc<<<DimGrid, DimBlock,

SMSize>>>();

Вызов ядер (2)

Page 23: Программирование для  GPU  с использованием  NVidia  CUDA

void __syncthreads() – синхронизирует все потоки внутри блока потоков;

как только все потоки достигли данной точки, они продолжают свое выполнение

используется, чтобы избежать RAW/WAR/ WAW конфликтов при доступе к shared или global памяти

Синхронизация

Page 24: Программирование для  GPU  с использованием  NVidia  CUDA

#include <stdio.h>#include <stdlib.h>#include <cutil.h> const int N = 256;const int DATA_SZ = N * sizeof(float); float RandFloat(float low, float high){ float t = (float)rand() / (float)RAND_MAX; return (1.0f - t) * low + t * high;} // ядро, каждый поток вычисляет сумму элементов массивов A и B с индексами, // соответствующими индексу потока__global__ void vecAdd(float* A, float* B, float* C){

int i = threadIdx.x;C[i] = A[i] + B[i];

}

Пример: сложение 2 векторов (1)

Page 25: Программирование для  GPU  с использованием  NVidia  CUDA

int main(int argc, char **argv){ float *h_A, *h_B, *h_C; float *d_A, *d_B, *d_C; int i;

h_A = (float *)malloc(DATA_SZ); h_B = (float *)malloc(DATA_SZ); h_C = (float *)malloc(DATA_SZ); for(i = 0; i < N; i++)

{h_A[i] = RandFloat(0.0f, 1.0f);

h_B[i] = RandFloat(0.0f, 1.0f); }

Пример: сложение 2 векторов (2)

Page 26: Программирование для  GPU  с использованием  NVidia  CUDA

// инициализация GPUCUT_DEVICE_INIT(argc, argv);

// выделение памяти на GPUCUDA_SAFE_CALL( cudaMalloc((void **)&d_A, DATA_SZ) );CUDA_SAFE_CALL( cudaMalloc((void **)&d_B, DATA_SZ) );CUDA_SAFE_CALL( cudaMalloc((void **)&d_C, DATA_SZ) );

// копирование данных с хоста на GPUCUDA_SAFE_CALL( cudaMemcpy(d_A, h_A, DATA_SZ, cudaMemcpyHostToDevice) );CUDA_SAFE_CALL( cudaMemcpy(d_B, h_B, DATA_SZ, cudaMemcpyHostToDevice) );

// вызов ядраvecAdd<<<1, N>>>(d_A, d_B, d_C);

// копирование вектора, содержащего сумму A и B с GPU на хост

CUDA_SAFE_CALL( cudaMemcpy(h_C, d_C, DATA_SZ, cudaMemcpyDeviceToHost) );

Пример: сложение 2 векторов (3)

Page 27: Программирование для  GPU  с использованием  NVidia  CUDA

// освобождение памяти на GPU CUDA_SAFE_CALL( cudaFree(d_C) ); CUDA_SAFE_CALL( cudaFree(d_B) ); CUDA_SAFE_CALL( cudaFree(d_A) );  free(h_C); free(h_B); free(h_A);

// освобождение ресурсов устройства СUT_EXIT(argc, argv);}

Пример: сложение 2 векторов (4)

Page 28: Программирование для  GPU  с использованием  NVidia  CUDA

Для каждого потока в свертке:◦ чтение операндов◦ выполнение инструкции◦ запись результата

Для повышения производительности необходимо:◦ уменьшить число арифметических инструкций

с низким throughput◦ максимизировать использование доступной

пропускной способности для каждого типа памяти

Оптимизация производительности

Page 29: Программирование для  GPU  с использованием  NVidia  CUDA

4 clock cycles:◦ floating point сложение, умножение,

умножение-сложение (multiply-add)◦ integer сложение◦ 24-bit integer умножение (__mul24) ◦ побитовые операции, сравнение, минимум,

максимум, преобразование типов 16 clock cycles:

◦ вычисление обратного числа, 1 / sqrt(x), __logf(x)

◦ умножение 32-bit integers

Производительность арифметических инструкций (1)

Page 30: Программирование для  GPU  с использованием  NVidia  CUDA

Целочисленное деление и взятие остатка по модулю следует заменять битовыми операциями везде, где это возможно:◦ если n=2^p, тогда i/n ~ i>>log2(n), i%n ~ i&(n-

1) 32 clock cycles:

◦ __sinf(x), __cosf(x), __expf(x) (доступны только из кода, выполняемого на устройстве)

Рекомендуется использовать везде, где это возможно, floating point данные и floating point версии арифметических функций

Производительность арифметических инструкций (2)

Page 31: Программирование для  GPU  с использованием  NVidia  CUDA

условные операторы и операторы циклов (if, switch, do, while, for) влияют на производительность приложений

Потоки выполнения

if (condition){ code1;}else{ code2;}

...

потоки в свёртке

condition == truecondition == false

...

потоки в свёртке

code 1 code 1 code 1idle

idleidle

idle

idle

idle

code2 code2 code2

Page 32: Программирование для  GPU  с использованием  NVidia  CUDA

Включают в себя операции чтения/записи глобальной, локальной и shared памяти.

Выполнение одной инструкции доступа к памяти требует 4 clock cycles.

Глобальная память обладает латентностью 400-600 clock cycles__shared__ float shared[32];__device__ float device[32];shared[threadIdx.x] = device[threadIdx.x];

Инструкции для работы с памятью

Page 33: Программирование для  GPU  с использованием  NVidia  CUDA

Существуют атомарные инструкции для чтения 32-bit, 64-bit и 128-bit машинных слов.__device__ type device[32];type data = device[tid];

sizeof(type) должен быть равен 4, 8 или 16 данные должны быть выровнены по

sizeof(type) Выравнивание обеспечивается

компилятором автоматически для встроенных типов данных (float2, float4, …)

Доступ к глобальной памяти (1)

Page 34: Программирование для  GPU  с использованием  NVidia  CUDA

Размер и выравнивание структур обеспечивается директивой компилятора __align__

Доступ к глобальной памяти (2)

struct __align__(8) { float a; float b;};

struct __align__(16) { float a; float b; float c;};1 64-bit

load instruction

1 128-bit load instruction

Page 35: Программирование для  GPU  с использованием  NVidia  CUDA

Структуры размера больше 16 байт следует определять, используя __align__(16)

Доступ к глобальной памяти (3)

struct{ float a; float b; float c; float d; float e;};

struct __align__(16){ float a; float b; float c; float d; float e;};

5 32-bit load instructions

2 128-bit load instructions

Page 36: Программирование для  GPU  с использованием  NVidia  CUDA

доступ к глобальной памяти всеми потоками половины свертки (half warp), объединяется в 1 или 2 инструкции, при выполнении условий:◦ потоки совершают доступ к 32-bit, 64-bit или

128-bit words.◦ все 16 машинных слов должны лежать в

одном и том же сегменте, размер которого равен размеру memory transaction size

◦ k-ый поток совершает доступ к k-му слову

Доступ к глобальной памяти (4)

Page 37: Программирование для  GPU  с использованием  NVidia  CUDA

Доступ к глобальной памяти (5)

Page 38: Программирование для  GPU  с использованием  NVidia  CUDA

Доступ к глобальной памяти (6)

Page 39: Программирование для  GPU  с использованием  NVidia  CUDA

Доступ к глобальной памяти (7)

Page 40: Программирование для  GPU  с использованием  NVidia  CUDA

shared memory состоит из блоков памяти равного размера, доступ к которым может быть осуществлен одновременно, - банков памяти

банки в shared memory организованы таким образом, что последовательно идущие 32-bit words относятся к последовательно идущим банкам памяти

Доступ к shared памяти (1)

Address 0

Address 16

...Bank 0Address 1

Address 17

...Bank 1Address 2

Address 18

...Bank 2Address 3

Address 19

...Bank 3Address 4

Address 20

...Bank 4Address 5

Address 21

...Bank 5Address 6

Address 22

...Bank 6Address 7

Address 23

...Bank 7Address 8

Address 24

...Bank 8Address 9

Address 25

...Bank 9Address 10

Address 26

...Bank 10 Address

11Address 27

...Bank 11 Address

12Address 28

...Bank 12 Address

13Address 29

...Bank 13 Address

14Address 30

...Bank 14 Address

15Address 31

...Bank 15

Page 41: Программирование для  GPU  с использованием  NVidia  CUDA

__shared__ float shared[32];float data = shared[BaseIndex + s * tid];

tid – thread ID, s – шаг доступа к элементам массива

потоки с ID tid и tid+n вызовут bank conflict, если sn кратно числу банков m

пусть d = НОД(m, s), тогда для того, чтобы избежать bank conflicts, необходимо, чтобы d = 1

Доступ к shared memory (2)

Page 42: Программирование для  GPU  с использованием  NVidia  CUDA

Доступ к shared memory (3)

Page 43: Программирование для  GPU  с использованием  NVidia  CUDA

Доступ к shared memory (4)

Page 44: Программирование для  GPU  с использованием  NVidia  CUDA

Доступ к shared memory (5)

Page 45: Программирование для  GPU  с использованием  NVidia  CUDA

BLAS (Basic Linear Algebra Subroutines) – набор базисных подпрограмм линейной алгебры.Данный набор является основой для функций из пакета LAPACK.

Состоит из 3 уровней:1.Операции над векторами (vector-vector)2.Вектор-матричные операции (matrix-vector)3.Операции над матрицами (matrix-matrix)

Библиотеки CUBLAS и CUFFT (1)

Page 46: Программирование для  GPU  с использованием  NVidia  CUDA

Имя любой процедуры BLAS имеет следующую структуру:<character code><name><mod>()<character code> : символ, описывающий тип данных, с которым работает процедура.

Библиотеки CUBLAS и CUFFT (2)

s вещественный, одинарной точности

с комплексный, одинарной точности

d вещественный, двойной точности

z комплексный, двойной точности

Page 47: Программирование для  GPU  с использованием  NVidia  CUDA

Для некоторых процедур и функций данные символы могут комбинироваться. Например, функция scasum принимает на вход массив комплексных чисел и возвращает вещественное значение.

<name> : для BLAS Level 1 определяет тип операции (например, dot – скалярное произведение, swap – перестановка элементов векторов местами), для BLAS Level 2 и 3 определяет тип матричного аргумента.

Библиотеки CUBLAS и CUFFT (3)

Page 48: Программирование для  GPU  с использованием  NVidia  CUDA

Некоторые функции BLAS возвращают индекс элемента массива. Независимо от того, какая версия библиотеки (Fortran или C) используется, элементы массива нумеруются с 1. Следовательно, при использовании C-версии из результата, который вернула функция, следует вычесть 1.

Библиотеки CUBLAS и CUFFT (4)

Page 49: Программирование для  GPU  с использованием  NVidia  CUDA

Библиотеки CUBLAS и CUFFT (5)#include <stdio.h>#include <mkl.h>void main(){

int n = 4;float x[4] = {1., 2., 3., -4.};float y[4] = {2., 2., -1., 10};int incx = 1, incy = 1;float alpha = 1.0;int imax = 0;saxpy(&n, &alpha, x, &incx, y, &incy); // y := alpha*x +

y}

Page 50: Программирование для  GPU  с использованием  NVidia  CUDA

cublasInit() - инициализация CUBLAS (должна быть вызвана перед использованием любой другой CUBLAS функции)

cublasShutdown() - освобождает ресурсы, используемые библиотекой CUBLAS на стороне хоста

Библиотеки CUBLAS и CUFFT (6)

Page 51: Программирование для  GPU  с использованием  NVidia  CUDA

cublasAlloc(int n, int elemSize, void **devicePtr) – создает объект в пространстве памяти GPU, содержащий массив из n элементов размера elemSize. Указатель на созданный объект размещается в devicePtr (данный указатель не должен впоследствии изменяться в коде, выполняемом на хосте)

cublasFree(const void *devicePtr) – освобождает память, выделенную на GPU

Библиотеки CUBLAS и CUFFT (7)

Page 52: Программирование для  GPU  с использованием  NVidia  CUDA

cublasSetVector (int n, int elemSize, const void *x, int incx, void *y, int incy) – копирует n элементов вектора x (пространство памяти CPU) в вектор y (пространство памяти GPU)

cublasGetVector (int n, int elemSize, const void *x, int incx, void *y, int incy) - копирует n элементов вектора x (пространство памяти GPU) в вектор y (пространство памяти CPU)

Библиотеки CUBLAS и CUFFT (8)

Page 53: Программирование для  GPU  с использованием  NVidia  CUDA

Библиотеки CUBLAS и CUFFT (9)#include <stdio.h>#include <cublas.h>void main(){

int n = 4;float x_H[4] = {1., 2., 3., -4.};float y_H[4] = {2., 2., -1., 10};float* x_D = 0;float* y_D = 0;int incx = 1, incy = 1;float alpha = 1.0;cublasInit();cublasAlloc(n, sizeof(float), &x_D);cublasAlloc(n, sizeof(float), &y_D);cublasSetVector(n, sizeof(float), x_H, incx, x_D, incx);cublasSetVector(n, sizeof(float), y_H, incy, y_D, incy);

Page 54: Программирование для  GPU  с использованием  NVidia  CUDA

Библиотеки CUBLAS и CUFFT (10)

// y_D := alpha*x_D + y_DcublasSaxpy(n, alpha, x_D, &incx, y_D, &incy); cublasGetVector(n, sizeof(float), y_D, incy, y_H, incy);cublasFree(x_D);cublasFree(y_D);cublasShutdown();

}

Page 55: Программирование для  GPU  с использованием  NVidia  CUDA

Настольная вычислительная суперкомпьютерная система Tesla D870

Tesla D870

= +

Page 56: Программирование для  GPU  с использованием  NVidia  CUDA

Tesla D870 (схема подключения)

Page 57: Программирование для  GPU  с использованием  NVidia  CUDA

2 GPU Tesla C870 32 (2x16) мультипроцессора 256 (2x128) потоковых процессорных

ядер Рабочая частота ядер – 1.35 ГГц Пропускная способность шины памяти

(пиковая) – 76.8 Гб/с Пиковая производительность – 1 Tflop/s Максимальная потребляемая мощность –

520 Вт

Tesla D870 (характеристики)

Page 58: Программирование для  GPU  с использованием  NVidia  CUDA

Физическое моделирование Вычислительная биология (задачи

молекулярной динамики) Вычислительная химия Томография Финансовая математика Компьютерное зрение …http://www.nvidia.com/object/cuda_home.html

Tesla D870 (области применения)

Page 59: Программирование для  GPU  с использованием  NVidia  CUDA

Умножение квадратных матриц Аппаратное обеспечение

◦ NVidia Tesla C870◦ Intel Core2 Quad Q6600

Используемое ПО:◦ Windows XP 32bit;◦ Microsoft Visual Studio 2005◦ CUBLAS 2.0 (включен в состав CUDA Toolkit 2.0) (для Tesla

C870)◦ Intel MKL 10.0.3 (для Core2 Quad 6600)

Замечание: при измерении общего времени работы алгоритма на видеокарте учитывается время загрузки данных на карту и получения данных с карты

Вычислительный эксперимент

Page 60: Программирование для  GPU  с использованием  NVidia  CUDA

Вычислительный эксперимент (результаты)

512 1024153620482560307235844096460851205632614466567168768081928704921697280

50

100

150

200

250

300

350

Core2 Quad Q6600Tesla C870Tesla D870

N

Про

изво

дите

льно

сть,

GFl

ops

Page 61: Программирование для  GPU  с использованием  NVidia  CUDA

Nvidia CUDA Programming Guide Многочисленные курсы по CUDA:

◦ http://courses.ece.uiuc.edu/ece498/al1/Syllabus.html◦ http://www.nvidia.ru/object/cuda_state_university_courses_ru.html (на

русском языке)

Литература

Page 62: Программирование для  GPU  с использованием  NVidia  CUDA

?

Вопросы