Programowanie Równoległe wykład, 21.01.2013. CUDA, przykłady praktyczne 1. Maciej Matyka Instytut Fizyki Teoretycznej



Podobne dokumenty
Programowanie Równoległe Wykład, CUDA praktycznie 1. Maciej Matyka Instytut Fizyki Teoretycznej

CUDA część 1. platforma GPGPU w obliczeniach naukowych. Maciej Matyka

Programowanie Równoległe wykład 12. OpenGL + algorytm n ciał. Maciej Matyka Instytut Fizyki Teoretycznej

CUDA jako platforma GPGPU w obliczeniach naukowych

Programowanie procesorów graficznych NVIDIA (rdzenie CUDA) Wykład nr 1

Modelowanie komputerowe dynamiki płynów Maciej Matyka Instytut Fizyki Teoretycznej

Programowanie kart graficznych

GRAFIKA CZASU RZECZYWISTEGO Wstęp do programowania grafiki czasu rzeczywistego.

Temat: Wprowadzenie do OpenGL i GLUT

Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.

CUDA ćwiczenia praktyczne

Programowanie kart graficznych. Architektura i API część 1

Programowanie procesorów graficznych GPGPU

Wstęp do Programowania, laboratorium 02

Programowanie Współbieżne

Obliczenia na GPU w technologii CUDA

GRAFIKA CZASU RZECZYWISTEGO Wprowadzenie do OpenGL

Programowanie aplikacji równoległych i rozproszonych

Wprowadzenie do programowania w środowisku CUDA. Środowisko CUDA

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

I - Microsoft Visual Studio C++

Porównanie wydajności CUDA i OpenCL na przykładzie równoległego algorytmu wyznaczania wartości funkcji celu dla problemu gniazdowego

Struktura programu. Projekty złożone składają się zwykłe z różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem.

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Temat: Transformacje 3D

I. WSTĘP. Przykład 1. Przykład 2. Programowanie czyli tworzenie programów komputerowych (aplikacji komputerowych)

Podstawy programowania w języku C++

Lab 8. Tablice liczbowe cd,. Operacje macierzowo-wektorowe, memcpy, memmove, memset. Wyrażenie warunkowe.

Języki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński

Programowanie kart graficznych. Kompilator NVCC Podstawy programowania na poziomie API sterownika

Programowanie procesorów graficznych GPGPU. Krzysztof Banaś Obliczenia równoległe 1

Programowanie kart graficznych. Architektura i API część 2

Programowanie procesorów graficznych w CUDA.

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

Operacje wejścia/wyjścia odsłona pierwsza

Spis treści PLIKI BINARNE W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF23

Wstęp do programowania

Podstawy Informatyki Wprowadzenie do języka C dr inż. Jarosław Bułat

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

Moc płynąca z kart graficznych

Wprowadzenie do programowania z wykorzystaniem biblioteki OpenGL. Dorota Smorawa

Spis treści PLIKI BINARNE W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF23

Spis treści JĘZYK C - PLIKI BINARNE. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF30

CUDA Median Filter filtr medianowy wykorzystujący bibliotekę CUDA sprawozdanie z projektu

// Potrzebne do memset oraz memcpy, czyli kopiowania bloków

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

JCuda Czy Java i CUDA mogą się polubić? Konrad Szałkowski

Język ludzki kod maszynowy

Programowanie Równoległe wykład 12. Thrust C Maciej Matyka Instytut Fizyki Teoretycznej

CUDA PROGRAMOWANIE PIERWSZE PROSTE PRZYKŁADY RÓWNOLEGŁE. Michał Bieńkowski Katarzyna Lewenda

Programowanie proceduralne w języku C++ Podstawy

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Języki i metodyka programowania. Wprowadzenie do języka C

1 Temat: Vertex Shader

Grafika Komputerowa, Informatyka, I Rok

Argumenty wywołania programu, operacje na plikach

Podstawy programowania. Wykład: 8. Wskaźniki. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw

Podstawy programowania w C++

Przedmiot : Programowanie w języku wewnętrznym. Ćwiczenie nr 4

Podstawy Programowania.

Programowanie strukturalne język C - wprowadzenie

Ćwiczenie nr 6. Poprawne deklaracje takich zmiennych tekstowych mogą wyglądać tak:

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

CUDA obliczenia ogólnego przeznaczenia na mocno zrównoleglonym sprzęcie. W prezentacji wykorzystano materiały firmy NVIDIA (

Podział programu na moduły

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

Programowanie w Ruby

Programowanie Równoległe Wykład 5. MPI - Message Passing Interface (część 3) Maciej Matyka Instytut Fizyki Teoretycznej

5 Przygotował: mgr inż. Maciej Lasota

AKADEMIA MORSKA W SZCZECINIE WI-ET / IIT / ZTT. Instrukcja do zajęc laboratoryjnych nr 1 AUTOMATYZACJA I ROBOTYZACJA PROCESÓW PRODUKCYJNYCH

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Część 4 życie programu

Dodatek A. CUDA. 1 Stosowany jest w tym kontekście skrót GPCPU (od ang. general-purpose computing on graphics processing units).

Janusz Ganczarski. OpenGL Pierwszy program

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

Podstawy Programowania

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Obsługa wyjątków. Język C++ WW12

Podstawy programowania komputerów

Proste algorytmy w języku C

Wstęp do programowania INP003203L rok akademicki 2016/17 semestr zimowy. Laboratorium 1. Karol Tarnowski A-1 p.

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

Języki i techniki programowania Ćwiczenia 2

Temat 1. Podstawy Środowiska Xcode i wprowadzenie do języka Objective-C

Podstawy Programowania

main( ) main( void ) main( int argc, char argv[ ] ) int MAX ( int liczba_1, liczba_2, liczba_3 ) źle!

CUDA. cudniejsze przyk ady

Ćwiczenie 1. Przygotowanie środowiska JAVA

Proste algorytmy w języku C

Prof. Danuta Makowiec Instytut Fizyki Teoretycznej i Astrofizyki pok. 353, tel danuta.makowiec at gmail.com

Podstawy programowania. Wykład: 5. Instrukcje sterujące c.d. Stałe, Typy zmiennych c.d. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Wprowadzenie do klas w C++ oraz biblioteki opengl

Programowanie CUDA informacje praktycznie i. Wersja

Programowanie kart graficznych

Transkrypt:

Programowanie Równoległe wykład, 21.01.2013 CUDA, przykłady praktyczne 1 Maciej Matyka Instytut Fizyki Teoretycznej

Motywacja l CPU vs GPU (anims)

Plan CUDA w praktyce Wykład 1: CUDA w praktyce l aplikacja Wykład 2: Algorytmy n ciał Wykład 3: Thrust CUDA

CUDA pod Windows Microsoft Visual C++ (2008, 2010) można użyć darmowej wersji Express Sterownik (ze strony Parallel NSIGHT): 266.58_desktop_win7_winvista_64bit_international_whql.exe CUDA Toolkit 3.2 CUDA SDK 3.2 nvidia Parallel NSIGHT HOST/MONITOR 1.51.11018 Uwaga: może sygnalizować problem z SP1 i.net, ale nas interesuje na razie tylko konfiguracja do projektów, a nie debugowanie więc nie przejmujemy się.

Parallel NSIGHT - projekty Pozycja w menu START: (przykład na żywo kompilacja - Windows)

Uwaga: Visual 2010 W menu Project->Properties wybieramy Platform Toolset v90!

Kompilacja LINUX Korzystamy z pracowni 426 Komputery mają zainstalowane karty nvidia GeForce Środowisko CUDA jest zainstalowane Kompilacja (plik program.cu) > nvcc program.cu >./a.out Kompilacja CUDA + GLUT (OpenGL) > nvcc main.cpp kernels.cu -lglut lglu >./a.out

Hello World Pierwszy prosty program w CUDA 1. CPU wywołuje funkcję na GPU Funkcja wstawia do pamięci GPU ciąg Hello world! 2. Kopiujemy dane z GPU do pamięci CPU 3. Dane wypisujemy przy pomocy funkcji i/o (cout etc.)

Hello World Pierwszy prosty program w CUDA 1. CPU wywołuje funkcję na GPU Funkcja wstawia do pamięci GPU ciąg Hello world! 2. Kopiujemy dane z GPU do pamięci CPU 3. Dane wypisujemy przy pomocy funkcji i/o (cout etc.)

Hello World #include <stdio.h> #include <cuda.h> device char napis_device[14]; global void helloworldondevice(void) napis_device[0] = 'H'; napis_device[1] = 'e'; napis_device[11] = '!'; napis_device[12] = '\n'; napis_device[13] = 0; int main(void) helloworldondevice <<< 1, 1 >>> (); char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*13, 0, cudamemcpydevicetohost); printf("%s",napis_host);

Hello World #include <stdio.h> #include <cuda.h> device char napis_device[14]; global void helloworldondevice(void) napis_device[0] = 'H'; napis_device[1] = 'e'; napis_device[11] = '!'; napis_device[12] = '\n'; napis_device[13] = 0; int main(void) helloworldondevice <<< 1, 1 >>> (); char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*13, 0, cudamemcpydevicetohost); printf("%s",napis_host);

Hello World #include <stdio.h> #include <cuda.h> device char napis_device[14]; global void helloworldondevice(void) napis_device[0] = 'H'; napis_device[1] = 'e'; napis_device[11] = '!'; napis_device[12] = '\n'; napis_device[13] = 0; int main(void) helloworldondevice <<< 1, 1 >>> (); char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*13, 0, cudamemcpydevicetohost); printf("%s",napis_host);

Hello World #include <stdio.h> #include <cuda.h> device char napis_device[14]; global void helloworldondevice(void) napis_device[0] = 'H'; napis_device[1] = 'e'; napis_device[11] = '!'; napis_device[12] = '\n'; napis_device[13] = 0; int main(void) helloworldondevice <<< 1, 1 >>> (); char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*13, 0, cudamemcpydevicetohost); printf("%s",napis_host);

Hello World #include <stdio.h> #include <cuda.h> device char napis_device[14]; global void helloworldondevice(void) napis_device[0] = 'H'; napis_device[1] = 'e'; napis_device[11] = '!'; napis_device[12] = '\n'; napis_device[13] = 0; int main(void) helloworldondevice <<< 1, 1 >>> (); (dla CUDA > 4.1 nie trzeba przekazywać nazwy, wystarczy symbol) char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*13, 0, cudamemcpydevicetohost); printf("%s",napis_host);

Hello World #include <stdio.h> #include <cuda.h> device char napis_device[14]; global void helloworldondevice(void) napis_device[0] = 'H'; napis_device[1] = 'e'; napis_device[11] = '!'; napis_device[12] = '\n'; napis_device[13] = 0; int main(void) helloworldondevice <<< 1, 1 >>> (); (dla CUDA > 4.1 nie trzeba przekazywać nazwy, wystarczy symbol) char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*13, 0, cudamemcpydevicetohost); printf("%s",napis_host);

Deklaracja funkcji na GPU Funkcja uruchamiana na GPU to kernel (jądro) Zmienne na GPU przedrostek device Preambuła jądra - przedrostek global char napis_device[14]; void helloworldondevice(void) napis_device[0] = 'H'; napis_device[1] = 'e'; napis_device[11] = '!'; napis_device[12] = '\n'; napis_device[13] = 0; CPU device char napis_device[14]; global void helloworldondevice(void) napis_device[0] = 'H'; napis_device[1] = 'e'; napis_device[11] = '!'; napis_device[12] = '\n'; napis_device[13] = 0; GPU

Wywołanie funkcji na GPU Wywołanie funkcji GPU: funkcja <<< numblocks, threadsperblock >>> ( parametry ); numblocks liczba bloków w macierzy wątków threadsperblock liczba wątków na blok W naszym przykładzie <<<1,1>>> oznaczało uruchomienie jądra na jednym wątku który zawierał się w jednym jedynym bloku macierzy wątków.

numblocks, threadsperblock <<< 1, 1 >>> <<< 1, 4 >>> <<< 4, 1 >>> <<< dim3(3,2,1), 4 >>>

A tak to widzi nvidia CUDA Programming Guide 3.2 <<< dim3(3,2,1), dim3(4,3,1) >>>

Hello World wielowątkowo 1. CPU wywołuje funkcję na GPU Funkcja wstawia do pamięci GPU ciąg Hello world! jedna litera na jeden wątek!

Hello World wielowątkowo jedna litera na jeden wątek stwórzmy 14 bloków po 1 wątku Każdy wątek widzi swój numer i numer bloku Numer bloku -> miejsce w tablicy do skopiowania

Hello World wielowątkowo Jądro dla hello world w wersji wielowątkowej: constant device char hw[] = "Hello World!\n"; device char napis_device[14]; global void helloworldondevice(void) int idx = blockidx.x; napis_device[idx] = hw[idx]; helloworldondevice <<< 14, 1 >>> (); idx zawiera numer bloku w którym znajduje się wątek mapowanie blok/wątek -> fragment problemu wątek z idx-ego bloku kopiuje idx-ą literę napisu Kopiowanie GPU-GPU (bez sensu, ale chodzi nam o najprostszy problem)

Hello World wielowątkowo Jądro dla hello world w wersji wielowątkowej: constant device char hw[] = "Hello World!\n"; device char napis_device[14]; global void helloworldondevice(void) int idx = blockidx.x; napis_device[idx] = hw[idx]; helloworldondevice <<< 14, 1 >>> (); idx zawiera numer bloku w którym znajduje się wątek mapowanie blok/wątek -> fragment problemu wątek z idx-ego bloku kopiuje idx-ą literę napisu Kopiowanie GPU-GPU (bez sensu, ale chodzi nam o najprostszy problem)

Hello World wielowątkowo Jądro dla hello world w wersji wielowątkowej: constant device char hw[] = "Hello World!\n"; device char napis_device[14]; global void helloworldondevice(void) int idx = blockidx.x; napis_device[idx] = hw[idx]; helloworldondevice <<< 14, 1 >>> (); idx zawiera numer bloku w którym znajduje się wątek mapowanie blok/wątek -> fragment problemu wątek z idx-ego bloku kopiuje idx-ą literę napisu Kopiowanie GPU-GPU (bez sensu, ale chodzi nam o najprostszy problem)

Hello World wielowątkowo Jądro dla hello world w wersji wielowątkowej: constant device char hw[] = "Hello World!\n"; device char napis_device[14]; global void helloworldondevice(void) int idx = blockidx.x; napis_device[idx] = hw[idx]; helloworldondevice <<< 14, 1 >>> (); idx zawiera numer bloku w którym znajduje się wątek mapowanie blok/wątek -> fragment problemu wątek z idx-ego bloku kopiuje idx-ą literę napisu Kopiowanie GPU-GPU (bez sensu, ale chodzi nam o najprostszy problem)

Hello World wielowątkowo Jedno z zadań na ćwiczenia to napisanie programu helloworld_parallel.cu tak, by wykonywany był przez 14 wątków w jednym bloku.

Projekt wieloplikowy w CUDA Kernele GPU trzymam w *.cu Interfejsy C++ do kerneli GPU w *.cu Deklaracje interfejsów trzymam w *.h W plikach C++ ładuję ww deklaracje interfejsów A w praktyce?

Projekt wieloplikowy CUDA main.cpp #include <cuda.h> #include <cuda_runtime.h> #include <stdio.h> #include "kernels.h" int main(void) call_helloworld(); cudathreadsynchronize(); char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*14, 0, cudamemcpydevicetohost); printf("%s\n",napis_host); (dla CUDA > 4.1 nie trzeba przekazywać nazwy, wystarczy symbol)

Projekt wieloplikowy CUDA main.cpp #include <cuda.h> #include <cuda_runtime.h> #include <stdio.h> #include "kernels.h" int main(void) call_helloworld(); cudathreadsynchronize(); char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*14, 0, cudamemcpydevicetohost); kernels.h void call_helloworld(void); printf("%s\n",napis_host);

Projekt wieloplikowy CUDA kernels.cu #include <cuda.h> device char napis_device[14]; constant device char hw[] = "Hello World!\n\0"; main.cpp #include <cuda.h> #include <cuda_runtime.h> #include <stdio.h> #include "kernels.h" global void helloworldondevice(void) int idx = threadidx.x; napis_device[idx] = hw[idx]; void call_helloworld(void) helloworldondevice <<< 1, 15 >>> (); int main(void) call_helloworld(); cudathreadsynchronize(); char napis_host[14]; const char *symbol="napis_device"; cudamemcpyfromsymbol (napis_host, symbol, sizeof(char)*14, 0, cudamemcpydevicetohost); kernels.h void call_helloworld(void); printf("%s\n",napis_host);

Graficzne hello world Punkt materialny na ekranie (OpenGL) Jego pozycja odczytywana z pamięci GPU Kernel zmienia pozycję punktu np. ruch jednostajny x = x + vdt warunki cykliczne: x = x-l, gdy x > L

Otwarcie okna OpenGL Minimalny kod w GLUT (GL Utility Toolkit) Schemat: int main(int argc, char **argv) glutinit(&argc, argv); glutinitdisplaymode(glut_depth GLUT_DOUBLE GLUT_RGBA); glutinitwindowposition(100,100); glutinitwindowsize(320,320); glutcreatewindow("cuda Hello World GFX"); C1 void changesize(int w, int h) float ratio = 1.0 * w / h; glmatrixmode(gl_projection); glloadidentity(); glviewport(0, 0, w, h); gluortho2d(-1,1,-1,1); glmatrixmode(gl_modelview); void idlefunction(void) C2 C3 // register callbacks glutdisplayfunc(renderscene); glutreshapefunc(changesize); glutidlefunc(idlefunction); // enter GLUT event processing cycle glutmainloop(); void renderscene(void) C4 glutpostredisplay(); glutswapbuffers(); Więcej: http://www.lighthouse3d.com/opengl/

C1 ustawienie współrzędnych w pamięci GPU C2 przesunięcie punktu (GPU) C3 skopiowanie x,y GPU->CPU C4 narysowanie punktu na ekranie (CPU)

Współrzędne punktu Deklaracja zmiennych w pamięci GPU Słowo kluczowe device device float px_gpu; device float py_gpu; Proste jądro ustawiające wartości px/py: global void setpardevice(float x, float y) px_gpu = x; py_gpu = y; void call_setpardevice (float x, float y) setpardevice <<< 1, 1 >>> (x, y); Ustawienie punktu: call_setpardevice(0,0); C1

Przesunięcie punktu Przesuwamy składową x wg wzoru: x = x + dx * dt; global void movepardevice(float dxdt) px_gpu = px_gpu + dxdt; if(px_gpu>1) px_gpu = px_gpu - 2; void call_movepar(float dxdt) movepardevice <<< 1, 1 >>> (dxdt); Wywołanie funkcji: call_movepar(0.04); C2

Ustawienie punktu - cudamemcpy CUDA Reference Manual: cudaerror_t cudamemcpyfromsymbol( const void *dst, const char *symbol, size_t count, size_t offset, src enum cudamemcpykind kind) adres docelowy do skopiowania symbol zmienna źródłowa w pamięci globalnej lub stałej jako adres lub ciąg znaków z nazwą zmiennej count rozmiar danych w bajtach offset przesunięcie względem adresu symbol kind - typ transferu (np. cudamemcpydevicetohost )

Pobieranie pozycji punktu Tablice symbol_px(y)_gpu zawierają nazwy zmiennych w pamięci GPU float px_cpu, py_cpu; const char *symbol_px_gpu="px_gpu"; const char *symbol_py_gpu="py_gpu"; C3 cudamemcpyfromsymbol (&px_cpu, symbol_px_gpu, sizeof(float), 0, cudamemcpydevicetohost); cudamemcpyfromsymbol (&py_cpu, symbol_py_gpu, sizeof(float), 0, cudamemcpydevicetohost); Podobnej funkcji można też użyć do transferu CPU->GPU (np. ustawianie pozycji punktu) cudamemcpytosymbol( )

Narysowanie punktu na ekranie Kod OpenGL void renderscene(void) glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); glloadidentity(); glcolor3f(1,1,1); glpointsize(5.0); C4 glbegin(gl_points) glvertex3f(px_cpu, py_cpu,0); glend(); glutswapbuffers(); Efektywność? GPU -> CPU -> OpenGL -> GPU

W działaniu Jak to działa? Do sprawdzenia w ramach ćwiczeń.

Ćwiczenia Kodem można się trochę pobawić: Więcej punktów (tablica px[], py[]) Przesunięcie punktów w pętli Wielowątkowe przesunięcie punktów Oddziaływanie grawitacyjne z centrum przyciągania (liczenie pierwiastka na punkt) Porównanie wydajności CPU->GPU

Za tydzień Następny wykład: środa 23.01.2013. Wstępny plan: Algorytm n ciał dla CUDA pokażemy jak potężnym narzędziem może być GPU! Lepsza współpraca z API OpenGL (pozbędziemy się kopiowania GPU->CPU)

Literatura http://www.sdsc.edu/us/training/assets/docs/nvidia-02-basicsofcuda.pdf

ODRZUCONE

Ustawienie punktu - cudamemcpy Za CUDA Reference Manual: cudaerror_t cudamemcpytosymbol ( const char symbol, const void src, size_t count, size_t offset, symbol enum cudamemcpykind kind) zmienna docelowa w pamięci globalnej lub stałej jako adres lub ciąg znaków z nazwą zmiennej src adres danych do skopiowania count rozmiar danych w bajtach offset przesunięcie względem adresu symbol kind - typ transferu (np. cudamemcpyhosttodevice )

Przykład: Ustawienie punktu - cudamemcpy device float px; device float py; void call_setpardevice2(float x, float y) // px <- x // py <- y const char *symbol_px="px_gpu"; const char *symbol_py="py_gpu"; cudamemcpytosymbol(symbol_px, &x, sizeof(float), 0, cudamemcpyhosttodevice); cudamemcpytosymbol(symbol_py, &y, sizeof(float), 0, cudamemcpyhosttodevice);