Witam serdecznie. Mam do wykonania taki o to projekt. Wykonać efekt rozmycia (Blur) na bitmapie na CPU i GPU i porównać szybkość wykonanego algorytmu. Tak jak na CPU mi to działa tak na GPU już nie. Nie wiem dlaczego ale dane odczytane przez CPU z obrazka nie są kopiowane do GPU poprzez funkcję cudaMemcpy. Wstawiam poniżej kod który wykonałem (drobna uwaga, funkcja GPUBlur nie jest jeszcze zrobiona bo szukam pomysłu na jej wykonanie).
#include <iostream>
#include "cuda.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <windows.h>
using namespace std;
BITMAPFILEHEADER BMPH; // 14 bajtowy nagłówek pliku bitmapy
BITMAPINFOHEADER BMPINFOH; // Zawiera informacje na temat wymiarów i kolorów w formacie DIB
// Wczytywanie nagłówka pliku
void ReadFileHeader()
{
char *filename = "birds.bmp";
FILE *input = fopen(filename, "rb+");
if (input == NULL)
{
printf("- Plik nie zostal otwarty (Wczytywanie naglowka pliku)\n");
exit(0);
}
printf("- Plik zostal otwarty pomyslnie (Wczytywanie naglowka pliku)\n");
if (fread(&BMPH, sizeof(BITMAPFILEHEADER), 1, input) != 1) {
printf(" Blad w odczycie naglowka bmp\n");
}
if (fread(&BMPINFOH, sizeof(BITMAPINFOHEADER), 1, input) != 1) {
printf(" Blad w odczycie informacji o zdjeciu\n");
}
fclose(input);
}
// Pobieranie wartosci RGB do tablicy
void Read_RGB_Array(unsigned char buffer[])
{
unsigned long int n = BMPINFOH.biWidth*BMPINFOH.biHeight * 3;
char *filename = "birds.bmp";
FILE *input = fopen(filename, "rb+");
fseek(input, BMPH.bfOffBits, SEEK_SET);
for (int i = 0; i<n; i++)
{
buffer[i] = fgetc(input);
}
printf("- Odczytano pomyslnie zawartosc danych o obrazie i zapisano do tablicy na CPU\n");
fclose(input);
}
__global__ void GPUBlur(unsigned char buffer[])
{
int yi = 512, xi = 768;
//int x = threadIdx.x + blockIdx.x * blockDim.x;
//int y = threadIdx.y + blockIdx.y * blockDim.y;
for (int y = 1; y < yi - 1; y++) {
for (int x = 0; x < xi - 2; x++) {
for (int c = 0; c < 3; c++) {
buffer[((y*xi * 3) + (x * 3 + 3)) + c] =
(buffer[(((y - 1)*xi * 3) + (x * 3)) + c] + buffer[(((y - 1)*xi * 3) + (x * 3 + 3)) + c] + buffer[(((y - 1)*xi * 3) + (x * 3 + 6)) + c] +
buffer[((y*xi * 3) + (x * 3)) + c] + buffer[((y*xi * 3) + (x * 3 + 3)) + c] + buffer[((y*xi * 3) + (x * 3 + 6)) + c] +
buffer[(((y + 1)*xi * 3) + (x * 3)) + c] + buffer[(((y + 1)*xi * 3) + (x * 3 + 3)) + c] + buffer[(((y + 1)*xi * 3) + (x * 3 + 6)) + c]) / 9;
}
}
}
}
void WriteBMP(unsigned char buffer[])
{
char *filename = "birds_BLUR.bmp";
FILE *output = fopen(filename, "wb+");
if (output == NULL)
{
printf("- Plik nie zostal otwarty (Zapisywanie bitmapy do pliku)\n");
exit(0);
}
printf("- Plik zostal otwarty pomyslnie (Zapisywanie bitmapy do pliku)\n");
// Zapis nagłówka
fwrite(&BMPH, 1, sizeof(BMPH), output);
// Zapis informacji o pliku
fwrite(&BMPINFOH, sizeof(BMPINFOH), 1, output);
// Zapisuje dane obrazu
fwrite(buffer, 1, BMPINFOH.biWidth*BMPINFOH.biHeight * 3, output);
fclose(output);
}
int main()
{
int start = GetTickCount(); // Pobiera aktualny czas
ReadFileHeader();
unsigned char *buffer_cuda;
cudaMalloc((void**)&buffer_cuda, BMPINFOH.biWidth*BMPINFOH.biHeight * 3);
unsigned char *buffer = (unsigned char*) malloc(BMPINFOH.biWidth*BMPINFOH.biHeight * 3);
Read_RGB_Array(buffer);
cudaMemcpy(buffer_cuda, buffer, BMPINFOH.biWidth*BMPINFOH.biHeight * 3, cudaMemcpyHostToDevice); // Kopiowanie danych CPU --> GPU
GPUBlur<<<BMPINFOH.biWidth*BMPINFOH.biHeight * 3, 1>>> (buffer);
cudaMemcpy(buffer, buffer_cuda, BMPINFOH.biWidth*BMPINFOH.biHeight * 3, cudaMemcpyDeviceToHost);
WriteBMP(buffer);
cudaFree(buffer_cuda);
free(buffer);
cout << "Czas wykonania kodu aplikacji: " << GetTickCount() - start << "ms." << endl;
system("pause");
}