CUDA
所属分类:GPU/显卡
开发工具:Others
文件大小:0KB
下载次数:0
上传日期:2024-03-12 19:48:03
上 传 者:
sh-1993
说明: CUDA:GPU编程
(CUDA: GPU Programing)
文件列表:
CUDA.md
# CUDA
CUDA: GPU Programing
## Alapok
C++ nyelvet használ.
Ezek kellenek, hogy tudjunk GPU-re programot írni.
```
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include
```
## konstans értékek
Lehet konstans értékeket beállítani, amikre késbb lehet hivatkozni:
```
#define N 5000
#define BLOCK_SIZE 500
#define BLOCK 10
```
## Fg és tárolók elhelyezkedése, létrehozása
Ezzel lehet a CPU-ra tmbt létrehozni: (CSAK A CPU-n létezik!)
```
int A[] = { 1,2,3,4,5 };
```
Ezzel lehet a GPU-n létrehozni változót, ami a GPU memória területére jn létre.
```
__device__ int dev_A[5];
```
Ezzel az eltaggal lehet olyan függvényt létrehozni, amit CPU-n és GPU-n is lehet futtatni.
```
__global__ void fg() { }
```
A GPU blokkon belül vannak még memória, ahova át lehet helyezni adatokat, de csak Globális fg-ben lehet rájuk hivatkozni:
```
_shared__ int shr_A[5];
```
## GPU indexek
Az adott blokkban a száll index lekérése: (Ez csak a blokkos indexet adja meg majd, más szóval ebbl lehet tbb is, mivel tbb blokkot is futatthatunk majd)
```
int i = threadIdx.x;
```
Az adott blokk indexét adja vissza amiben van:
```
int i = blockIdx.x;
```
Az adott blokk hosszát adja vissza:
```
int i = blockDim.x;
```
## Szállak bevárása
Meg lehet oldani, hogy a szállak bevárják egymást és ami után minden száll ugyan ott van, csak akkor lépjenek tovább.
```
__syncthreads();
```
## Main metódus
CPU-ról GPU-ra másolni az adatok így lehet:
```
cudaMemcpyToSymbol(dev_A, &A, 5*sizeof(int));
```
1. dev_A a GPU-s változót tartalmazza (memóriában a helyét)
2. &A a CPU-n az adatot, amit másolunk (lehetne így is: &(A[0]), A)
3. 5*sizeof(int) mekkora az átmásolt adat mérete
A GPU-n fg futtatása:
```
fg <<<1, 5 >>> ();
```
Ahol az 1-es most a blokkot jelenti, hogy 1 blokkot indítunk és az 5-s pedig azt, hogy mennyi szállat abban.
GPU-ról CPU-ra vissza másolás:
```
cudaMemcpyFromSymbol(A, dev_A, 5 * sizeof(int));
```
1. A a CPU-n az adatot, amit másolunk
2. dev_A a GPU-s változót tartalmazza
3. 5*sizeof(int) mekkora az átmásolt adat mérete
Console-ra kiírás:
```
printf("A[%d]=%d\n", i, A[i]);
```
## Segéd képletek
Vissza adja a megfelel tmb indexet:
```
int Global_x_component = blockIdx.x * blockDim.x + threadIdx.x
```
## GPU-n belüli szorzás kód
```
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include
int A[] = { 1,2,3,4,5 };
__device__ int dev_A[5];
int b = 5;
__device__ int dev_b;
__global__ void szorzas(int mennyivel) {
int i = threadIdx.x;
dev_A[i] *= mennyivel;
}
int main() {
cudaMemcpyToSymbol(dev_b, &b, sizeof(int));
cudaMemcpyToSymbol(dev_A, &(A[0]), 5* sizeof(int));
szorzas <<<1, 5 >>> (3);
cudaMemcpyFromSymbol(A, dev_A, 5 * sizeof(int));
cudaMemcpyFromSymbol(&b, dev_b, sizeof(int));
for (int i = 0; i < 5; i++)
{
printf("A[%d]=%d\n", i, A[i]);
}
}
```
## Szvegben szó keresés
```
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include
#include
std::string szoveg = "ababcab";
std::string szo = "abc";
const int n = (int)szoveg.size();
int m = (int)szo.size();
char szovegTomb[];
__device__ std::string dev_szoveg;
__device__ std::string dev_szo;
int hol = -1;
__device__ int dev_hol;
void keresesCPU()
{
for (int i = 0; i <= n-m; ++i)
{
if (szoveg[i] == szo[0] && szoveg[i + 1] == szo[1] & szoveg[i + 2] == szo[2])
{
hol = i;
}
}
}
void keresesGPU()
{
int i = threadIdx.x;
if (dev_szoveg[i] == dev_szo[0] && dev_szoveg[i + 1] == dev_szo[1] & dev_szoveg[i + 2] == dev_szo[2])
{
dev_hol = i;
}
}
int main() {
//keresesCPU();
cudaMemcpyToSymbol(&dev_szoveg, &szoveg, n);
cudaMemcpyToSymbol(&dev_szo, &szo, m);
cudaMemcpyToSymbol(&dev_hol, &hol, sizeof(int));
keresesGPU <<<1, n - m+1 >>> ();
cudaMemcpyFromSymbol(&szoveg, &dev_szoveg, n);
cudaMemcpyFromSymbol(&szo, &dev_szo, m);
cudaMemcpyFromSymbol(&hol, &dev_hol, sizeof(int));
printf("%d", hol);
}
```
## Futószalag rendezés + szimpla szorzás
```
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include
#define N 5000
#define BLOCK_SIZE 500
#define BLOCK 10
int A[N];
__device__ int dev_A[N];
__global__ void Multiply() //simple multiply
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
dev_A[i] *= 2;
}
__global__ void OneBlockSort()
{
for (int i = 1; i <= N/2; i++)
{
for (int shift = 0; shift <= 1; shift++)
{
int chk = 2 * threadIdx.x - shift;
if ((threadIdx.x > 0 || shift != 1) && dev_A[chk] > dev_A[chk + 1])
{
int temp = dev_A[chk];
dev_A[chk] = dev_A[chk + 1];
dev_A[chk + 1] = temp;
}
__syncthreads();
}
}
}
__global__ void MultipleBlockSort()
{
for (int i = 1; i <= blockDim.x; i++)
{
for (int shift = 0; shift <= 1; shift++)
{
int chk = 2 * (blockIdx.x * blockDim.x + threadIdx.x) - shift;
if ((threadIdx.x > 0 || shift != 1) && dev_A[chk] > dev_A[chk + 1])
{
int temp = dev_A[chk];
dev_A[chk] = dev_A[chk + 1];
dev_A[chk + 1] = temp;
}
__syncthreads();
}
}
}
__global__ void MultipleBlockSortWithShare()
{
__shared__ int shr_A[BLOCK_SIZE * 2];
shr_A[2 * threadIdx.x] = dev_A[(blockIdx.x * blockDim.x + threadIdx.x) * 2];
shr_A[2 * threadIdx.x + 1] = dev_A[(blockIdx.x * blockDim.x + threadIdx.x) * 2 + 1];
__syncthreads();
for (int i = 1; i <= blockDim.x; i++)
{
for (int shift = 0; shift <= 1; shift++)
{
int chk = 2 * threadIdx.x - shift;
if ((threadIdx.x > 0 || shift != 1) && shr_A[chk] > shr_A[chk + 1])
{
int temp = shr_A[chk];
shr_A[chk] = shr_A[chk + 1];
shr_A[chk + 1] = temp;
}
__syncthreads();
}
}
dev_A[(blockIdx.x * blockDim.x + threadIdx.x) * 2] = shr_A[2 * threadIdx.x];
dev_A[(blockIdx.x * blockDim.x + threadIdx.x) * 2 + 1] = shr_A[2 * threadIdx.x + 1];
}
int main()
{
int tolt = N;
for (int i = 0; i < N; i++)
{
A[i] = tolt;
tolt--;
}
cudaMemcpyToSymbol(dev_A, A, N * sizeof(int));
MultipleBlockSortWithShare <<< BLOCK, BLOCK_SIZE >>> ();
cudaMemcpyFromSymbol(A, dev_A, N * sizeof(int));
for (int i = 0; i < N; i++)
{
printf("A[%d] = %d\n", i, A[i]);
}
return 0;
}
```
近期下载者:
相关文件:
收藏者: