Advertisement
Guest User

Untitled

a guest
Nov 21st, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.23 KB | None | 0 0
  1. // Karty_2.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4.  
  5. #include <time.h>
  6. #include <stdio.h>
  7. #include <iostream>
  8. #include <cstdlib>
  9. #include <cstddef>
  10. // Macierze są pamiętane wierszami, a więc:
  11. // M(row, col) = *(M.elements + row * M.width + col)
  12. using namespace std;
  13.  
  14. clock_t startD, stopD;
  15. clock_t startH, stopH;
  16. double czasD, czasH;
  17. typedef struct Matrix{
  18.     int width;
  19.     int height;
  20.     float *elements;
  21. }Matrix;
  22.  
  23. // definiujemy rozmiar bloku wątków:
  24. #define BLOCK_SIZE  16
  25. #define N   16
  26.  
  27.  
  28.  
  29. // prototyp funkcji mnożącej (kernela)
  30. __global__ void MatMulKernel( Matrix, Matrix, Matrix);
  31. void MatMul( const Matrix, const Matrix, Matrix);
  32. //  prototyp funkcji uzupelniajaca macierz dla CPU
  33. void pseudolosowe(Matrix macierz);         
  34.  
  35.  
  36. // Zakładamy (dla uproszczenia rozważań), że wymiary macierzy są
  37. // całkowitymi wielokrotnościami wartości BLOCK_SIZE
  38.  
  39. int main()
  40. {
  41.     Matrix A;               //  Macierz A
  42.     A.height=N;
  43.     A.width=N;
  44.     A.elements=(float*)malloc(N*N*sizeof(float));
  45.     Matrix B;               //  Macierz B
  46.     B.height=N;
  47.     B.width=N;
  48.     B.elements=(float*)malloc(N*N*sizeof(float));
  49.     Matrix C;               //  Macierz C
  50.     C.height=N;
  51.     C.width=N;
  52.     C.elements=(float*)malloc(N*N*sizeof(float));
  53.  
  54.     pseudolosowe(A);            //  losujemy wartosci dla A
  55.  
  56.     pseudolosowe(B);            //  losujemy wartosci dla B
  57.     pseudolosowe(C);
  58.    
  59.     startH = clock();           //  liczenie dla CPU
  60.  
  61.     MatMul(A,B,C);
  62. cout<<"eeeee"<<endl;
  63.     stopH = clock();
  64.     czasH=(double)(stopH-startH)/CLOCKS_PER_SEC;
  65.     cout<<"czas CPU: "<<czasH<<endl;
  66.  
  67.     dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
  68.     dim3 dimGrid(B.width / dimBlock.x, A.height / dimBlock.y);
  69.     startD = clock();
  70.     MatMulKernel <<<dimGrid, dimBlock >>>(A,B,C);
  71.     stopD = clock();
  72.     czasD=(double)(stopD-startD)/CLOCKS_PER_SEC;
  73.     cout<<"czas CPU: "<<czasD<<endl;
  74.    
  75.     return 0;
  76. }
  77.  
  78. // Funkcja mnożąca           
  79. void MatMul( const Matrix A, const Matrix B, Matrix C)
  80. {
  81.     // kopiujemy macierze A i B to globalnej pamięci urządzenia
  82.  
  83.     // najpierw A
  84.     Matrix d_A;
  85.     d_A.width = A.width;
  86.     d_A.height = A.height;
  87.     //d_A.elements=(float *)malloc(N*sizeof(float));
  88.     size_t size = A.width * A.height * sizeof(float);                       //  okreslamy jakiego potrzebujemy rozmiaru
  89.     cudaMalloc((void **)d_A.elements, size);                                //  alokuje pamiec na karcie graficznej
  90.     cudaMemcpy(d_A.elements, A.elements, size, cudaMemcpyHostToDevice);     //  Kopiuje dane między kartą graficzną, a pamięcią RAM
  91.     //  cudaMemcpyHostToDevice - kierunek transferu danych (pamięć źródłowa w RAM, a obszar docelowy w karcie graficznej
  92. cout<<"eeeee"<<endl;
  93.  
  94.     // potem B
  95.     Matrix d_B;
  96.     d_B.width = B.width;
  97.     d_B.height = B.height;
  98.     size = B.width * B.height * sizeof(float);
  99.     cudaMalloc((void **)&d_B.elements, size);
  100.     cudaMemcpy(d_B.elements, B.elements, size, cudaMemcpyHostToDevice);
  101.  
  102.     // przydzielamy macierz C w globalnej pamięci urządzenia
  103.     Matrix d_C;
  104.     d_C.width = C.width;
  105.     d_C.height = C.height;
  106.     size = C.width * C.height * sizeof(float);
  107.     cudaMalloc((void **)&d_C.elements, size);
  108.  
  109. // przygotowujemy środowisko i wywołujemy kernel
  110.     dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
  111.     dim3 dimGrid(B.width / dimBlock.x, A.height / dimBlock.y);
  112.     MatMulKernel <<<dimGrid, dimBlock >>>(d_A, d_B, d_C);
  113.  
  114.  
  115.     // odbieramy obliczoną macierz C z pamięci globalnej urządzenia
  116.     cudaMemcpy(C.elements, d_C.elements, size, cudaMemcpyDeviceToHost);
  117.     //  cudaMemcpyDeviceToHost kierunek transferu danych (pamięć źródłowa w karcie, a obszar docelowy w RAM)
  118.  
  119.     //  zwalniamy pamięć
  120.     cudaFree(d_A.elements);
  121.     cudaFree(d_B.elements);
  122.     cudaFree(d_C.elements);
  123. }
  124.  
  125.  
  126. // kernel odpowiedzialny za wymnożenie macierzy
  127. __global__ void MatMulKernel(Matrix A, Matrix B, Matrix C)
  128. {
  129.     // każdy wątek oblicza jeden element macierzy C
  130.     // akumulując wynik w zmiennej Cvalue
  131.     float Cvalue = 0;
  132.     int row = blockIdx.y * blockDim.y + threadIdx.y;
  133.     int col = blockIdx.x * blockDim.x + threadIdx.x;
  134.     for (int e = 0; e < A.width; ++e)
  135.         Cvalue += A.elements[row * A.width + e]
  136.         * B.elements[e * B.width + col];
  137.     C.elements[row * C.width + col] = Cvalue;
  138.  
  139.    
  140. }
  141.  
  142. void pseudolosowe(Matrix macierz)
  143. {
  144.     srand(time(NULL));
  145.  
  146.  
  147.  
  148.     for (int i = 0; i < macierz.height*macierz.width; i++)
  149.     {
  150.     macierz.elements[i] = ((rand() % 100) + 1); //  tak uzyskujemy wartości po przecinku
  151.     }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement