Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Karty_2.cpp : Defines the entry point for the console application.
- //
- #include <time.h>
- #include <stdio.h>
- #include <iostream>
- #include <cstdlib>
- #include <cstddef>
- // Macierze są pamiętane wierszami, a więc:
- // M(row, col) = *(M.elements + row * M.width + col)
- using namespace std;
- clock_t startD, stopD;
- clock_t startH, stopH;
- double czasD, czasH;
- typedef struct Matrix{
- int width;
- int height;
- float *elements;
- }Matrix;
- // definiujemy rozmiar bloku wątków:
- #define BLOCK_SIZE 16
- #define N 16
- // prototyp funkcji mnożącej (kernela)
- __global__ void MatMulKernel( Matrix, Matrix, Matrix);
- void MatMul( const Matrix, const Matrix, Matrix);
- // prototyp funkcji uzupelniajaca macierz dla CPU
- void pseudolosowe(Matrix macierz);
- // Zakładamy (dla uproszczenia rozważań), że wymiary macierzy są
- // całkowitymi wielokrotnościami wartości BLOCK_SIZE
- int main()
- {
- Matrix A; // Macierz A
- A.height=N;
- A.width=N;
- A.elements=(float*)malloc(N*N*sizeof(float));
- Matrix B; // Macierz B
- B.height=N;
- B.width=N;
- B.elements=(float*)malloc(N*N*sizeof(float));
- Matrix C; // Macierz C
- C.height=N;
- C.width=N;
- C.elements=(float*)malloc(N*N*sizeof(float));
- pseudolosowe(A); // losujemy wartosci dla A
- pseudolosowe(B); // losujemy wartosci dla B
- pseudolosowe(C);
- startH = clock(); // liczenie dla CPU
- MatMul(A,B,C);
- cout<<"eeeee"<<endl;
- stopH = clock();
- czasH=(double)(stopH-startH)/CLOCKS_PER_SEC;
- cout<<"czas CPU: "<<czasH<<endl;
- dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
- dim3 dimGrid(B.width / dimBlock.x, A.height / dimBlock.y);
- startD = clock();
- MatMulKernel <<<dimGrid, dimBlock >>>(A,B,C);
- stopD = clock();
- czasD=(double)(stopD-startD)/CLOCKS_PER_SEC;
- cout<<"czas CPU: "<<czasD<<endl;
- return 0;
- }
- // Funkcja mnożąca
- void MatMul( const Matrix A, const Matrix B, Matrix C)
- {
- // kopiujemy macierze A i B to globalnej pamięci urządzenia
- // najpierw A
- Matrix d_A;
- d_A.width = A.width;
- d_A.height = A.height;
- //d_A.elements=(float *)malloc(N*sizeof(float));
- size_t size = A.width * A.height * sizeof(float); // okreslamy jakiego potrzebujemy rozmiaru
- cudaMalloc((void **)d_A.elements, size); // alokuje pamiec na karcie graficznej
- cudaMemcpy(d_A.elements, A.elements, size, cudaMemcpyHostToDevice); // Kopiuje dane między kartą graficzną, a pamięcią RAM
- // cudaMemcpyHostToDevice - kierunek transferu danych (pamięć źródłowa w RAM, a obszar docelowy w karcie graficznej
- cout<<"eeeee"<<endl;
- // potem B
- Matrix d_B;
- d_B.width = B.width;
- d_B.height = B.height;
- size = B.width * B.height * sizeof(float);
- cudaMalloc((void **)&d_B.elements, size);
- cudaMemcpy(d_B.elements, B.elements, size, cudaMemcpyHostToDevice);
- // przydzielamy macierz C w globalnej pamięci urządzenia
- Matrix d_C;
- d_C.width = C.width;
- d_C.height = C.height;
- size = C.width * C.height * sizeof(float);
- cudaMalloc((void **)&d_C.elements, size);
- // przygotowujemy środowisko i wywołujemy kernel
- dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
- dim3 dimGrid(B.width / dimBlock.x, A.height / dimBlock.y);
- MatMulKernel <<<dimGrid, dimBlock >>>(d_A, d_B, d_C);
- // odbieramy obliczoną macierz C z pamięci globalnej urządzenia
- cudaMemcpy(C.elements, d_C.elements, size, cudaMemcpyDeviceToHost);
- // cudaMemcpyDeviceToHost kierunek transferu danych (pamięć źródłowa w karcie, a obszar docelowy w RAM)
- // zwalniamy pamięć
- cudaFree(d_A.elements);
- cudaFree(d_B.elements);
- cudaFree(d_C.elements);
- }
- // kernel odpowiedzialny za wymnożenie macierzy
- __global__ void MatMulKernel(Matrix A, Matrix B, Matrix C)
- {
- // każdy wątek oblicza jeden element macierzy C
- // akumulując wynik w zmiennej Cvalue
- float Cvalue = 0;
- int row = blockIdx.y * blockDim.y + threadIdx.y;
- int col = blockIdx.x * blockDim.x + threadIdx.x;
- for (int e = 0; e < A.width; ++e)
- Cvalue += A.elements[row * A.width + e]
- * B.elements[e * B.width + col];
- C.elements[row * C.width + col] = Cvalue;
- }
- void pseudolosowe(Matrix macierz)
- {
- srand(time(NULL));
- for (int i = 0; i < macierz.height*macierz.width; i++)
- {
- macierz.elements[i] = ((rand() % 100) + 1); // tak uzyskujemy wartości po przecinku
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement